Почему все файлы скриптов начинаются с
#!/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/tcsht-shell, /bin/bashbash 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; это не имеет того же значения.