我想从一个bash脚本运行一个命令,其中有单引号和一些其他命令在单引号和变量中。
例如:repo forall -c '....$variable'
在这种格式中,$被转义,变量不会展开。
我尝试了以下变化,但它们被拒绝了:
repo forall -c '...."$variable" '
repo forall -c " '....$variable' "
" repo forall -c '....$variable' "
repo forall -c "'" ....$variable "'"
如果我将值替换为变量,命令就会很好地执行。
请告诉我我哪里做错了。
在单引号内,所有内容都按字面意义保留,无一例外。
这意味着您必须关闭引号,插入一些内容,然后再次输入。
'before'"$variable"'after'
'before'"'"'after'
'before'\''after'
单词拼接简单地通过并置完成。正如您可以验证的那样,上面的每一行对于shell来说都是一个单词。引号(单引号或双引号,取决于情况)不会孤立单词。它们仅用于禁用各种特殊字符的解释,如空格,$,;…关于引用的教程,请看Mark Reed的回答。同样相关的:哪些字符需要在bash中转义?
不要连接由shell解释的字符串
您绝对应该避免通过连接变量来构建shell命令。这是一个糟糕的想法,类似于SQL片段的连接(SQL注入!)
通常可以在命令中使用占位符,并将命令与变量一起提供,以便被调用方可以从调用参数列表中接收它们。
例如,下面是非常不安全的。不要这样做
script="echo \"Argument 1 is: $myvar\""
/bin/sh -c "$script"
如果$myvar的内容是不可信的,这是一个漏洞:
myvar='foo"; echo "you were hacked'
使用位置参数代替上述调用。下面的调用更好——它是不可利用的:
script='echo "arg 1 is: $1"'
/bin/sh -c "$script" -- "$myvar"
请注意在脚本的赋值中使用了单勾,这意味着它是字面上的,没有变量展开或任何其他形式的解释。