Заголовки сценариев оболочки (#!/bin/sh vs #!/bin/csh)
Почему все файлы сценариев начинаются с
#!/bin/sh
или с
#!/bin/csh
Это требуется? Какова цель этого? И в чем разница между двумя?
3 ответа
Это известно как Shebang
:
http://en.wikipedia.org/wiki/Shebang_%28Unix%29
#! интерпретатор [необязательный аргумент]
Шебанг имеет значение только тогда, когда скрипт имеет разрешение на выполнение (например, chmod u+x script.sh).
Когда оболочка выполняет скрипт, она будет использовать указанный интерпретатор.
Пример:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#!
строка сообщает ядру (в частности, о реализации execve
системный вызов), что эта программа написана на интерпретируемом языке; Абсолютный путь, который следует, идентифицирует интерпретатор. Программы, скомпилированные для машинного кода, начинаются с другой последовательности байтов - в большинстве современных Unixes, 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
). Если вы делаете sh ./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 Заменитель делает с чаем. Он имеет (или, скорее, имел; современные реализации sh
догнали) ряд преимуществ перед sh
для интерактивного использования, но используя его (или его потомка tcsh
) для скриптинга это почти всегда ошибка. Если вы новичок в сценариях оболочки в целом, я настоятельно рекомендую вам игнорировать его и сосредоточиться на sh
, Если вы используете csh
относительно вашей оболочки входа в систему, переключитесь на bash
или же zsh
, так что интерактивный командный язык будет таким же, как и язык сценариев, который вы изучаете.
Это определяет, какую оболочку (командный интерпретатор) вы используете для интерпретации / запуска вашего скрипта. Каждая оболочка немного отличается тем, как она взаимодействует с пользователем и выполняет скрипты (программы).
Когда вы вводите команду в командной строке Unix, вы взаимодействуете с оболочкой.
Например, #!/bin/csh
относится к C-оболочке, /bin/tcsh
Т-оболочка, /bin/bash
оболочка bash и т. д.
Вы можете сказать, какую интерактивную оболочку вы используете
echo $SHELL
команда, или в качестве альтернативы
env | grep -i shell
Вы можете изменить командную оболочку с помощью chsh
команда.
Каждый из них имеет свой набор команд и способ назначения переменных, а также свой собственный набор программных конструкций. Например, оператор if-else с bash выглядит не так, как в C-shell.
Эта страница может представлять интерес, поскольку она "переводит" между командами / синтаксисом bash и tcsh.
Использование директивы в сценарии оболочки позволяет запускать программы с использованием другой оболочки. Например, я использую tcsh
Оболочка в интерактивном режиме, но часто запускает сценарии bash, используя /bin/bash в файле сценария.
В сторону:
Эта концепция распространяется и на другие сценарии. Например, если вы программируете на Python, вы бы поставили
#!/usr/bin/python
в верхней части вашей программы Python