Вот выдержка из руководства (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 в нем вызовут ошибки.