将多个参数作为单个字符串传递给外部程序

Tim*_*kle 0 bash string shell-script

我想将多个参数作为单个字符串参数传递给 bash 脚本给外部可执行文件(尤其是git

我找到了几个建议这样的答案:

"'$*'"
"'$@'"
Run Code Online (Sandbox Code Playgroud)

这在传递到时看起来不错,echo但在传递到外部程序时失败,即使通过echo.

这是一个 MWE:

#!/bin/bash

# preparation
git init .
git add -A

echo git commit -m "'$@'" # works when copied to terminal
git commit -m "'$@'" # fails if more than one parameter given
git commit -m $(echo "'$@'") # fails if more than one parameter given

rm -rf .git # c
Run Code Online (Sandbox Code Playgroud)

导致:

$ bash test.sh test2 test2
empty Git-Repository in /tests/bash-scripts/.git/ initialized
git commit -m 'test1 test2'
error: pathspec 'test2'' did not match any file(s) known to git.
error: pathspec 'test2'' did not match any file(s) known to git.
Run Code Online (Sandbox Code Playgroud)

如何将多个脚本参数作为单个字符串(包括空格)传递给外部可执行文件(而不将它们包装""在脚本调用中。


刚刚发现这有效:

 git commit -m "$(echo "'$@'")"
Run Code Online (Sandbox Code Playgroud)

但这让我更上一层楼:

-m如果没有给出参数,我想省略参数,以便触发提交消息编辑器:

if [ 0 != $# ]
then
  MESSAGE ="-m " "$(echo "'$@'")"
fi
git commit $MESSAGE
Run Code Online (Sandbox Code Playgroud)

或者

if [ 0 != $# ]
then
  MESSAGE =("-m " "$(echo "'$@'")")
fi
echo 
git commit ${MESSAGE[@]}
Run Code Online (Sandbox Code Playgroud)

这再次失败甚至wose,引用的词也分开了。:

$bash test.sh "test1 test2" test3
git commit -m 'test1 test2 test3'
error: pathspec 'test2' did not match any file(s) known to git.
error: pathspec 'test3'' did not match any file(s) known to git.
Run Code Online (Sandbox Code Playgroud)

cho*_*oba 5

如果要将所有参数解释为一个字符串,请使用

"$*"
Run Code Online (Sandbox Code Playgroud)

IE

git commit -m "$*"
Run Code Online (Sandbox Code Playgroud)

它记录在man bash“特殊参数”下:

*扩展到位置参数,从 1 开始。当扩展不在双引号内时,每个位置参数扩展为一个单独的词。在执行它的上下文中,这些词会受到进一步的分词和路径名扩展。当扩展发生在双引号内时,它扩展为单个单词,每个参数的值由IFS特殊变量的第一个字符分隔。也就是说,"$*"相当于"$1c$2c...",其中 c 是 IFS 变量值的第一个字符。如果为 null,则连接参数时不插入分隔符。IFS未设置,则参数以空格分隔。如果IFS