Почему все файлы скриптов начинаются с
#!/bin/sh
или с
#!/bin/csh
Это требуется? Какая у этого цель? И в чем разница между ними?
Почему все файлы скриптов начинаются с
#!/bin/sh
или с
#!/bin/csh
Это требуется? Какая у этого цель? И в чем разница между ними?
Ответы:
Это известно как Shebang
:
http://en.wikipedia.org/wiki/Shebang_(Unix)
#! интерпретатор [необязательный-аргумент]
Shebang имеет значение, только если у сценария есть разрешение на выполнение (например, chmod u + x script.sh).
Когда оболочка выполняет сценарий, она будет использовать указанный интерпретатор.
Пример:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#!
Строка сообщает ядро ( в частности, об осуществлении execve
системного вызова) , что эта программа написана на интерпретируемых языках; следующий за ним абсолютный путь идентифицирует интерпретатор. Программы, скомпилированные в машинный код, начинаются с другой последовательности байтов - в большинстве современных Unix-систем 7f 45 4c 46
(^?ELF ), которая идентифицирует их как таковые.
Вы можете указать абсолютный путь к любой программе после символа #!
, если эта программа сама по себе не является #!
сценарием. Ядро перезаписывает вызов
./script arg1 arg2 arg3 ...
где ./script
начинается, скажем, #! /usr/bin/perl
как если бы командная строка действительно была
/usr/bin/perl ./script arg1 arg2 arg3
Или, как вы видели, вы можете использовать #! /bin/sh
для написания сценария, предназначенного для интерпретации sh
.
#!
Строка обрабатывается только , если вы непосредственно вызывать скрипт ( ./script
в командной строке); файл также должен быть исполняемым ( chmod +x script
). Если вы линия не является необходимым (и будет игнорироваться , если он присутствует), и файл не должен быть исполняемым. Точка в функции, чтобы позволить вам непосредственно вызывать программы истолковано языка , не зная , на каком языке они написаны. (Dosh ./script
#!
grep '^#!' /usr/bin/*
- вы обнаружите , что очень многие фондовые программы, на самом деле , используя эту функцию.)
Вот несколько правил использования этой функции:
#!
должны быть самые первые два байта в файле. В частности, файл должен быть в кодировке, совместимой с ASCII (например, UTF-8 будет работать, а UTF-16 - нет) и не должен начинаться с «метки порядка байтов», иначе ядро не распознает его как #!
сценарий.#!
должен быть абсолютным (начинается с /
). Он не может содержать символы пробела, табуляции или новой строки.#!
и /
. Не помещайте здесь более одного места.#!
строку, они не будут расширены.#! /usr/bin/awk -f
), иногда просто полезно ( #! /usr/bin/perl -Tw
). К сожалению, после абсолютного пути нельзя поставить два или более аргумента.#! /usr/bin/env interpreter
вместо #! /absolute/path/to/interpreter
. Это почти всегда ошибка. Это делает поведение вашей программы зависимым от $PATH
переменной пользователя, который запускает скрипт. И не все системы env
в первую очередь.setuid
или setgid
которые не могут использовать привилегии #!
; они должны быть скомпилированы в машинный код. (Если вы не знаете, что это setuid
такое, не беспокойтесь об этом.)Что касается csh
, это sh
примерно так же, как Nutrimat Advanced Tea Substitute для чая. Он имеет (или, скорее, имел; современные реализации sh
догнали) ряд преимуществ перед sh
интерактивным использованием, но использование его (или его потомка tcsh
) для написания сценариев почти всегда является ошибкой . Если вы новичок в написании сценариев оболочки в целом, я настоятельно рекомендую вам игнорировать его и сосредоточиться на sh
. Если вы используете csh
родственника в качестве оболочки для входа в систему, переключитесь на bash
или zsh
, чтобы интерактивный командный язык был таким же, как язык сценариев, который вы изучаете.
#!
; Без комментариев, хороший ли это стиль. См. Этот вопрос и мой ответ для обсуждения плюсов и минусов #!/usr/bin/env
взлома.
#!/usr/bin/env
было правильно, но я по-прежнему считаю, что это почти всегда плохая идея.
Это определяет, какую оболочку (интерпретатор команд) вы используете для интерпретации / запуска вашего скрипта. Каждая оболочка немного отличается по способу взаимодействия с пользователем и выполнения скриптов (программ).
Когда вы вводите команду в командной строке Unix, вы взаимодействуете с оболочкой.
Например, #!/bin/csh
относится к C-shell, /bin/tcsh
t-shell, /bin/bash
bash shell и т. Д.
Вы можете сказать, какую интерактивную оболочку вы используете
echo $SHELL
команда, или альтернативно
env | grep -i shell
Вы можете изменить свою командную оболочку с помощью chsh
команды.
У каждого из них немного другой набор команд и способ назначения переменных, а также собственный набор программных конструкций. Например, оператор if-else с bash отличается от оператора C-оболочки.
Эта страница может быть интересна, поскольку она «переводит» между командами / синтаксисом bash и tcsh.
Использование директивы в сценарии оболочки позволяет запускать программы с использованием другой оболочки. Например, я использую tcsh
оболочку в интерактивном режиме, но часто запускаю сценарии bash, используя / bin / bash в файле сценария.
В сторону:
Эта концепция распространяется и на другие скрипты. Например, если вы программируете на Python, вы должны поместить
#!/usr/bin/python
в верхней части вашей программы Python
#! $SHELL
? Будет ли это поместить в Shebang правильную оболочку?
!#/bin/bash
директивы eg ,. Он сообщает системе, какую оболочку использовать для выполнения сценария оболочки.
$SHELL
не обязательно говорит вам, какую оболочку вы используете в данный момент; обычно он сообщает вам оболочку по умолчанию . tcsh устанавливает $version
и $tcsh
; наборы bash $BASH_VERSION
. Не все снаряды обязательно имеют одинаковые механизмы.
#!
строка должна соответствовать синтаксису сценария, а не интерактивной оболочке, используемой тем, кто запускает сценарий.
#!/bin/csh -f
;-f
говорит оболочке не к источнику пользователя.login
и.cshrc
, что делает скрипт запущен быстрее и избежать зависимостей от настройки пользователя. (Или еще лучше, не пишите сценарии csh.) Не используйте-f
для сценариев sh или bash; это не имеет того же значения.