Заголовки сценариев оболочки (#!/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

Другие вопросы по тегам