#!/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スクリプトに渡したくありません。どうすればよいですか?
元のスクリプトを変更します。
#!/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
がdash
シェル、または新しいシェルセッションの開始時にIFS
を適切にリセットしない他のシェルである場合(これはPOSIXで必要です)、何らかの理由でIFS
をエクスポートし、それにデフォルト以外の値を指定した場合は、上記の上部でunset IFS
を使用することができます。脚本。
修正したときはいつでも_IFS
をエクスポートする他のすべての問題が疑いなく発生しました(_IFS
をエクスポートしないでください) 。
配列をサポートしない最小限のPOSIXシェルでは、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
シェルが配列ボーンを再度サポートしている場合は、シェルbash
、zsh
またはその他の場合、配列を使用できます
argv=(--noise "$1" --snr 25 --iterations 1250)
if [ ! -z "$2" ]; then
argv+=( --enhancement "$2" )
fi
スクリプトを次のように呼び出します
python evaluate.py "${argv[@]}"
コメントで指摘されているように、あなたはnot forループからのsnr
値の実際の値を使用しています。スクリプト引数の該当する場合は、値を$snr
として使用します。この場合、引数リストを作成するロジックをループ内に移動する必要がある場合があります。
入力に基づいて変数に引数を作成します。
#!/bin/sh
echo "Noise $1"
echo "Enhancement $2"
if [ $# -eq 1 ]
then
enhance=""
else
enhance="--enhancement $2"
fi
for snr in 0 5 10 15 20 25
do
python evaluate.py --noise $1 --snr "$snr" --iterations 1250 $enhance
done
(ループ本体のループ変数の修正も含まれます)
コマンド置換を使用して、1行で実行できます。
python evaluate.py --noise $1 --snr 25 --iterations 1250 $(test -n "$2" && echo --enhancement "$2")
変数展開を非表示にする唯一の方法は、展開が引用符で囲まれていないときに展開を空の値に展開させることです。
$ 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 >
IFSにset
が含まれている場合に値e
を拡張した結果として生じた2つの引数<s>
および<t>
に注意してください。
したがって、展開する値がある場合に、値の引用符で囲まれた展開になる、未設定または空の値の引用符で囲まれていない展開が必要です。
${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
にいくつかの(nullではない)値がある場合はtwo個別の引数(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の価値の影響を受けません