Rac*_*hit 344 variables bash shell quotes
我想从一个bash shell脚本运行一个命令,该脚本在单引号和变量中有单引号和一些其他命令.
例如 repo forall -c '....$variable'
在此格式中,$
进行转义并且不扩展变量.
我尝试了以下变化,但他们被拒绝了:
repo forall -c '...."$variable" '
repo forall -c " '....$variable' "
" repo forall -c '....$variable' "
repo forall -c "'" ....$variable "'"
Run Code Online (Sandbox Code Playgroud)
如果我用值代替变量来执行命令就好了.
请告诉我哪里出错了.
Jo *_* So 554
在单引号内,一切都是字面上保留,毫无例外.
这意味着你必须关闭引号,插入一些东西,然后再次重新输入.
'before'"$variable"'after'
'before'"'"'after'
'before'\''after'
Run Code Online (Sandbox Code Playgroud)
您可以验证,上面的每一行都是shell的单个单词.字符串连接简单地通过并置来完成.引号(单引号或双引号,取决于具体情况)用于禁用各种特殊字符的解释,如空格$
,;
... ...有关引用的好教程请参阅Mark Reed的答案.同样相关:哪些角色需要在bash中转义?
您绝对应该通过连接变量来避免构建shell命令.这是一个类似于SQL片段连接的坏主意(SQL注入!).
通常可以在命令中包含占位符,并将命令与变量一起提供,以便被调用者可以从调用参数列表中接收它们.
例如,以下内容非常不安全.不要这样做
script="echo \"Argument 1 is: $myvar\""
/bin/sh -c "$script"
Run Code Online (Sandbox Code Playgroud)
如果内容$myvar
不受信任,这里有一个漏洞利用:
myvar='foo"; echo "you were hacked'
Run Code Online (Sandbox Code Playgroud)
而不是上面的调用,使用位置参数.以下调用更好 - 它不可利用:
script='echo "arg 1 is: $1"'
/bin/sh -c "$script" -- "$myvar"
Run Code Online (Sandbox Code Playgroud)
注意在赋值中使用单个刻度script
,这意味着它是字面上的,没有可变扩展或任何其他形式的解释.
Mar*_*eed 84
该repo
命令无关心它得到什么样的引号.如果需要参数扩展,请使用双引号.如果这意味着你不得不反复使用大量的东西,那么对大多数东西使用单引号,然后突破它们并进入双打,以便你需要进行扩展.
repo forall -c 'literal stuff goes here; '"stuff with $parameters here"' more literal stuff'
Run Code Online (Sandbox Code Playgroud)
如果您有兴趣,请说明如下.
从shell运行命令时,该命令作为参数接收的是一个以null结尾的字符串数组.这些字符串可以包含绝对任何非空字符.
但是当shell从命令行构建那个字符串数组时,它会特别解释一些字符; 这旨在使命令更容易(实际上,可能)键入.例如,空格通常表示数组中字符串之间的边界; 因此,个别论点有时被称为"单词".但是,一个论点可能会有空格; 你需要一些方法来告诉shell你想要什么.
您可以在任何字符(包括空格或其他反斜杠)前面使用反斜杠来告诉shell按字面意思处理该字符.但是你可以这样做:
echo \"Thank\ you.\ \ That\'ll\ be\ \$4.96,\ please,\"\ said\ the\ cashier
......它可能会让人厌倦.因此shell提供了另一种选择:引号.这有两个主要品种.
双引号称为"分组引号".它们可以防止通配符和别名被扩展,但主要是它们用于包含单词中的空格.其他一些事情,比如参数和命令扩展(由a发出的各种事情$
)仍然会发生.当然,如果你想在双引号内使用双字引号,你必须反斜杠:
echo "\"Thank you. That'll be \$4.96, please,\" said the cashier"
单引号更严苛.它们之间的所有东西都是字面意思,包括反斜杠.绝对没有办法在单引号内获得文字单引号.
幸运的是,shell 中的引号不是单词分隔符 ; 他们自己不会终止一个字.您可以在同一个单词中输入和输出引号(或不同类型的引号之间)以获得所需的结果:
echo '"Thank you. That'\''ll be $4.96, please," said the cashier'
所以这更容易 - 反斜杠的数量要少得多,尽管单引号,反单词 - 单引号,开引单引号序列需要一些人习惯.
现代shell添加了另一种POSIX标准未指定的引用样式,其中前导单引号以美元符号为前缀.引用的字符串遵循与ANSI C编程语言中的字符串文字类似的约定,因此有时称为"ANSI字符串"和$'
...... '
对"ANSI引号".在这些字符串中,上面关于反斜杠的建议实际上不再适用.相反,它们再次变得特殊 - 不仅可以通过在其前面添加反斜杠来包含文字单引号或反斜杠,而且shell还会扩展ANSI C字符转义(例如\n
换行符,\t
制表符和\xHH
字符十六进制代码HH
).否则,它们表现为单引号字符串:不进行参数或命令替换:
echo $'"Thank you. That\'ll be $4.96, please," said the cashier'
Run Code Online (Sandbox Code Playgroud)
需要注意的重要一点是,作为echo
命令参数接收的单个字符串在所有这些示例中都完全相同.在shell完成解析命令行之后,没有办法运行命令来告诉引用的内容.即使它想要.
小智 6
以下是对我有用的 -
QUOTE="'"
hive -e "alter table TBL_NAME set location $QUOTE$TBL_HDFS_DIR_PATH$QUOTE"
Run Code Online (Sandbox Code Playgroud)