我正在尝试git
使用概述的方法来修改 的行为这里,但我在如何正确传递 的内容$@
而不丢失原始输入的引号方面遇到了困难。
基本上,我有这个:
# foo.sh
#!/bin/bash
cmd=$1
shift
args=$@
if [ $cmd == "bar" ]; then args=('--baz' "${args[@]}"); fi
echo git $cmd ${args[@]}
但是当我运行 时./foo.sh bar -a "one two three"
,它输出(因此会运行),./foo.sh bar --baz -a one two
而不是./foo.sh bar --baz -a "one two"
我需要的。
我不知道如何正确传递$@
到另一个命令并保留引用的参数。是否可以?如何?
答案1
使用时,"${args[@]}"
您假设它args
是一个数组,但事实并非如此。
要args
成为数组,必须用数组赋值来给它赋值,例如
args=( "$@" )
要在扩展 时单独引用数组的元素${args[@]}
,必须双引号扩展(就像 一样"$@"
):
echo git "$cmd" "${args[@]}"
在这个简单的示例中,args
根本不需要单独的数组:
#!/bin/sh
cmd=$1
shift
if [ "$cmd" = "bar" ]; then
set -- --baz "$@"
fi
echo git "$cmd" "$@"
请注意,上面的命令不会输出引号echo
。但你可以放心,它echo
恰好得到两个参数(git
和),再加上此时$cmd
有很多东西。$@
这是因为 shell 在执行命令之前会删除命令的引号。您可以将其与例如echo "one two" three
输出进行比较。
输出用于目视检查的命令的更好方法可能是
printf 'Arg: %s\n' git "$cmd" "$@"
这会将每个单独的参数打印在printf
其自己的行上(以字符串前缀Arg:
)。
您的git
命令git "$cmd" "$@"
(或者git "$cmd" "${args[@]}"
如果您使用单独的数组)将正确运行(假设变量有意义,例如,普通命令git
没有bar
带选项的子命令)。--baz
有关的: