В чем разница между ./ и sh для запуска скрипта?

Я написал простой сценарий. Когда я запускаю sh <myscriptname.sh>, я получаю правильный вывод, но когда я запускаю ./<myscriptname.sh>, я получаю ошибку.

В чем разница между тем, когда я делаю sh и ./?

79
задан 7 April 2011 в 23:31

6 ответов

Когда вы запускаете любой сценарий, передавая имя файла программе интерпретатора сценария, вы запускаете программу интерпретатора со сценарием в качестве аргумента, переданного ей. Например, это будет выглядеть как процесс «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 для установить его. Нам нужно уменьшить количество случайных скриптов в сети и увеличить количество файлов, которые можно удалить.

69
ответ дан 7 April 2011 в 23:31

Разница в том, что

  • с sh , вы запускаете программу, которая интерпретирует строки в вашем скрипте так же, как если бы вы их набрали в интерактивной подсказке терминала

  • с ./ вы делаете ярлык, предполагая, что сценарий находится прямо здесь, в текущем каталоге, в котором вы находитесь, И он будет исполняемым (потому что например, вы выполнили chmod + x myscript.sh ), сэкономив бесценное время на будущее: -)

7
ответ дан 7 April 2011 в 23:31
mkdir ~/bin ; cp myscript.sh ~/bin/

echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ; 

Не / usr / sbin , это для несущественных административных инструментов, / usr / local / bin - лучший выбор, если вы не хотите иметь ~ / bin / , но избегая sudo столько же, сколько возможно желательно.

0
ответ дан 7 April 2011 в 23:31

Вы можете получить сообщение об ошибке по трем основным причинам:

  • файл не является исполняемым
    запустите 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 /' .

3
ответ дан 7 April 2011 в 23:31

Краткая версия:

  • sh - это интерпретатор командной строки (тире).
    Выполнение sh my_script заставляет тире интерпретировать сценарий.

  • ./ пытается выяснить, какой интерпретатор использовать, просматривая первую строку. Например. #! / Bin / bash или даже #! / Bin / ruby ​​ (в отличие от выполнения ruby ​​my_script ).

45
ответ дан 7 April 2011 в 23:31

Ответ в том, что sh - это название очень популярной оболочки. Но устарел и заменен другими. В настоящее время sh связан с другими оболочками, установленными на машине. например Я там баш поставил. Запуск любой оболочки из sh обычно вызывает некий режим «совместимости» с исходным поведением «оболочки».

Так что решение довольно простое. Посмотрите, что стоит за командой sh (ls -al / bin / sh), и поместите #! / Bin / any_you_find_there в качестве первой строки (или, если в вашем скрипте есть что-то подобное, отредактируйте это).

Или, как вариант, могут быть некоторые ошибка в самом скрипте. Подобно зависимости, встречающейся в sh, но не интерпретатору, который фактически используется.

0
ответ дан 7 April 2011 в 23:31

Другие вопросы по тегам:

Похожие вопросы: