#!/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
지정되지 않은 경우 Python 스크립트에 $2
인수를 전달하고 싶지 않습니다 . --enhancement $2
어떻게 해야 하나요?
답변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
쉘이거나 새 쉘 세션이 시작될 때 다른 쉘이 제대로 재설정되지 않는 경우 dash
(POSIX에서 필요함) 어떤 이유로든 IFS
내보내고 IFS
제공 하십시오. 기본값이 아닌 값이면 unset IFS
위 스크립트의 맨 위에서 사용할 수 있습니다.
고칠 때마다 이렇게 하세요IFS
수출로 인해 의심할 여지 없이 제기되는 기타 모든 문제(내보내지 마십시오 IFS
).
답변2
배열을 지원하지 않는 최소 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
쉘이 bourne Again 쉘 bash
또는 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
변수 확장을 없애는 유일한 방법은 따옴표 없이 확장할 때 null로 확장하는 것입니다.
$ unset a; b=''; c=set
$ printf '<%s> ' unquoted $a $b quoted "$a" "$b" val $c "$c"; echo
<unquoted> <quoted> <> <> <val> <s> <t> <set>
따옴표를 해제하면 변수의 설정되지 않은 값과 null 값( 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
따라서 설정되지 않은 값이나 null 값을 따옴표로 묶지 않은 확장이 필요하며, 확장할 값이 있으면 해당 값을 따옴표로 묶은 확장이 됩니다.
${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이 아닌) 값이 있는 경우 별도의 매개변수(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 값의 영향을 받지 않습니다.