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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4824590/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-09 20:08:17  来源:igfitidea点击:

Propagate all arguments in a bash shell script

bashcommand-line-arguments

提问by Fragsworth

I am writing a very simple script that calls another script, and I need to propagate the parameters from my current script to the script I am executing.

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

For instance, my script name is foo.shand calls bar.sh

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

foo.sh:

foo.sh:

bar    

How can I do this without explicitly specifying each parameter?

如何在不明确指定每个参数的情况下执行此操作?

回答by Sdaz MacSkibbons

Use "$@"instead of plain $@if you actually wish your parameters to be passed the same.

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

Observe:

观察:

$ cat foo.sh
#!/bin/bash
baz.sh $@

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

$ cat baz.sh
#!/bin/bash
echo Received: 
echo Received: 
echo Received: 
echo Received: 

$ ./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:

回答by Chris Johnsen

For bashand other Bourne-like shells:

对于bash和其他类似 Bourne 的 shell:

java com.myserver.Program "$@"

回答by miku

Use "$@"(works for all POSIXcompatibles).

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

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

[...] ,bash 具有 "$@" 变量,它扩展到所有由空格分隔的命令行参数。

From Bash by example.

来自Bash 的例子

回答by JDS

I realize this has been well answered but here's a comparison between "$@" $@ "$*" and $*

我意识到这已经得到了很好的回答,但这里是 "$@" $@ "$*" 和 $* 之间的比较

Contents of test script:

测试脚本内容:

# 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 "================================="

Now, run the test script with various arguments:

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

# ./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
=================================

回答by Gregory Patmore

#!/usr/bin/env bash
while [ "" != "" ]; do
  echo "Received: " && shift;
done;

Just thought this may be a bit more useful when trying to test how args come into your script

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

回答by Hampden123

My SUN Unix has a lot of limitations, even "$@" was not interpreted as desired. My workaround is ${@}. For example,

我的 SUN Unix 有很多限制,甚至“$@”也没有按预期解释。我的解决方法是 ${@}。例如,

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

By the way, I had to have this particular script because my Unix also does not support grep -r

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

回答by ColinM

If you include $@in a quoted string with other characters the behavior is very odd when there are multiple arguments, only the first argument is included inside the quotes.

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

Example:

例子:

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

Yields:

产量:

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

But assigning to a different variable first:

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

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

Yields:

产量:

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

回答by kvantour

Sometimes you want to pass all your arguments, but preceded by a flag (e.g. --flag)

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

$ bar --flag "" --flag "" --flag ""

You can do this in the following way:

您可以通过以下方式执行此操作:

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

note:to avoid extra field splitting, you must quote %sand $@, and to avoid having a single string, you cannot quote the subshell of printf.

注意:为了避免额外的字段拆分,您必须引用%sand $@,并且为了避免单个字符串,您不能引用printf.

回答by user6650302

Works fine, except if you have spaces or escaped characters. I don't find the way to capture arguments in this case and send to a ssh inside of script.

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

This could be useful but is so ugly

这可能很有用,但太丑了

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

回答by Shital Shah

A lot answers here recommends $@or $*with and without quotes, however none seems to explain what these really do and why you should that way. So let me steal this excellent summary from this answer:

这里有很多答案推荐$@$*带引号和不带引号,但是似乎没有人解释这些真正的作用以及为什么你应该这样做。所以让我从这个答案中窃取这个优秀的总结:

enter image description here

在此处输入图片说明

Notice that quotes makes all the difference and without them both have identical behavior.

请注意,引号使一切变得不同,没有它们,它们的行为都相同。

For my purpose, I needed to pass parameters from one script to another as-is and for that the best option is:

出于我的目的,我需要按原样将参数从一个脚本传递到另一个脚本,为此最好的选择是:

##代码##

Notice no quotes and $@should work as well in above situation.

注意没有引号,$@应该在上述情况下也能正常工作。