[英]Strange behavior with parameter expansion in program arguments
I'm trying to conditionally pass an argument to a bash script only if it has been set in the calling script and I've noticed some odd behavior. 我试图仅在调用脚本中设置了参数的情况下才将参数传递给bash脚本,并且我注意到某些奇怪的行为。 I'm using parameter expansion to facilitate this, outputting an option only if the corresponding variable is set.
我正在使用参数扩展来简化此操作,仅在设置了相应变量的情况下才输出选项。 The aim is to pass an argument from a 'parent' script to a 'child' script.
目的是将参数从“父”脚本传递到“子”脚本。
Consider the following example: 考虑以下示例:
The calling script: 调用脚本:
#!/bin/bash
# 1.sh
ONE="TEST_ONE"
TWO="TEST_TWO"
./2.sh \
--one "${ONE}" \
"${TWO:+"--two ${TWO}"}" \
--other
and the called script: 和被调用的脚本:
#!/bin/bash
# 2.sh
while [[ $# -gt 0 ]]; do
key="${1}"
case $key in
-o|--one)
ONE="${2}"
echo "ONE: ${ONE}"
shift
shift
;;
-t|--two)
TWO="${2}"
echo "TWO: ${TWO}"
shift
shift
;;
-f|--other)
OTHER=1
echo "OTHER: ${OTHER}"
shift
;;
*)
echo "UNRECOGNISED: ${1}"
shift
;;
esac
done
output: 输出:
ONE: TEST_ONE
UNRECOGNISED: --two TEST_TWO
OTHER: 1
Observe the behavior of the option '--two', which will be unrecognised. 观察选项“ --two”的行为,该行为不会被识别。 It looks like it is being expanded correctly, but is not recognised as being two distinct strings.
看起来好像已正确扩展了该字符串,但并未将其识别为两个不同的字符串。 Can anyone explain why this is happening?
谁能解释为什么会这样? I've seen it written in one source that
it will not work with positional parameter arguments
, but I'm still not understanding why this behaves as it does. 我已经看到它是在一个来源中编写的,
it will not work with positional parameter arguments
,但是我仍然不明白为什么这样做会如此。
It is because when you pass $2
as a result of parameter expansion from 1.sh
you are quoting it in a way that --two TEST_TWO
is evaluated as one single argument, so that the number of arguments in 2.sh
result in 4
instead of 5
这是因为当您从
$2
1.sh
进行参数扩展时传递$2
时,您以--two TEST_TWO
作为一个单一参数求值的方式1.sh
进行引用,从而使2.sh
中的参数数改为4
共5
But that said, using your $2
as ${TWO:+--two ${TWO}}
would solve the problem, but that would word-split the content of $2
if it contains spaces. 但这就是说,将您的
$2
用作${TWO:+--two ${TWO}}
可以解决此问题,但是如果$2
包含空格,则会将其单词拆分。 You need to use arrays. 您需要使用数组。
As a much more recommended and fail-proof approach use arrays as below on 1.sh
as 作为一种更推荐
1.sh
方法,请在1.sh
上使用以下数组:
argsList=(--one "${ONE}" ${TWO:+--two "${TWO}"} --other)
and pass it along as 并将其作为
./2.sh "${argsList[@]}"
or if you are familiar with how quoting rules work (how and when to quote to prevent word-splitting from happening) use it directly on the command line as below. 或者,如果您熟悉引用规则的工作原理(如何以及何时引用以防止单词拆分的发生),请在命令行上直接使用它,如下所示。 This would ensure that the contents variables
ONE
and TWO
are preserved even if they have spaces. 这样可以确保内容变量
ONE
和TWO
即使有空格也可以保留。
./2.sh \
--one "${ONE}" \
${TWO:+--two "${TWO}"} \
--other
As a few recommended guidelines 作为一些推荐的准则
getopts()
for more robust argument flags parsing getopts()
进行更健壮的参数标志解析
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.