我们有一个运行最后两个命令的脚本。但它失败了..
$ if [ -d / ]; then echo a; else echo b; fi
a
$ bash -c 'if [ -d / ]; then echo a; else echo b; fi'
a
$ A="bash -c 'if [ -d / ]; then echo a; else echo b; fi'"
$ $A
[: -c: line 0: unexpected EOF while looking for matching `''
[: -c: line 1: syntax error: unexpected end of file
我真的好奇为什么?谢谢!
答案 0 :(得分:0)
在上一个命令行中,您已为变量A
分配了一个值,但在调用$A
之前未能对其进行评估。相反,以下任何一个都可以使用:
定义变量,然后对其进行评估,
~]# A="bash -c 'if [ -d / ]; then echo a; else echo b; fi'"
~]# eval $A
首先评估它,然后echo
评估它。
~]# A=$(bash -c 'if [ -d / ]; then echo a; else echo b; fi')
~]# echo $A
或者不是个人喜欢的,你也可以使用这个:
~]# A="eval bash -c 'if [ -d / ]; then echo a; else echo b; fi'"
~]# $A
以上所有内容都会产生a
。
注意:请参阅为什么不应使用第三个选项:http://mywiki.wooledge.org/BashFAQ/048
答案 1 :(得分:0)
让我们用一个更简单的例子来解释:
$ A="bash -c 'echo hello'"
$ $A
hello': -c: line 0: unexpected EOF while looking for matching `''
hello': -c: line 1: syntax error: unexpected end of file
执行$A
时,
shell对$A
的值执行单词拆分。
它找到了这些词:
bash
-c
'echo
hello'
您可能希望将'echo hello'
评估为值echo hello
(不使用单引号),但事实并非如此。
它不可能发生。
使用A
设置A="..."
的值时,
嵌套在'...'
中的任何"..."
都不会被评估,
所以文字'
仍然存在。
递归计算这样的字符串值会很危险。
因此,在单词拆分后,执行的内容看起来更像是这样:
bash -c "'echo" "hello'"
然后bash
尝试执行命令'echo
,它失败了,
因为它找不到匹配的'
。
至于错误消息的hello':
前缀是什么,
我相信man bash
的摘录解释了:
SYNOPSIS
bash [options] [command_string | file]
...
-c If the -c option is present, then commands are read from the
first non-option argument command_string. If there are argu-
ments after the command_string, the first argument is
assigned to $0 and any remaining arguments are assigned to
the positional parameters. The assignment to $0 sets the
name of the shell, which is used in warning and error mes-
sages.
另一个例子,在问题的原始代码中,
错误消息以[:
为前缀,因为在"bash -c 'if [ -d / ]; then echo a; else echo b; fi'"
的单词拆分之后,
'if
之后的下一个字是[
。
如果你真的想做这样的事情,你可以改用数组:
A=(bash -c 'if [ -d / ]; then echo a; else echo b; fi')
"${A[@]}"
通过这种方式写作,A
将有3个值:
bash
-c
if [ -d / ]; then echo a; else echo b; fi
这些将在执行时用作3个单词,
产生预期的输出a
。