我想从一个bash脚本运行一个命令,其中有单引号和一些其他命令在单引号和变量中。

例如:repo forall -c '....$variable'

在这种格式中,$被转义,变量不会展开。

我尝试了以下变化,但它们被拒绝了:

repo forall -c '...."$variable" '

repo forall -c " '....$variable' "

" repo forall -c '....$variable' "

repo forall -c "'" ....$variable "'"

如果我将值替换为变量,命令就会很好地执行。

请告诉我我哪里做错了。


当前回答

下面是对我有效的方法

QUOTE="'"
hive -e "alter table TBL_NAME set location $QUOTE$TBL_HDFS_DIR_PATH$QUOTE"

其他回答

只需使用printf

而不是

repo forall -c '....$variable'

使用printf将变量标记替换为展开的变量。

例如:

template='.... %s'

repo forall -c $(printf "${template}" "${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"

请注意在脚本的赋值中使用了单勾,这意味着它是字面上的,没有变量展开或任何其他形式的解释。

我想知道为什么我永远不能让我的awk语句从ssh会话打印,所以我找到了这个论坛。这里没有什么直接帮助我,但如果有人有类似的问题,然后给我一个投票。似乎任何单引号或双引号都没有帮助,但我并没有尝试所有的方法。

check_var="df -h / | awk 'FNR==2{print $3}'"
getckvar=$(ssh user@host "$check_var")
echo $getckvar

你得到了什么?一无所有。

修复:逃脱\$3在您的打印功能。

下面是对我有效的方法

QUOTE="'"
hive -e "alter table TBL_NAME set location $QUOTE$TBL_HDFS_DIR_PATH$QUOTE"

变量可以包含单引号。

myvar=\'....$variable\'

repo forall -c $myvar