Shell- script (#!/bin/sh vs #!/bin/csh)

Почему все script файлы начинаются с

#!/bin/sh

или

#!/bin/csh

Требуется ли это? Какова цель этого? И какая разница между ними?

Ответы

Ответ 1

Это называется 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

Ответ 2

Строка #! сообщает ядру (в частности, реализацию системного вызова 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, так что интерактивный командный язык будет таким же, как и язык сценариев, который вы изучаете.

Ответ 3

Определяет, какую оболочку (интерпретатор команд) вы используете для интерпретации/запуска 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