Чому всі файли скриптів починаються з
#!/bin/sh
або с
#!/bin/csh
Це потрібно? Яка мета цього? І яка різниця між ними?
Чому всі файли скриптів починаються з
#!/bin/sh
або с
#!/bin/csh
Це потрібно? Яка мета цього? І яка різниця між ними?
Відповіді:
Це відомо як Shebang:
http://en.wikipedia.org/wiki/Shebang_(Unix)
#! інтерпретатор [необов’язково-аргумент]
Шебанг актуальний лише тоді, коли сценарій має дозвіл на виконання (наприклад, chmod u + x script.sh).
Коли оболонка виконує сценарій, вона використовуватиме вказаний інтерпретатор.
Приклад:
#!/bin/bash
# file: foo.sh
echo 1
$ chmod u+x foo.sh
$ ./foo.sh
1
#!Рядок повідомляє ядро ( в Зокрема, про здійсненні execveсистемного виклику) , що ця програма написана на інтерпретованих мовах; абсолютна назва шляху, що слідує, ідентифікує інтерпретатор. Програми, скомпільовані до машинного коду, починаються з іншої послідовності байтів - на більшості сучасних Unix, 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це, #!рядок не є необхідним (і буде проігноровано, якщо він присутній), і файл не повинен бути виконуваним. Точка в функції, щоб дозволити вам безпосередньо Invoke програми інтерпретовані мови , не знаючи , на якій мові вони написані. (Do 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, щоб інтерактивна мова команд була такою ж, як мова сценаріїв, яку ви вивчаєте.
#!; немає коментарів щодо того, чи це хороший стиль. Дивіться це питання та мою відповідь для обговорення плюсів і мінусів #!/usr/bin/envхакерства.
#!/usr/bin/envбуло правильно, але я залишаюсь на мою думку, що це майже завжди погана ідея.
Це визначає, яку оболонку (інтерпретатор команд) ви використовуєте для інтерпретації / запуску вашого сценарію. Кожна оболонка дещо відрізняється за тим, як вона взаємодіє з користувачем і виконує сценарії (програми).
Коли ви вводите команду в рядку Unix, ви взаємодієте з оболонкою.
Наприклад, #!/bin/cshвідноситься до C-оболонки, /bin/tcsht-оболонки, /bin/bashоболонки bash тощо.
Ви можете сказати, яку інтерактивну оболонку ви використовуєте
echo $SHELL
команди, або як варіант
env | grep -i shell
Ви можете змінити свою командну оболонку за допомогою chshкоманди.
Кожен має дещо інший набір команд і спосіб призначення змінних, а також свій власний набір конструктивних програм. Наприклад, оператор if-else з bash виглядає інакше, ніж той, що міститься в оболонці C.
Ця сторінка може зацікавити, оскільки вона "перекладає" між командами / синтаксисом bash та tcsh.
Використання директиви у сценарії оболонки дозволяє запускати програми, використовуючи іншу оболонку. Наприклад, я використовую tcshоболонку інтерактивно, але часто запускаю скрипти bash, використовуючи / bin / bash у файлі сценарію.
Окрім:
Ця концепція поширюється і на інші сценарії. Наприклад, якщо ви програмуєте на Python, який ви б поставили
#!/usr/bin/python
у верхній частині вашої програми Python
#! $SHELL? Чи поставить це правильну оболонку в Shebang?
!#/bin/bashдирективи. Він повідомляє системі, яку оболонку використовувати для виконання вашого сценарію оболонки.
$SHELLнеобов’язково вказує вам, яку оболонку ви запускаєте на даний момент; це зазвичай повідомляє вам вашу оболонку за замовчуванням . tcsh набори $versionта $tcsh; баш-набори $BASH_VERSION. Не всі оболонки обов'язково мають схожі механізми.
#!рядок повинен відповідати синтаксису сценарію, а не інтерактивній оболонці, що використовується тим, хто запускає сценарій.
#!/bin/csh -f;-fговорить оболонці ні до джерела користувача.loginі.cshrc, що робить скрипт запущений швидше і уникнути залежностей від настройки користувача. (Або ще краще, не пишіть скрипти csh.) Не використовуйте-fдля скриптів sh або bash; воно не має однакового значення.