Является ли #! / bin / sh интерпретатором?

57

В bash или sh , я думаю, что все, что начинается с # , это комментарий .

Но в скриптах bash мы пишем:

#!/bin/bash

В сценариях Python есть:

#!/bin/python

Означает ли это, что # сам по себе является комментарием, тогда как #! не является?

    
задан Gaurav Sharma 09.01.2013 в 07:04
источник

3 ответа

85

Строка #! используется до , сценарий запускается, а затем игнорируется , когда запускается сценарий.

Вы спрашиваете, какая разница между линией shebang и обычным комментарием.

Строка, начинающаяся с #! , является таким же комментарием, как и любая другая строка, начинающаяся с # . Это верно, если #! - первая строка файла или где-либо еще. #!/bin/sh имеет эффект , но он не читается самим интерпретатором .

# не является комментарием на всех языках программирования, но, как вы знаете, это комментарий в оболочках в стиле Бурна, включая sh и bash (а также большинство оболочек не-борновского типа, например% код%). Это также комментарий в Python . И это комментарий в различных конфигурационных файлах, которые вообще не являются скриптами (например, csh ).

Предположим, что сценарий оболочки начинается с /etc/fstab . Это комментарий, и интерпретатор (оболочка) игнорирует все в строке после символа #!/bin/sh .

Цель строки # не предоставлять информацию интерпретатору. Цель строки #! - сообщить операционной системе (или какой-либо процесс запуска интерпретатора) , что использовать в качестве интерпретатора .

  • Если вы вызываете скрипт как исполняемый файл, например, запустив #! , система проконсультирует первую строку, чтобы увидеть, начинается ли с ./script.sh , а затем ноль или более пробелов, за которым следует команда. Если это так, он запускает эту команду с именем скрипта в качестве аргумента. В этом примере он запускает #! (или, технически, /bin/sh script.sh ).

  • Если вы вызываете скрипт, явно вызывая интерпретатор, никогда не проконсультируйтесь с линией /bin/sh ./script.sh . Итак, если вы запустите #! , первая строка не имеет эффекта. Если первая строка sh script.sh равна script2.sh , запуск #!/usr/games/nibbles не будет пытаться открыть скрипт в sh script2.sh (но nibbles будет).

Вы заметите, что ни в одном случае расширение скрипта ( ./script2.sh ), если оно есть, влияет на его запуск. В Unix-подобной системе это обычно не влияет на запуск сценария. В некоторых других системах, таких как Windows, строка .sh shebang может полностью игнорироваться системой, а расширение может определять, что запускает скрипты. (Это не значит, что вам нужно дать свои расширения для скриптов, но это одна из причин, почему, если вы это сделаете, они должны быть правильными.)

#! выбрано для этой цели точно , потому что #! начинает комментарий. Строка # предназначена для системы, а не для интерпретатора, и ее интерпретатор должен игнорировать.

Строка Shebang для скриптов Bash

Вы (первоначально) сказали, что используете #! для скриптов #!/bin/sh . Вы должны сделать это только в том случае, если скрипт не требует каких-либо из bash расширений - bash должен иметь возможность запускать скрипт. sh не всегда является символической ссылкой на sh . Часто, включая все удаленные системы Debian и Ubuntu, bash является символической ссылкой на sh .

Строка Shebang для скриптов Python

Вы также сказали (в первой версии своего вопроса перед редактированием), что вы запускаете свои скрипты Python с dash . Если вы имеете в виду это буквально, то вы должны обязательно прекратить это делать. Если #!/bin/sh read by the interpretor начинается с этой строки, выполняется hello.py :

/bin/sh read by the interpretor hello.py

./hello.py попытается выполнить скрипт с именем /bin/shread в качестве его аргументов), by the interpretor hello.py будет (надеюсь) не найден, и ваш скрипт Python никогда не увидит интерпретатор Python.

Если вы делаете эту ошибку, но не имеете проблемы, которую я описываю, вы, вероятно, ссылаетесь на свои скрипты на Python, явно указывая интерпретатор (например, read ), вызывая игнорирование первой строки. Когда вы распространяете свои скрипты другим или используете их долгое время позже, может быть неясно, что это необходимо для их работы. Лучше всего их исправить. Или, по крайней мере, удалить первую строку целиком, так что, когда они не смогут работать с python hello.py , сообщение об ошибке будет иметь смысл.

Для скриптов Python, если вы знаете, где находится (или будет) Python, вы можете написать строку ./ так же:

#!/usr/bin/python

Или, если это скрипт Python 3, вы должны указать #! , так как python3 почти всегда Python 2:

#!/usr/bin/python3

Однако проблема заключается в том, что, хотя предполагается, что python всегда существует, а /bin/sh почти всегда существует в системах, где /bin/bash поставляется с ОС, Python может существовать в разных местах.

Поэтому многие программисты Python используют это вместо:

#!/usr/bin/env python

(Или bash для Python 3.)

Это заставляет скрипт полагаться на #!/usr/bin/env python3 , находясь в «правильном месте» вместо того, чтобы полагаться на env , находясь в нужном месте. Это хорошо, потому что:

  • python почти всегда находится в env .
  • В большинстве систем, в зависимости от того, какой из /usr/bin должен запускать ваш скрипт, тот, который появляется первым в python . Запуск PATH с hello.py make #!/usr/bin/env python run ./hello.py , который (фактически) эквивалентен запуску /usr/bin/env python hello.py .

