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