gpt4 book ai didi

linux - 程序参数中参数扩展的奇怪行为

转载 作者:太空狗 更新时间:2023-10-29 11:48:38 25 4
gpt4 key购买 nike

我试图有条件地将参数传递给 bash 脚本,前提是它已在调用脚本中设置并且我注意到一些奇怪的行为。我正在使用参数扩展来促进这一点,只有在设置了相应的变量时才输出一个选项。目的是将参数从“父”脚本传递到“子”脚本。

考虑以下示例:

调用脚本:

#!/bin/bash
# 1.sh

ONE="TEST_ONE"
TWO="TEST_TWO"

./2.sh \
--one "${ONE}" \
"${TWO:+"--two ${TWO}"}" \
--other

和被调用的脚本:

#!/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

输出:

ONE: TEST_ONE
UNRECOGNISED: --two TEST_TWO
OTHER: 1

观察选项“--two”的行为,它将无法识别。看起来它正在被正确扩展,但未被识别为两个不同的字符串。谁能解释为什么会这样?我看到它写在one source 它不适用于位置参数参数,但我仍然不明白为什么会这样。

最佳答案

这是因为当您通过 1.sh 的参数扩展传递 $2 时,您以 --two TEST_TWO< 的方式引用它 被评估为一个参数,因此 2.sh 中的参数数量导致 4 而不是 5

但是也就是说,使用你的 $2 作为 ${TWO:+--two ${TWO}} 会解决问题,但是那会分词$2 的内容(如果它包含空格)。您需要使用数组。

作为更推荐和防故障的方法,在 1.sh 上使用如下数组作为

argsList=(--one "${ONE}" ${TWO:+--two "${TWO}"} --other)

并将其传递给

./2.sh "${argsList[@]}"

或者如果您熟悉引用规则的工作原理(如何以及何时引用以防止发生分词),请直接在命令行上使用它,如下所示。这将确保保留内容变量 ONETWO,即使它们有空格也是如此。

./2.sh \
--one "${ONE}" \
${TWO:+--two "${TWO}"} \
--other

一些推荐的指南

  • 始终对用户定义的变量使用小写变量名称,以免将它们与 shell 本身维护的环境变量混淆。
  • 使用 getopts() 进行更稳健的参数标志解析

关于linux - 程序参数中参数扩展的奇怪行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53849223/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com