Чтобы запустить неисполняемый скрипт sh
, используйте:
sh myscript
Чтобы запустить неисполняемый скрипт bash
, используйте:
bash myscript
Запустить исполняемый файл (любой файл с разрешением на выполнение); вы просто указываете его по пути:
/foo/bar
/bin/bar
./bar
Чтобы сделать сценарий исполняемым, дайте ему необходимое разрешение:
chmod +x bar
./bar
Когда файл исполняемый, ядро отвечает за выяснение того, как его выполнить. Для недвоичных файлов это делается путем просмотра первой строки файла. Он должен содержать hashbang
:
#! /usr/bin/env bash
hashbang сообщает ядру, какую программу запускать (в этом случае команда /usr/bin/env
запускается с аргументом bash
). Затем сценарий передается программе (в качестве второго аргумента) вместе со всеми аргументами, которые вы указали сценарию в качестве последующих аргументов.
Это означает, что каждый исполняемый скрипт должен иметь хэш-банг . Если это не так, вы не сообщаете ядру, что это , то есть , и поэтому ядро не знает, какую программу использовать для его интерпретации. Это может быть bash
, perl
, python
, sh
или что-то еще. (На самом деле ядро часто использует оболочку пользователя по умолчанию для интерпретации файла, что очень опасно, потому что он может вообще не быть подходящим интерпретатором или может анализировать некоторые из них, но с небольшими поведенческими различиями, такими как регистр между sh
и bash
).
Записка о /usr/bin/env
Чаще всего вы увидите такие хэш-челки:
#!/bin/bash
В результате ядро запустит программу /bin/bash
для интерпретации сценария. К сожалению, bash
не всегда поставляется по умолчанию и не всегда доступен в /bin
. В то время как на машинах Linux это обычно так, есть ряд других машин POSIX, где bash
поставляется в различных местах, таких как /usr/xpg/bin/bash
или /usr/local/bin/bash
.
Поэтому для написания переносимого сценария bash мы не можем полагаться на жесткое программирование местоположения программы bash
. POSIX уже имеет механизм для решения этой проблемы: PATH
. Идея состоит в том, что вы устанавливаете свои программы в один из каталогов, которые находятся в PATH
, и система должна быть в состоянии найти вашу программу, когда вы хотите запустить ее по имени.
К сожалению, вы не можете просто сделать это:
#!bash
Ядро не (некоторые могут) выполнить поиск PATH
. Существует программа, которая может выполнить поиск PATH
, однако она называется env
. К счастью, почти во всех системах установлена программа env
, установленная в /usr/bin
. Поэтому мы запускаем env
с использованием жестко заданного пути, который затем PATH
выполняет поиск bash
и запускает его, чтобы он мог интерпретировать ваш сценарий:
#!/usr/bin/env bash
У этого подхода есть один недостаток: согласно POSIX, хэш-банг может иметь один аргумент . В этом случае мы используем bash
в качестве аргумента для программы env
. Это означает, что у нас нет места для передачи аргументов bash
. Так что нет способа конвертировать что-то вроде #!/bin/bash -exu
в эту схему. Вместо хеш-бенга вы должны поставить set -exu
.
У этого подхода есть и другое преимущество: некоторые системы могут поставляться с /bin/bash
, но пользователю это может не понравиться, он может обнаружить, что он неисправен или устарел, и, возможно, установил свой собственный bash
где-то еще. Это часто имеет место в OS X (Mac), где Apple поставляет устаревшую /bin/bash
, и пользователи устанавливают обновленную /usr/local/bin/bash
, используя что-то вроде Homebrew. Когда вы используете подход env
, который выполняет поиск PATH
, вы учитываете предпочтения пользователя и используете его предпочтительный bash по сравнению с тем, который поставлялась его системой.