用于接收和重新传递引用参数的 Bash 脚本

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/448407/
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 17:53:54  来源:igfitidea点击:

Bash script to receive and repass quoted parameters

bashunix

提问by chilltemp

I'm trying to get quoted parameters of a bash script to safely be received by a nested script. Any ideas?

我试图让嵌套脚本安全地接收 bash 脚本的引用参数。有任何想法吗?

test.sh

测试文件

#!/bin/bash
echo $*
bash myecho.sh $*

myecho.sh

myecho.sh

#!/bin/bash
 echo 
 echo 
 echo 
 echo 

Sample:

样本:

bash test.sh aaa bbb '"ccc ddd"'

Result:

结果:

aaa bbb "ccc ddd"
aaa
bbb
"ccc
ddd"

Wanted result

想要的结果

aaa bbb "ccc ddd"
aaa
bbb
ccc ddd

采纳答案by pixelbeat

#!/bin/bash
echo $*
bash myecho.sh "$@"

Note the "$@" construct is not bash specific and should work with any POSIX shell (it does with dash at least). Note also that given the output you want, you don't need the extra level of quoting at all. I.E. just call the above script like:

请注意,“$@”构造不是特定于 bash 的,应该与任何 POSIX shell 一起使用(它至少可以与破折号一起使用)。另请注意,鉴于您想要的输出,您根本不需要额外的引用级别。IE 只需调用上面的脚本,如:

./test.sh 1 2 "3 4"

回答by Dave Dopson

You want to use "$@" (quoted dollar at) to pass parameters to a subscript. Like so ....

您想使用“$@”(引用美元)将参数传递给下标。像这样....

ls-color.sh:

ls-color.sh:

#!/bin/bash
/bin/ls --color=auto "$@"    # passes though all CLI-args to 'ls'



As to why.....

至于为什么……

From the Bash man page:

Bash 手册页

$*-- Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, it expands to a single word with the value of each parameter separated by the first character of the IFS special variable. That is, "$*"is equivalent to "$1c$2c...", where c is the first character of the value of the IFS variable. If IFS is unset, the parameters are separated by spaces. If IFS is null, the parameters are joined without intervening separators.

$@-- Expands to the positional parameters, starting from one. When the expansion occurs within double quotes, each parameter expands to a separate word. That is, "$@"is equivalent to "$1" "$2" ...If the double-quoted expansion occurs within a word, the expansion of the first parameter is joined with the beginning part of the original word, and the expansion of the last parameter is joined with the last part of the original word. When there are no positional parameters, "$@"and $@expand to nothing (i.e., they are removed).

$*-- 扩展到位置参数,从 1 开始。当扩展发生在双引号内时,它扩展为单个单词,每个参数的值由 IFS 特殊变量的第一个字符分隔。也就是说,"$*"相当于 "$1c$2c...",其中 c 是 IFS 变量值的第一个字符。如果未设置 IFS,则参数以空格分隔。如果 IFS 为空,则连接参数时不插入分隔符。

$@-- 扩展到位置参数,从 1 开始。当扩展发生在双引号内时,每个参数都扩展为一个单独的词。即"$@"等价于"$1" "$2" ...如果双引号扩展发生在一个词内,第一个参数的扩展与原词的开头部分连接,最后一个参数的扩展与原词的最后部分连接单词。当有没有位置参数, "$@"并且$@扩大到什么(即,它们被删除)。



Setting up some demo scripts ...

设置一些演示脚本...

echo 'echo -e "$1=\n$2=\n$3=\n$4="' > echo-params.sh
echo './echo-params.sh $*' > dollar-star.sh
echo './echo-params.sh $@' > dollar-at.sh
echo './echo-params.sh "$*"' > quoted-dollar-star.sh
echo './echo-params.sh "$@"' > quoted-dollar-at.sh
chmod +x *.sh

"$@"- quoted-dollar-at is an identity transformationfor re-passing args to a subshell (~99% of the time, this is what you meant to do):

"$@"-quoted-dollar-at 是一种身份转换,用于将 args 重新传递到子 shell(大约 99% 的时间,这就是您想要做的):

./quoted-dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
  # = aaa
  # =            
  # = 'cc cc'
  # = "ddd ddd"

"$*"- quoted-dollar-star smashes the args into a single string(~1% of the time you actually want this behavior, eg in a conditional: if [[ -z "$*" ]]; then ...):

"$*"-quoted-dollar-star将 args 粉碎成单个字符串(大约 1% 的时间您实际上想要这种行为,例如在条件中:)if [[ -z "$*" ]]; then ...

./quoted-dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
  # = aaa  'cc cc' "ddd ddd"   
  # =                     
  # =             
  # =

$*/ $@- without quotes, both forms strip off one level of quotation and interpret spaces from the underlying strings but ignore quotation characters (almost always, this is a mistake):

$*/ $@- 没有引号,这两种形式都会去掉一级引号并解释底层字符串中的空格,但忽略引号字符(几乎总是这样,这是一个错误):

./dollar-star.sh aaa '' "'cc cc'" '"ddd ddd"'
  # = aaa
  # = 'cc                  
  # = cc'
  # = "ddd

./dollar-at.sh aaa '' "'cc cc'" '"ddd ddd"'
  # = aaa
  # = 'cc
  # = cc'
  # = "ddd


If you want to have some fun, you can use "$@" to nest things as deep as you'd like, pushing and popping elements off the args stack if you like.

如果你想玩得开心,你可以使用“$@”来嵌套任意深的东西,如果你愿意,可以将元素从 args 堆栈中推入和弹出。

function identity() {
  "$@"
}
set -x
identity identity identity identity identity echo Hello \"World\"
# + identity identity identity identity identity echo Hello '"World"'
# + identity identity identity identity echo Hello '"World"'
# + identity identity identity echo Hello '"World"'
# + identity identity echo Hello '"World"'
# + identity echo Hello '"World"'
# + echo Hello '"World"'
# Hello "World"