Проблема в том, что вы не цитируете $ line
. Для исследования измените два сценария так, чтобы они просто выводили $ line
:
#!/usr/bin/env bash
while read line; do
echo $line
done < "$1"
и
#!/usr/bin/env zsh
while read line; do
echo $line
done < "$1"
Теперь сравните их вывод:
$ bash.sh input
foo bar baz
foo bar baz
$ zsh.sh input
foo bar baz
foo bar baz
Как видите, потому что вы не цитируете $ line
, вкладки неправильно интерпретируются bash. Zsh, кажется, справляется с этим лучше. Теперь cut
по умолчанию использует \ t
в качестве разделителя полей. Следовательно, поскольку ваш сценарий bash
использует вкладки (из-за оператора split + glob), cut
видит только одно поле и действует соответственно. На самом деле вы выполняете:
$ echo "foo bar baz" | cut -f 2
foo bar baz
Итак, чтобы ваш скрипт работал должным образом в обеих оболочках, укажите вашу переменную в кавычках:
while read line; do
<<<"$line" cut -f 2
done < "$1"
Затем оба выдают одинаковый результат:
$ bash.sh input
bar
bar
$ zsh.sh input
bar
bar