linux - Bash 在传递给另一个 bash shell 时丢弃命令行参数

标签 linux bash shell

我有一个很大的脚本(称之为 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

只是运行 echohi 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 argument command_string. If there are arguments after the command_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/

相关文章:

linux - 将现有数组中的所有元素传递给 xargs

php - 允许 laravel 正常工作

linux - Git 克隆/下载历史

linux - Shell 脚本错误 : No such file or directory

bash - xargs 和 kill 不能协同工作以终止特定进程

适用于 Linux 的 Python 前端 GUI

bash - 自动化ssh响应

bash - Shell脚本运行命令创建多个进程

json - 使用 BASH 将 CSV 转换为 JSON

bash - 如果使用 Bash 目录为空,则不显示结果