我正在编写一个调用另一个脚本的非常简单的脚本,我需要将参数从当前脚本传播到我正在执行的脚本。

例如,我的脚本名为foo.sh,调用bar.sh。

foo.sh:

bar $1 $2 $3 $4

如何在不显式指定每个参数的情况下做到这一点?


当前回答

如果在带引号的字符串中包含$@和其他字符,当有多个参数时,行为是非常奇怪的,只有第一个参数包含在引号中。

例子:

#!/bin/bash
set -x
bash -c "true foo $@"

收益率:

$ bash test.sh bar baz
+ bash -c 'true foo bar' baz

但是先赋值给另一个变量:

#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"

收益率:

$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'

其他回答

如果在带引号的字符串中包含$@和其他字符,当有多个参数时,行为是非常奇怪的,只有第一个参数包含在引号中。

例子:

#!/bin/bash
set -x
bash -c "true foo $@"

收益率:

$ bash test.sh bar baz
+ bash -c 'true foo bar' baz

但是先赋值给另一个变量:

#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"

收益率:

$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'
#!/usr/bin/env bash
while [ "$1" != "" ]; do
  echo "Received: ${1}" && shift;
done;

只是认为在尝试测试args如何进入脚本时,这可能更有用

使用“$@”(适用于所有POSIX兼容程序)。

[…), bash提供了“$@”变量,它扩展为所有用空格分隔的命令行参数。

以Bash为例。

我知道这个问题已经得到了很好的回答,但这里有一个“$@”$@“$*”和$*之间的比较

测试脚本内容:

# cat ./test.sh
#!/usr/bin/env bash
echo "================================="

echo "Quoted DOLLAR-AT"
for ARG in "$@"; do
    echo $ARG
done

echo "================================="

echo "NOT Quoted DOLLAR-AT"
for ARG in $@; do
    echo $ARG
done

echo "================================="

echo "Quoted DOLLAR-STAR"
for ARG in "$*"; do
    echo $ARG
done

echo "================================="

echo "NOT Quoted DOLLAR-STAR"
for ARG in $*; do
    echo $ARG
done

echo "================================="

现在,运行带有各种参数的测试脚本:

# ./test.sh  "arg with space one" "arg2" arg3
=================================
Quoted DOLLAR-AT
arg with space one
arg2
arg3
=================================
NOT Quoted DOLLAR-AT
arg
with
space
one
arg2
arg3
=================================
Quoted DOLLAR-STAR
arg with space one arg2 arg3
=================================
NOT Quoted DOLLAR-STAR
arg
with
space
one
arg2
arg3
=================================

有时你想传递所有的参数,但前面有一个标志(例如——flag)

$ bar --flag "$1" --flag "$2" --flag "$3"

你可以通过以下方式做到这一点:

$ bar $(printf -- ' --flag "%s"' "$@")

注意:为了避免额外的字段分割,您必须引用%s和$@,并且为了避免使用单个字符串,您不能引用printf的子shell。