Причина, по которой вы не можете использовать python hello.py , такова:

  • Вы хотите, чтобы интерпретатор задавался абсолютным путем (т. е. начиная с #!python ).
  • Вызывающий процесс выполнил бы / в текущем каталоге. Поведение поиска пути, когда команда не содержит косой черты, - это поведение конкретной оболочки.

Иногда Python или другой скрипт, который не является скриптом оболочки, будет иметь строку shebang, начиная с python , где #!/bin/sh ... - это другой код. Иногда это правильно, потому что есть некоторые способы вызвать совместимую с Bourne оболочку ( ... ) с аргументами, чтобы заставить ее вызвать интерпретатор Python. (Один из аргументов, вероятно, будет содержать sh .) Однако для большинства целей python проще, более элегантно и с большей вероятностью работает так, как вы хотите.

Линии Шебанга на других языках

Многие языки программирования и скриптов и некоторые другие форматы файлов используют #!/usr/bin/env python в качестве комментария. Для любого из них файл на языке может быть запущен программой, которая принимает его как аргумент, указав программу в первой строке после # .

В некоторых языках программирования #! обычно не является комментарием, но в качестве частного случая первая строка игнорируется, если она начинается с # . Это облегчает использование синтаксиса #! , хотя #! не делает иначе комментарий.

Линии Shebang для файлов, которые не запускаются как скрипты

Хотя он менее интуитивно понятен, любой файл, формат файла которого может содержать первую строку, начинающуюся с # , за которой следует полный путь к исполняемому файлу, может иметь строку shebang. Если вы сделаете это, и файл будет помечен как исполняемый файл, вы можете запустить его как программу ... заставляя его открываться как документ.

Некоторые приложения используют это поведение намеренно. Например, в VMware #! файлов определяют виртуальные машины. Вы можете «запустить» виртуальную машину, как если бы это был скрипт, потому что эти файлы отмечены как исполняемые и имеют строку shebang, заставляющую их открываться в утилите VMware.

Линии Shebang для файлов, которые не запускаются в виде скриптов, но в любом случае действуют как скрипты

.vmx удаляет файлы. Это не скриптовый язык. Однако файл, который запускает rm и помечен как исполняемый, может быть запущен, а при его запуске на него вызывается #!/bin/rm , удаляя его.

Это часто концептуализируется как «файл удаляет себя». Но файл вообще не работает. Это больше похоже на ситуацию, описанную выше для файлов rm .

Тем не менее, поскольку строка .vmx облегчает выполнение упрощенной команды (включая аргументы командной строки), вы можете выполнить некоторые сценарии таким образом. В качестве простого примера «сценария», более сложного, чем #! , рассмотрим:

#!/usr/bin/env tee -a

Это вводит пользовательский ввод в интерактивном режиме, отсылает его обратно пользователю по очереди и добавляет его в конец файла сценария.

Полезно? Не очень. Концептуально интересно? Полностью! Да. (Несколько).

Концептуально похожие понятия программирования / сценариев (просто для удовольствия)

ответ дан Eliah Kagan 09.01.2013 в 08:30
источник
7

Шэбанг - это последовательность символов, состоящая из знака числа знаков и восклицательного знака (например, «#!»), когда он встречается как начальные два символа в начальной строке скрипта.

В операционных системах под * nix, когда запускается скрипт, начинающийся с shebang, программный загрузчик анализирует остальную часть начальной строки скрипта в качестве директивы интерпретатора; вместо этого выполняется указанная программа интерпретатора, передавая ей в качестве аргумента путь, который изначально использовался при попытке запустить скрипт. Например, если сценарий назван с пуском «путь / к / ваш-скрипт» и начинается со следующей строки:

#!/bin/sh

, тогда загрузчику программы будет предложено запустить программу «/ bin / sh», вместо этого, например. оболочкой Bourne или совместимой оболочкой, передавая «путь / в / ваш-скрипт» в качестве первого аргумента.

Соответственно, это сценарий с именем path / to / python-script и начинается со следующей строки:

#!/bin/python

, тогда загруженной программе предлагается запустить программу «/ bin / python», а не, например. Python, передавая в качестве первого аргумента «path / to / python-script».

Короче говоря, «#» будет комментировать строку, а последовательность символов «#!» как первые два символа в начальной строке скрипта имеет значение, описанное выше.

Подробнее см. Почему некоторые скрипты начинаются с #! ...?

Источник: Некоторые разделы этого ответа выводятся (с небольшими изменениями) из Shebang (Unix) на Английская Википедия (от авторов Wikipedia ). Эта статья лицензирована под CC-BY-SA 3.0 , так же как и пользовательский контент здесь, на AU, поэтому этот вывод разрешен с атрибуцией.     

ответ дан Goran Miskovic 09.01.2013 в 07:57
4

#! называется shebang , когда он встречается как начальные два символа в начальной строке скрипта. Он используется в сценариях для указания интерпретатора для выполнения. % Co_de% для операционной системы (ядра), а не для оболочки; поэтому он не будет интерпретироваться как комментарий.

Предоставлено: Ссылка

  

В общем случае, если файл исполняемый, но фактически не исполняемый файл   (двоичной) программы, и такая строка присутствует, указанная программа   после #! запускается с именем сценария и всеми его аргументами. Эти   два символа # и! должны быть первые два байта в файле!

Подробная информация: Ссылка

    
ответ дан saji89 09.01.2013 в 07:34