我有一个很大的脚本(称之为 test
),在去掉不相关的部分后,归结为这个,我可以用它来解释我的问题:
#!/bin/bash
bash -c "$@"
这没有按预期工作。例如。 ./test echo hi
只执行 echo
并且参数消失了!
使用各种输入进行测试我可以看到只有 $1
被传递给 bash -c ...
其余的被丢弃。
但是如果我使用这样的变量:
#!/bin/bash
cmd="$@"
bash -c "$cmd"
它对所有输入都按预期工作。
问题:
1) 我想了解为什么双引号不会将整个命令行参数“传递”给 bash -c ...
。我在这里缺少什么(使用中间变量时它工作得很好)?
2) 为什么 bash 丢弃其余参数($1
除外)没有任何错误消息?
例如:
bash -c "ls" -l -a hi hello blah
只是运行 echo
和 hi hello blah
根本不会导致任何错误?
(如果可能,请引用记录此行为的 bash 语法)。
最佳答案
1) I would like to understand why the double quotes don't "pass" the entire command line arguments to bash -c .... What am I missing here (that it works perfectly fine when using an intermediate variable)?
来自 info bash @
:
@
($@
) Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is,"$@"
is equivalent to"$1" "$2" ...
.
因此,bash -c "$@"
等同于 bash -c "$1""$2"...
。在 ./test echo hi
调用的情况下,表达式扩展为
bash -c "echo" "hi"
2) Why does bash discard the rest of the arguments (except $1) without any error messages?
Bash 实际上不会丢弃任何东西。来自 man bash
:
If the
-c
option is present, then commands are read from the first non-option argumentcommand_string
. If there are arguments after thecommand_string
, they are assigned to the positional parameters, starting with$0
.
因此,对于命令 bash -c "echo""hi"
,Bash 将 "hi"
作为 $0
传递给 >“echo ”
脚本。
bash -c "ls" -l -a hi hello blah
simply runs echo and hi hello blah doesn't result in any errors at all?
根据上述规则,Bash 执行"ls"
脚本并将以下位置参数传递给此脚本:
$0
:“-l”
$1
:“-a”
$2
:“嗨”
$3
:“你好”
$4
:“blah”
因此,该命令实际上执行了 ls
,并且位置参数在脚本中未使用。您可以通过引用位置参数来使用它们,例如:
$ set -x
$ bash -c "ls \$0 \$1 \$3" -l -a hi hello blah
+ bash -c 'ls $0 $1 $3' -l -a hi hello blah
ls: cannot access hello: No such file or directory
关于linux - Bash 在传递给另一个 bash shell 时丢弃命令行参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40936798/