替换/替换shell脚本中的对抗性子字符串变量 [英] Replace/substitute adversarial substring variables in shell script

查看:101
本文介绍了替换/替换shell脚本中的对抗性子字符串变量的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有三个未转义的对抗壳变量.

I have three unescaped adversarial shell variables.

$mystring
$old
$new

请记住,所有三个字符串都是对抗性的.它们将包含特殊字符.它们将包含一切可能弄乱替换的内容.如果替换中存在漏洞,则字符串会利用它.

Remember, all three strings are adversarial. They will contain special characters. They will contain everything possible to mess up the replace. If there is a loophole in your replace, the strings will exploit it.

在$ mystring中用$ new替换$ old的最简单函数是什么? (对于通用替换在所有情况下都有效,我在堆栈溢出中找不到任何解决方案.)

What is the simplest function to replace $old with $new in $mystring? (I couldn't find any solution in stack overflow for a generic substitution that will work in all cases).

推荐答案

这里没什么特别的-您唯一需要做的就是确保您的值在

There's nothing fancy here -- the only thing you need to do to ensure that your values are treated as literals in a parameter expansion is to ensure that you're quoting the search value, as described in the relevant section of BashFAQ #21:

result=${mystring/"$old"/$new}

如果内部没有双引号,则$old将被解释为fnmatch样式的glob表达式;和他们在一起,就是字面意思.

Without the double quotes on the inside, $old would be interpreted as a fnmatch-style glob expression; with them, it's literal.

要改为对流进行操作,请考虑gsub_literal,这在BashFAQ#21中也有描述:

To operate on streams instead, consider gsub_literal, also described in BashFAQ #21:

# usage: gsub_literal STR REP
# replaces all instances of STR with REP. reads from stdin and writes to stdout.
gsub_literal() {
  # STR cannot be empty
  [[ $1 ]] || return

  # string manip needed to escape '\'s, so awk doesn't expand '\n' and such
  awk -v str="${1//\\/\\\\}" -v rep="${2//\\/\\\\}" '
    # get the length of the search string
    BEGIN {
      len = length(str);
    }

    {
      # empty the output string
      out = "";

      # continue looping while the search string is in the line
      while (i = index($0, str)) {
        # append everything up to the search string, and the replacement string
        out = out substr($0, 1, i-1) rep;

        # remove everything up to and including the first instance of the
        # search string from the line
        $0 = substr($0, i + len);
      }

      # append whatever is left
      out = out $0;

      print out;
    }
  '
}

some_command | gsub_literal "$search" "$rep"

......还可以使用以下技术用于文件的就地替换(但仍取自先前链接的FAQ):

...which can also be used for in-place replacement on files using techniques from the following (yet again taken from the previously-linked FAQ):

# Using GNU tools to preseve ownership/group/permissions
gsub_literal "$search" "$rep" < "$file" > tmp &&
  chown --reference="$file" tmp &&
  chmod --reference="$file" tmp &&
  mv -- tmp "$file"

这篇关于替换/替换shell脚本中的对抗性子字符串变量的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