Fra*_*rth 769 bash command-line-arguments
我正在编写一个调用另一个脚本的非常简单的脚本,我需要将参数从当前脚本传播到我正在执行的脚本.
例如,我的脚本名称是foo.sh
和调用bar.sh
foo.sh:
bar $1 $2 $3 $4
Run Code Online (Sandbox Code Playgroud)
如何在不明确指定每个参数的情况下执行此操作?
Sda*_*ons 1276
如果您真的希望您的参数传递相同,请使用"$@"
而不是plain $@
.
注意:
$ 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:
Run Code Online (Sandbox Code Playgroud)
Chr*_*sen 468
对于bash和其他类似Bourne的shell:
java com.myserver.Program "$@"
Run Code Online (Sandbox Code Playgroud)
mik*_*iku 93
使用"$@"
(适用于所有POSIX兼容机).
[...],bash具有"$ @"变量,该变量扩展为由空格分隔的所有命令行参数.
以Bash为例.
JDS*_*JDS 48
我意识到这已经得到了很好的解答,但这里是"$ @"$ @"$*"和$*之间的比较
测试脚本的内容:
# 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 "================================="
Run Code Online (Sandbox Code Playgroud)
现在,使用各种参数运行测试脚本:
# ./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
=================================
Run Code Online (Sandbox Code Playgroud)
Shi*_*hah 34
这里有很多答案推荐$@
或$*
带引号和不带引号,但是似乎没有人解释这些真正的作用以及为什么你应该这样做。所以让我从这个答案中窃取这个优秀的总结:
+--------+---------------------------+
| Syntax | Effective result |
+--------+---------------------------+
| $* | $1 $2 $3 ... ${N} |
+--------+---------------------------+
| $@ | $1 $2 $3 ... ${N} |
+--------+---------------------------+
| "$*" | "$1c$2c$3c...c${N}" |
+--------+---------------------------+
| "$@" | "$1" "$2" "$3" ... "${N}" |
+--------+---------------------------+
Run Code Online (Sandbox Code Playgroud)
请注意,引号使一切变得不同,如果没有它们,它们都具有相同的行为。
出于我的目的,我需要按原样将参数从一个脚本传递到另一个脚本,为此最好的选择是:
# file: parent.sh
# we have some params passed to parent.sh
# which we will like to pass on to child.sh as-is
./child.sh $*
Run Code Online (Sandbox Code Playgroud)
注意没有引号,$@
应该在上述情况下也能正常工作。
Gre*_*ore 31
#!/usr/bin/env bash
while [ "$1" != "" ]; do
echo "Received: ${1}" && shift;
done;
Run Code Online (Sandbox Code Playgroud)
只是认为在尝试测试args如何进入脚本时可能会更有用
我的SUN Unix有很多限制,甚至"$ @"也没有被解释为所希望的.我的解决方法是$ {@}.例如,
#!/bin/ksh
find ./ -type f | xargs grep "${@}"
Run Code Online (Sandbox Code Playgroud)
顺便说一句,我必须有这个特殊的脚本,因为我的Unix也不支持grep -r
如果$@
在带引号的字符串中包含其他字符,则当有多个参数时,行为非常奇怪,引号内仅包含第一个参数。
例:
#!/bin/bash
set -x
bash -c "true foo $@"
Run Code Online (Sandbox Code Playgroud)
产量:
$ bash test.sh bar baz
+ bash -c 'true foo bar' baz
Run Code Online (Sandbox Code Playgroud)
但是首先要分配一个不同的变量:
#!/bin/bash
set -x
args="$@"
bash -c "true foo $args"
Run Code Online (Sandbox Code Playgroud)
产量:
$ bash test.sh bar baz
+ args='bar baz'
+ bash -c 'true foo bar baz'
Run Code Online (Sandbox Code Playgroud)
有时你想传递所有参数,但前面有一个标志(例如--flag
)
$ bar --flag "$1" --flag "$2" --flag "$3"
Run Code Online (Sandbox Code Playgroud)
您可以通过以下方式执行此操作:
$ bar $(printf -- ' --flag "%s"' "$@")
Run Code Online (Sandbox Code Playgroud)
注意:为了避免额外的字段拆分,您必须引用%s
and $@
,并且为了避免单个字符串,您不能引用printf
.
bar "$@"
将相当于bar "$1" "$2" "$3" "$4"
请注意,引号很重要!
"$@"
、$@
、"$*"
或$*
每个在转义和连接方面的行为略有不同,如本stackoverflow 答案中所述。
一个密切相关的用例是将所有给定的参数传递到一个参数中,如下所示:
bash -c "bar \"$1\" \"$2\" \"$3\" \"$4\""
。
我使用@kvantour的答案的变体来实现这一点:
bash -c "bar $(printf -- '"%s" ' "$@")"
归档时间: |
|
查看次数: |
385394 次 |
最近记录: |