bash添加了额外的单引号


14

我在执行脚本时遇到问题。
当以调试模式(bash -x)执行它时,我可以看到bash添加了额外的引号。因此,我的脚本失败了。

这在我的脚本中:

testvar="\"sudo /home/pi/shared/blink.sh 27 off\""
ssh -n -q -q -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 $1 ${testvar}

这是输出:

ssh -n -q -q -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 192.168.42.105 '"sudo' /home/pi/shared/blink.sh 27 'off"'

Answers:


9

Bash显示单引号,以便显示有效输入语法的命令。它没有运行在命令的参数中包含这些单引号的ssh命令。

ssh  '"sudo' /home/pi/shared/blink.sh 27 'off"'

告诉你的SSH命令的最后4个参数是"sudo/home/pi/shared/blink.sh27off"

在远程主机上,ssh守护程序以空格作为分隔符将命令的单词连接在一起,因此您正在执行的远程命令是

"sudo /home/pi/shared/blink.sh 27 off"

这会尝试执行名称为的命令sudo /home/pi/shared/blink.sh 27 off,该命令当然不存在。

从您的定义中删除双引号testvar

在这里无关紧要,但是在您的实际情况下可能很重要:代替${testvar}编写"$testvar"(或者,"${testvar}"如果需要,但括号是可选的)。除非您知道为什么需要将双引号引起来,否则始终将双引号引起来。"$testvar"扩展为变量的值testvar,而$testvar当不在双引号中时,将的值testvar视为由空格分隔的glob模式列表。


3

我认为您应该使用:

testvar="sudo /home/pi/shared/blink.sh 27 off"
ssh -n -q -q -o BatchMode=yes -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no -o ConnectTimeout=5 $1 "${testvar}"

这为我工作:

$ bash -x -c 'testvar="la la la"; echo "${testvar}"'
+ testvar='la la la'
+ echo 'la la la'
la la la

但是,如果我像您一样写,就会得到相同的错误结果:

$ bash -x -c 'testvar="\"la la la\""; echo ${testvar}'
+ testvar='"la la la"'
+ echo '"la' la 'la"'
"la la la"

引号至关重要,因为引号是外壳将多个单词组合在一起以形成单个参数的机制。
glenn jackman 2014年

2

Shell将变量的值拆分为单词。将其双引号以防止拆分。看到不同:

t='"a b c"'
set -xv
echo $t
echo "$t"
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.