Будьте осторожны, cat не является идеальным инструментом для отображения данных, которые могут быть двоичными.
Простым инструментом для Unix является od(восьмеричный дамп ).
Пример od -c -tx1
root@server:~# od -c -tx1 /etc/passwd | head
0000000 r o o t : x : 0 : 0 : r o o t :
72 6f 6f 74 3a 78 3a 30 3a 30 3a 72 6f 6f 74 3a
0000020 / r o o t : / b i n / b a s h \n
2f 72 6f 6f 74 3a 2f 62 69 6e 2f 62 61 73 68 0a
0000040 d a e m o n : x : 1 : 1 : d a e
64 61 65 6d 6f 6e 3a 78 3a 31 3a 31 3a 64 61 65
0000060 m o n : / u s r / s b i n : / u
6d 6f 6e 3a 2f 75 73 72 2f 73 62 69 6e 3a 2f 75
0000100 s r / s b i n / n o l o g i n \n
73 72 2f 73 62 69 6e 2f 6e 6f 6c 6f 67 69 6e 0a
так что вы можете видеть, что возврат каретки \n
Изменение исходного сценария:
#!/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
в качестве аргумента option -, должно быть значением переменной цикла.
Мой личный подход к коду (в основном просто использует 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[@]}"
Как указано в комментариях, вы не используете фактическое значение значения snr
из цикла for. Используйте значение как $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
(Также включает исправление переменной цикла в теле цикла)
Вы можете сделать это в одной строке, используя подстановку команд
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 >
Обратите внимание на два аргумента <s>
и <t>
, возникшие в результате раскрытия значения set
, когда IFS содержало 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"}
В приведенной выше строке будет либо напечатано два отдельных аргумента (, не затронутых IFS ), если $1
имеет некоторое (ненулевое )значение, либо ничего, если $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