将 $@ 传递给命令,保留引号

将 $@ 传递给命令,保留引号

我正在尝试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

有关的:

相关内容