在bash shell脚本中传播所有参数

Propagate all arguments in a bash shell script

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

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

SH:

1
bar $1 $2 $3 $4

如何在不显式指定每个参数的情况下完成此操作?


如果您希望传递相同的参数,请使用"$@"而不是普通的$@

观察:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
$ cat foo.sh
#!/bin/bash
baz.sh $@

$ cat bar.sh
#!/bin/bash
baz.sh"$@"

$ cat baz.sh
#!/bin/bash
echo Received: $1
echo Received: $2
echo Received: $3
echo Received: $4

$ ./foo.sh first second
Received: first
Received: second
Received:
Received:

$ ./foo.sh"one quoted arg"
Received: one
Received: quoted
Received: arg
Received:

$ ./bar.sh first second
Received: first
Received: second
Received:
Received:

$ ./bar.sh"one quoted arg"
Received: one quoted arg
Received:
Received:
Received:


对于巴什和其他类似波恩的贝壳:

1
java com.myserver.Program"$@"


使用"$@"(适用于所有posix兼容项)。

[...] , bash features the"$@" variable, which expands to all command-line parameters separated by spaces.

一个接一个的例子。


1
2
3
4
#!/usr/bin/env bash
while ["$1" !="" ]; do
  echo"Received: ${1}" && shift;
done;

只是觉得在测试args如何进入脚本时,这可能会更有用一些。


我知道这个问题得到了很好的回答,但是这里比较了"$@"、"$@"、"$*"和$*

测试脚本内容:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
# 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"================================="

现在,使用各种参数运行测试脚本:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
# ./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
=================================

我的Sun Unix有很多限制,即使"$@"也没有按需要解释。我的解决方法是@。例如,

1
2
#!/bin/ksh
find ./ -type f | xargs grep"${@}"

顺便说一下,我必须有这个特定的脚本,因为我的Unix也不支持grep-r


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

例子:

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

产量:

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

但首先分配给不同的变量:

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

产量:

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


工作正常,除非您有空格或转义字符。在这种情况下,我找不到捕获参数并将其发送到脚本内部的ssh的方法。

这可能有用,但太难看了

1
_command_opts=$( echo"$@" | awk -F\- 'BEGIN { OFS=" -" } { for (i=2;i<=NF;i++) { gsub(/^[a-z] /,"&@",$i) ; gsub(/ $/,"",$i );gsub (/$/,"@",$i) }; print $0 }' | tr '@' \' )