Зачем мне ставить sh перед запуском .sh файлов?

16

Когда я хочу запустить .shфайлы в Терминале, мне нужно поставить их shперед собой.

Есть ли способ избежать этого и, таким образом, сохранить печать?

Больше пяти
источник
3
Я создал папку в ~ / bin, чтобы поместить в нее сценарии оболочки и поместил ее в свой $ PATH, а также прикрепил действие папки к папке ~ / bin для автоматической установки разрешений на выполнение, потому что это так легко забыть сделать.
Кейделл

Ответы:

22

Если вы запускаете свой сценарий из оболочки, вам на самом деле не нужен #!/bin/shшебанг, как указано в этом ответе - каждая Unix-подобная система, которую я использовал, включая OS X, будет по умолчанию работать, /bin/shесли не указан конкретный интерпретатор ( хотя это хорошая идея, поскольку не-оболочки не будут знать, как выполнить ваш сценарий, если вы не дадите шебанг.)

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

$ chmod +x script.sh

(Это $приглашение оболочки; я использую его для иллюстрации команд, которые вы даете интерактивной оболочке. Не вводите его!)

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

$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found

( ^Dозначает control- D. Вы найдете эту запись во многих рецензиях на использование Unix.)

Тот факт, что script.shв данном случае это сценарий оболочки - это только половина проблемы; Ваша настоящая проблема заключается в том, что по умолчанию оболочка не будет искать программу в текущем каталоге. Тем не менее, это работает:

$ sh script.sh
hello, world

потому что shпринимает сценарий в качестве аргумента.

Вы можете выполнить скрипт - или, опять же, любой исполняемый файл - в текущем каталоге, если он помечен как исполняемый (то есть chmod +x), указав, что вы хотите запустить тот в текущем каталоге:

$ ./script.sh
hello, world

Вы также можете переместить скрипт в каталог на вашем PATH. Я рекомендую /usr/local/binдля этого, если ваш сценарий предназначен для использования в масштабе всей системы, или binкаталог в вашем доме, если сценарий предназначен только для вас. Последнее требует, чтобы вы добавили $HOME/bin, который расширяет ваш новый каталог bin, в ваш каталог, PATHдобавив следующие строки .profileв ваш домашний каталог:

PATH=$HOME/bin:$PATH
export PATH

Наконец, вы можете, если хотите, фактически добавить текущий каталог в свой PATH, что позволит вам просто перейти в каталог, содержащий script.sh- или любой другой исполняемый файл - и набрать

$ script.sh

выполнить это. Однако я не рекомендую эту практику , поскольку злоумышленник теперь может заставить вас запустить произвольный исполняемый файл, поместив исполняемый скрипт (названный, скажем, ls) в каталог, в котором вы будете находиться. Однако, если вы действительно хотите это сделать, просто добавьте следующее к вашему .profile:

PATH=.:$PATH
export PATH
zigg
источник
Поставь '.' в конце $ PATH вместо начала, и теперь вам не нужно беспокоиться о фантоме 'ls'. (Хотя, если кто-то может войти в вашу систему, у вас будут большие проблемы.)
TJ Luoma
2
@TJ, но вам действительно нужен беспокоиться о вещах , как slили llsили l... то есть, опечатки. Просто уйти .из $PATH. Кроме того, вы не можете (или не должны) доверять всем в вашей системе. Например, предположим, что есть какой-то эксплойт, который позволяет злоумышленнику поместить произвольный файл в какой-то каталог, но ему нужно , чтобы вы выполнили этот файл, чтобы перейти к лучшему (например, собрать данные и позвонить домой). Глубокая защита!
Рейд
@TJLuoma Что сказал @Reid, и имейте в виду, что существует множество вариантов использования системы Unix, помимо персонального рабочего стола OS X. Не пробовал, но держу пари, что даже гостевая учетная запись может оставить один из этих элементов в /tmpкаком-либо другом общедоступном каталоге.
зигг
Если вы используете систему, где другие люди имеют доступ к каталогам, которые вы используете, у вас есть большие проблемы.
TJ Luoma
@TJLuoma Тогда вам лучше никогда не использовать несколько учетных записей в любой системе Unix. /tmpи другие. прийти с территории.
Зигг
10

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


Чтобы быть полностью подходящим, вы захотите сделать две вещи:

  1. Отредактируйте ваш скрипт, добавив в его верхнюю часть директиву shebang :

    #!/bin/sh

    ... Это говорит оболочке, какой интерпретатор использовать для запуска скрипта; в этом случае /bin/shисполняемый файл.

  2. Пометьте скрипт как исполняемый вами с помощью команды chmod :

    chmod u+x scriptname.sh

Как только вы сделаете оба этих шага, вы сможете запустить свой скрипт, введя имя файла вашего скрипта в командной строке. Вам нужно будет находиться в том же каталоге, что и ваш скрипт, если только вы не предпримете дополнительный шаг, добавив содержащую папку в переменную PATH . Если вам не важно, какая оболочка запускает скрипт, вам не нужно указывать первый шаг, shно часто лучше быть точным и установить «shebangsh».

Крис В. Ри
источник
Шебанги на самом деле не нужны /bin/sh, хотя они не причиняют вреда.
зигг
@zigg - Вы правы. Я надеюсь, что Крис не возражает против моих правок ... Nuke или отредактируйте по желанию: -0
bmike
@bmike Редактирование работает для меня. Что касается shebangs, моя привычка заключалась в том, чтобы всегда указывать, потому что kshв свое время я писал множество сценариев для HP-UX, но приятно знать, что в этом нет особой необходимости.
Крис В. Ри
1
Я думаю, что мне нужно отступить от моего предыдущего заявления о необходимости shebang (хотя остальная часть моего ответа остается в силе.) Вы можете запустить сценарий без shebang из оболочки, но если вы используете execsyscall, вы получите ENOEXEC(ошибка формата exec ). К сожалению об этом, @bmike, @ ChrisW.Rea. Я собираюсь изменить свой ответ сейчас.
зигг