Я написал простой сценарий. Когда я бегу sh <myscriptname.sh>
, я получаю правильный вывод, но когда я бегу ./<myscriptname.sh>
, я получаю ошибку.
Какая разница между тем, когда я делаю sh
и ./
?
command-line
scripts
executable
mr_eclair
источник
источник
Ответы:
Когда вы запускаете любой сценарий, передавая имя файла программе-интерпретатору сценария, вы запускаете программу-интерпретатор со сценарием в качестве аргумента, переданного ему. Например, это будет выглядеть как процесс 'sh' с аргументом 'filename.sh'.
sh
Интерпретатор открывает файл.С другой стороны, если вы запускаете сам скрипт, система вызывает указанную программу интерпретатора и передает содержимое скриптов. В этом случае процесс выглядит как «filename.sh» без аргументов.
Вы должны убедиться, что у вас есть линия взрыва:
Строка взрыва - это самая первая строка в скрипте, которая начинается с тех же двух символов
#!
, это то, что система читает, когда она пытается выполнить скрипт, а затем система сразу передает скрипт в программу. Обратите внимание, что эта строка не имеет ничего общего с bash и работает так же хорошо для python и perl, хотя они очень разные языки. Вы могли бы использовать,#!/usr/bin/python
например, а затем следовать за ним с кодом Python.Как только у вас есть ваш скрипт, убедитесь, что вы установили права на выполнение:
Затем вы можете запустить скрипт как собственный процесс:
Или поместите файл в известное место с хорошим именем программы, как
/usr/sbin
и запустить из любого места:И это действительно практическое преимущество использования линии взрыва с правильными разрешениями - все дело в развертывании . Пользователям очень сложно запустить скрипт, если они должны помнить, с какой программой запускать скрипт. Не забывайте указывать полный путь к скрипту каждый раз, когда они захотят его запустить. Где , как положить его в
/usr/local/bin
, например, и сделать его исполняемым, можно сэкономить очень много горя для людей , которые пытаются использовать ваш сценарий. Эти программы затем становятся доступными для всех пользователей на вашем компьютере.Это также хорошо для идентификации. Если вы войдете в
top
программу, сценарий, запускаемый без строки взрыва, будет иметь только имя интерпретатора, т. Е.bash
,perl
Илиpython
. Но если скрипт запускается с нужными разрешениями, то отображается имя скрипта.Примечание. Если вы хотите распространять сценарий, доступный для всех, создайте страницу руководства и пакет deb для его установки. Нам нужно уменьшить количество случайных скриптов в сети и увеличить количество дэбов, которые можно удалить.
источник
bash
нетsh
.PATH
./usr/local/bin
Вероятно, лучше/usr/sbin
- это означает, что программа является локальной для этой машины, а не частью дистрибутива.Краткая версия:
sh
интерпретатор командной строки (тире)Запуск
sh my_script
заставляет dash интерпретировать скрипт../
пытается выяснить, какой интерпретатор использовать, посмотрев на первую строку. Например#!/bin/bash
, или даже#!/bin/ruby
(в отличие от бегаruby my_script
).источник
./
что находит, это метод выполнения системы, который просматривает первые два байта файла.sh
и файл содержит sha-bang, означает ли это, что sha-bang будет проигнорирован или откроет оболочку, в которой также естьsh
ссылки, а затем, возможно, какую-нибудь другую оболочку или что она делает :)?Разница в том, что
с
sh
, вы запускаете программу, которая будет интерпретировать строки в вашем скрипте так же, как вы бы набрали их в интерактивной подсказке терминала,когда
./
вы делаете ярлык, предполагая, что скрипт находится прямо здесь, в текущем каталоге, в котором вы сидите, и он будет исполняемым (потому что, например, вы его выпустилиchmod +x myscript.sh
), сохраняя ваше бесценное время на будущее :-)источник
sh
файлом не обязательно должен быть исполняемый файл.Есть три основные причины, по которым вы можете получить ошибку:
бежать ,
chmod +x <myscriptname.sh>
чтобы исправитьnoexec
")копировать скрипт в
/usr/local/bin
#!
линия ошибкиубедитесь , что первая строка
#!/bin/sh
или#!/bin/bash
Если ваша первая строка выглядит правильно, но все еще не работает, убедитесь, что в файле нет окончаний строки DOS.
Ошибка будет выглядеть примерно так:
Вы можете это исправить, выполнив
dos2unix <myscriptname.sh>
, или если у вас нет этогоperl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
.источник
И ответ таков: sh - это имя очень популярной оболочки. Но устаревшие и заменены другими. В настоящее время sh связан с другими оболочками, установленными на машине. например, я поместил Баш там. Запуск любой оболочки из sh обычно вызывает некоторый режим «совместимости» с оригинальным поведением «оболочки».
Так что решение довольно простое. Посмотрите, что стоит за командой sh (ls -al / bin / sh), и поместите #! / Bin / what_you_find_there в качестве первой строки (или, если в вашем скрипте есть что-то подобное, отредактируйте ее).
И наоборот, в самом скрипте может быть какая-то ошибка. Как и зависимость, которую встречает sh, но не интерпретатор, который фактически используется.
источник
Не
/usr/sbin
, это для ненужных административных инструментов,/usr/local/bin
это лучший выбор, если вы не хотите иметь~/bin/
, ноsudo
желательно избегать как можно больше.источник
~/.profile
уже есть код для добавления~/bin
, если он существует, вPATH
. С другой стороны, не помещайте расширения в сценарии.ls ~/bin/|wc -l = 428
) Я положил много вещей там;)/bin
и/usr/bin
вы увидите, что они не используют расширения.