Я написал простой сценарий. Когда я запускаю sh <myscriptname.sh>
, я получаю правильный вывод, но когда я запускаю ./<myscriptname.sh>
, я получаю ошибку.
В чем разница между тем, когда я делаю sh
и ./
?
Когда вы запускаете любой сценарий, передавая имя файла программе интерпретатора сценария, вы запускаете программу интерпретатора со сценарием в качестве аргумента, переданного ей. Например, это будет выглядеть как процесс «sh» с аргументом «filename.sh». Интерпретатор sh
открывает файл.
С другой стороны, если вы запускаете сам сценарий, система обращается к указанной программе интерпретатора и передает содержимое сценария. В этом случае процесс выглядит как 'filename.sh' без аргументов.
Вы должны убедиться, что у вас есть строка с ответом:
#!/bin/bash
# bash script here
Строка с ответом - это самая первая строка в скрипте и начинается с тех же двух символов #!
, это то, что система читает, когда пытается выполнить сценарий, а затем система сразу после этого передает сценарий программе. Обратите внимание, что эта строка не имеет ничего общего с bash и работает так же хорошо для python и perl, хотя это очень разные языки. Например, вы можете использовать #! / Usr / bin / python
, а затем ввести код Python.
После того, как у вас есть сценарий, убедитесь, что вы установили права на выполнение:
chmod a+x filename.sh
Затем вы можете запустите сценарий как отдельный процесс:
./filename.sh
Или поместите файл в известное место с красивым именем программы, например / usr / sbin
, и запустите откуда угодно:
sudo cp filename.sh /usr/sbin/program-name
program-name
И это действительно практическое преимущество использования строки bang с правильными разрешениями - все дело в развертывании . Очень трудно заставить пользователей запускать сценарий, если им нужно помнить, с какой программой запускать сценарий. Не забывайте указывать полный путь к сценарию каждый раз, когда они хотят его запустить. Если, например, поместить его в / usr / local / bin
и сделать его исполняемым, то люди, пытающиеся использовать ваш скрипт, могут сэкономить очень много горя. Затем эти программы становятся доступными для всех пользователей вашего компьютера.
Это также полезно для идентификации. Если вы войдете в программу top
, сценарий, запущенный без строки bang, будет иметь просто имя интерпретатора, то есть bash
, perl
или python
. Но если сценарий запущен с правильными разрешениями, то отображается имя сценария.
Примечание: Если вы хотите распространить сценарий, доступный для всех, создайте страницу руководства и пакет deb для установить его. Нам нужно уменьшить количество случайных скриптов в сети и увеличить количество файлов, которые можно удалить.
Разница в том, что
с sh
, вы запускаете программу, которая интерпретирует строки в вашем скрипте так же, как если бы вы их набрали в интерактивной подсказке терминала
с ./
вы делаете ярлык, предполагая, что сценарий находится прямо здесь, в текущем каталоге, в котором вы находитесь, И он будет исполняемым (потому что например, вы выполнили chmod + x myscript.sh
), сэкономив бесценное время на будущее: -)
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Не / usr / sbin
, это для несущественных административных инструментов, / usr / local / bin
- лучший выбор, если вы не хотите иметь ~ / bin /
, но избегая sudo
столько же, сколько
возможно желательно.
Вы можете получить сообщение об ошибке по трем основным причинам:
chmod + x
, чтобы исправить, что noexec
») / usr / local / bin
#!
есть ошибка #! / bin / sh
или #! / bin / bash
Если ваша первая строка выглядит правильно, но по-прежнему не работает, убедитесь, что файл не нет окончаний строк DOS.
Ошибка будет выглядеть примерно так:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
Вы можете исправить ее, запустив dos2unix
, или, если у вас его нет,
perl -p -i -e 's / \ r \ n $ / \ n /'
.
Краткая версия:
sh
- это интерпретатор командной строки (тире).
Выполнение sh my_script
заставляет тире интерпретировать сценарий.
./
пытается выяснить, какой интерпретатор использовать, просматривая первую строку. Например. #! / Bin / bash
или даже #! / Bin / ruby
(в отличие от выполнения ruby my_script
).
Ответ в том, что sh - это название очень популярной оболочки. Но устарел и заменен другими. В настоящее время sh связан с другими оболочками, установленными на машине. например Я там баш поставил. Запуск любой оболочки из sh обычно вызывает некий режим «совместимости» с исходным поведением «оболочки».
Так что решение довольно простое. Посмотрите, что стоит за командой sh (ls -al / bin / sh), и поместите #! / Bin / any_you_find_there в качестве первой строки (или, если в вашем скрипте есть что-то подобное, отредактируйте это).
Или, как вариант, могут быть некоторые ошибка в самом скрипте. Подобно зависимости, встречающейся в sh, но не интерпретатору, который фактически используется.