#!/bin/sh
echo "Noise $1"
echo "Enhancement $2"
for snr in 0 5 10 15 20 25
do
python evaluate.py --noise $1 --snr 25 --iterations 1250 --enhancement $2
done
如果$2
未指定,我不想将参数传递--enhancement $2
给我的 python 脚本。我该怎么做呢?
答案1
修改原来的脚本:
#!/bin/sh
echo "Noise $1"
echo "Enhancement $2"
for snr in 0 5 10 15 20 25
do
python evaluate.py --noise "$1" --snr "$snr" --iterations 1250 ${2:+--enhancement "$2"}
done
标准参数扩展 ${var:+word}
word
如果变量var
已设置且不为空,则将扩展为。在上面的代码中,我们使用它来添加--enhancement "$2"
到命令(如果$2
可用且不为空)。
我还冒昧地假设您--snr
作为选项参数提供的应该是循环变量的值。
我个人对代码的看法(主要是使用printf
而不是echo
,避免长行,并给代码更多的空气):
#!/bin/sh
printf 'Noise %s\n' "$1"
printf 'Enhancement %s\n' "$2"
for snr in 0 5 10 15 20 25; do
python evaluate.py \
--noise "$1" \
--snr "$snr" \
--iterations 1250 \
${2:+--enhancement "$2"}
done
正如 mosvy 在下面的评论中指出的那样:如果您/bin/sh
碰巧是shell,或其他一些 shell在新的 shell 会话启动时dash
无法正确重置(这是 POSIX 所要求的),并且如果您出于某种原因,IFS
导出IFS
并给它一个非默认值,那么您可能需要unset IFS
在上面脚本的顶部使用。
每当你修好后就这样做IFS
出口无疑引起的所有其他问题(不要导出IFS
)。
答案2
在不支持任何数组的最小 POSIX shell 上,您只需使用set
命令操作位置参数列表即可。在循环之前for
你可以做
if [ -z "$2" ]; then
set -- --noise "$1" --snr 25 --iterations 1250
else
set -- --noise "$1" --snr 25 --iterations 1250 --enhancement "$2"
fi
现在运行你的 for 循环
for snr in 0 5 10 15 20 25; do
python evaluate.py "$@"
done
如果您的 shell 支持数组 bourne Again shellbash
或zsh
其他,您可以只使用数组
argv=(--noise "$1" --snr 25 --iterations 1250)
if [ ! -z "$2" ]; then
argv+=( --enhancement "$2" )
fi
现在将脚本称为
python evaluate.py "${argv[@]}"
正如评论中指出的,你是不是snr
使用for 循环中 value的实际值。使用脚本参数中适用的值$snr
,在这种情况下,您可能需要在循环内移动构造参数列表的逻辑。
答案3
您可以使用命令替换在一行中完成此操作
python evaluate.py --noise $1 --snr 25 --iterations 1250 $(test -n "$2" && echo --enhancement "$2")
答案4
使变量扩展消失的唯一方法是在扩展未加引号时将扩展扩展为空值。
$ unset a; b=''; c=set
$ printf '<%s> ' unquoted $a $b quoted "$a" "$b" val $c "$c"; echo
<unquoted> <quoted> <> <> <val> <s> <t> <set>
当不加引号时,变量的未设置值和空值(a
和b
)都会消失(作为参数)。引用时两者均被保留。
此外,如果包含在 IFS 中,甚至空格(或任何字符)也会消失。
$ IFS=' '
$ unset a; b=' '; c=' set '
$ printf '<%s> ' unquoted $a $b quoted "$a" "$b" val $c "$c"; echo
<unquoted> <quoted> <> < > <val> <set> < set >
事实上,在要扩展的值中包含字符(不带引号)的 IFS 将分隔参数。
$ IFS='e '
$ $ printf '<%s> ' unquoted $a $b quoted "$a" "$b" val $c "$c"; echo
<unquoted> <quoted> <> < > <val> <s> <t> < set >
请注意两个参数<s>
和 ,它们是在 IFS 包含 时<t>
扩展值而产生的。set
e
因此,我们需要对未设置或空值进行无引号扩展,当有值要扩展时,它会成为该值的带引号扩展:
${var:+"$var"}
描述:
${ # starts an un-quoted variable expansion
var # name of variable to expand
: # also replace if var is null
+ # use what follows if is not unset (nor null)
"$var" # a quoted variable expansion.
} # end of expansion.
# In short: expand "$var" if it has a value, $var otherwise.
然后我们可以利用$1
价值来消除它或扩大它
echo ${1:+"--noise"} ${1:+"$1"}
上面的行将打印二$1
如果有一些(非空)值,则单独的参数(不受 IFS 影响);如果$1
为空或未设置,则没有任何值。
该脚本将变为:
#!/bin/sh
echo "Noise $1"
echo "Enhancement $2"
for snr in 0 5 10 15 20 25
do python evaluate.py \
${1:+"--noise"} ${1:+"$1"} \
--snr "$snr" \
--iterations 1250 \
${2:+"--enhancement"} ${2:+"$2"}
done
该方案不受IFS值的影响