Вот выдержка из руководства (man sh
):
Если были указаны аргументы командной строки помимо параметров, то оболочка обрабатывает первый аргумент как имя файла, из которого нужно прочитать команды (сценарий оболочки), а остальные аргументы задаются как позиционные параметры оболочки ($ 1 , $ 2 и т.д.).
В противном случае оболочка читает команды со своего стандартного ввода.
Таким образом, в sh file.sh
указанный файл file.sh
становится источником ввода для оболочки, поэтому должен быть читаемым, но не обязательно исполняемым. То же самое относится и к source
или .
команда, поэтому следующие все запустят неисполняемый файл:-
sh ./file.sh
sh<./file.sh
. ./file.sh
source ./file.sh
Последние два будут выполняться в текущей оболочке, первые два - в под-оболочке. Обратите внимание, что для sh -c ./file.sh
для исполняемого файла потребуется file.sh
, а для sh -c ". ./file.sh"
необходимости. Также обратите внимание, что если file.sh
является исполняемым, то его местоположение должно быть в $PATH
если он вызывается напрямую, если не указан конкретный путь (./
в примере):
file.sh
Однако четыре предыдущих примера не нуждаются в префиксе ./
, поскольку файл для чтения всегда будет искать в текущем каталоге (хотя команды .
И source
также будут искать $PATH
).
Два последних пункта:-
- Четыре примера работают только для файлов сценариев: все они потерпят неудачу, если
file.sh
- двоичный исполняемый файл.
- В четырех примерах
#!/bin/bash
- это просто комментарий: исполняющий sh
будет читать его как таковой и не будет клонировать bash
для выполнения остальной части файла, поэтому любые расширения bash
в нем вызовут ошибки.