Анализ последовательности команд Unix: создание и выполнение скрипта

Дан фрагмент Bash-скрипта. Что здесь происходит?

cd ~
mkdir foo
touch bar && echo "ls foo" >> bar
chmod +x bar
./bar

Построчное выполнение

Ниже приведено последовательное объяснение каждой строки, включая смысл операторов && и >>.

cd ~
  • Происходит переход в домашний каталог текущего пользователя.
  • Символ ~ разворачивается оболочкой в путь домашней директории.
mkdir foo
  • Создается директория foo в текущем каталоге (после cd ~ — это ~/foo).
  • Если директория уже существует, команда обычно завершится ошибкой (в базовом варианте без -p).
touch bar && echo "ls foo" >> bar
  • touch bar:
    • создает файл bar, если его не было;
    • либо обновляет временные метки, если файл уже существует.
  • &&:
    • правая команда запускается только при успешном выполнении левой (то есть когда код завершения touch равен 0).
  • echo "ls foo" >> bar:
    • echo печатает строку ls foo в стандартный вывод;
    • >> bar перенаправляет этот вывод в файл bar в режиме добавления (append), то есть строка дописывается в конец файла;
    • если файла bar по какой-то причине нет, он будет создан при открытии на добавление.

В итоге содержимое bar становится таким (как минимум одна строка, без shebang):

ls foo

Важно понимать, что touch bar и >> bar могут привести к тому, что строка ls foo будет добавлена повторно при повторном запуске фрагмента (то есть появится несколько одинаковых строк).

chmod +x bar
  • Добавляется право исполнения для файла bar.
  • В практическом смысле это означает, что файл можно запускать как ./bar (при наличии прав и корректного формата исполнения).
./bar
  • Выполняется файл bar из текущей директории.
  • Префикс ./ важен: без него оболочка ищет команду по каталогам из PATH, а bar обычно не лежит в PATH.

Ожидаемое поведение в типичном интерактивном bash-сеансе:

  • оболочка попытается запустить файл как программу;
  • если файл является обычным текстом без shebang, может произойти попытка выполнить его как сценарий оболочки;
  • выполняется команда ls foo, которая выводит содержимое foo (здесь — пусто).

Таблица “что создается и меняется”:

ШагКомандаИзменениеИтог
1cd ~Меняется текущий каталогТекущий каталог = home
2mkdir fooФайловая системаПоявляется ~/foo/
3touch barФайловая системаПоявляется ~/bar (пустой) или обновляются метки
4echo "ls foo" >> barСодержимое файлаВ ~/bar дописывается строка ls foo
5chmod +x barПрава доступа~/bar становится исполняемым
6./barВыполнениеПечатается содержимое ~/foo/

Почему может работать без shebang

Shebang — это первая строка файла вида #!/path/to/interpreter, которая подсказывает системе, какой интерпретатор должен выполнять сценарий. Если shebang отсутствует, система не имеет явной подсказки, чем интерпретировать текстовый файл.

В Linux при попытке выполнить “неподходящий формат” файла ядро может вернуть ошибку формата выполнения (часто это связывают с Exec format error). После этого поведение зависит от оболочки:

  • некоторые оболочки пытаются повторно запустить файл через интерпретатор shell (условно “прочитать как команды”);
  • другие оболочки или среды запуска могут просто показать ошибку и завершиться.
Отсутствие shebang делает сценарий менее переносимым: в одном окружении он выполнится, а в другом — завершится ошибкой, либо будет выполнен другой оболочкой с отличающимися правилами синтаксиса.

Пример “более надежного” варианта файла bar:

#!/bin/sh
ls foo

Теория: &&, >> и chmod +x

Оператор && реализует “условную цепочку”: правая команда выполняется только если левая завершилась успешно. Это часто используется как короткая форма вместо if, когда нужно продолжать работу только при успехе.

Оператор >> — это перенаправление вывода в файл в режиме добавления:

  • > перезаписывает файл целиком;
  • >> дописывает в конец.

Команда chmod +x меняет права доступа:

  • x — бит исполнения;
  • + — добавление бита к текущим правам. При этом chmod не меняет содержимое файла: если в bar записана строка ls foo, то она такой и остается.

Схема потока выполнения:

cd ~
  |
  v
mkdir foo
  |
  v
touch bar  --(успех)-->  echo "ls foo" >> bar
   |                      |
   '---(ошибка)-----------'  (echo пропускается)
  |
  v
chmod +x bar
  |
  v
./bar  -> (часто) попытка интерпретации как shell-скрипта -> ls foo

Кратко: создается директория foo и файл bar, в bar дописывается команда ls foo, затем bar становится исполняемым и запускается; чаще всего выводится содержимое foo (пусто), а отсутствие shebang является потенциальной проблемой переносимости, хотя в bash нередко “работает”.