Странный вывод из bash одним вкладышем
В процессе изучения bash я часто настраиваю существующую вещь и вижу ее вывод.
~$ for i in {1..19}; do echo "Everything in UNIX is a file."; sleep 1; done
У меня было это, и из любопытства я подправил вышеизложенное в следующее:
~$ for i in {1..19 * 2}; do echo "Everything in UNIX is a file."; echo "The value of i is ${i}"; sleep 1; done
Теперь, к моему удивлению, я начал получать следующий вывод:
Everything in UNIX is a file.
The value of i is OneDrive
Everything in UNIX is a file.
The value of i is opera autoupdate
Everything in UNIX is a file.
The value of i is Personal_Workspace
Everything in UNIX is a file.
The value of i is Pictures
Everything in UNIX is a file.
The value of i is PrintHood
Everything in UNIX is a file.
The value of i is Recent
Everything in UNIX is a file.
The value of i is Roaming
Everything in UNIX is a file.
The value of i is Saved Games
Everything in UNIX is a file.
The value of i is Searches
Некоторые из значений i - это имена файлов и каталогов в моем домашнем каталоге, я нахожусь в домашнем каталоге при выполнении этого скрипта.
То, что я ожидал, что значения i будут в диапазоне от 1 до 19*2 = 38, поэтому я буду принимать значения от 1,2,3...30...38. Но, очевидно, это не почему?
2 ответа
Да в bash
Расширение диапазона происходит раньше всего остального. Вы ожидали, что произойдет арифметическое расширение, которое не произошло ожидаемым из-за порядка расширения bash
ракушка. Ваш код закончил интерпретацию {1..19
, *
а также 2}
как буквальные строки.
поскольку *
имеет особое значение в оболочке, которая представляет собой глобальное расширение, в котором перечислены все файлы / каталоги в текущей папке. Также вы можете увидеть одну запись с указанием двух других строк, интерпретированных буквально.
Со страницы man bash(1) в разделе Expansion
Порядок расширений: расширение фигурных скобок, расширение тильды, расширение параметров, переменных и арифметики и подстановка команд (выполняется слева направо), разбиение слов и расширение имени пути.
Вы намного лучше, используя for
петля с ((..))
построить, если вы нацелены на сценарии для Bourne снова оболочки
for ((i=1; i<=38; i++)); do
*
Символ в оболочке Unix переводится в подстановочный знак, так что в основном то, что {1..19 * 2}
означает от 1 до 19, все файлы в текущем каталоге (это *), а затем 2. это будут значения i в вашем цикле