Я создал папку в ~ / 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 вместо начала, и теперь вам не нужно беспокоиться о фантоме 'ls'. (Хотя, если кто-то может войти в вашу систему, у вас будут большие проблемы.)
TJ Luoma
2
@TJ, но вам действительно нужен беспокоиться о вещах , как slили llsили l... то есть, опечатки. Просто уйти .из $PATH. Кроме того, вы не можете (или не должны) доверять всем в вашей системе. Например, предположим, что есть какой-то эксплойт, который позволяет злоумышленнику поместить произвольный файл в какой-то каталог, но ему нужно , чтобы вы выполнили этот файл, чтобы перейти к лучшему (например, собрать данные и позвонить домой). Глубокая защита!
Рейд
@TJLuoma Что сказал @Reid, и имейте в виду, что существует множество вариантов использования системы Unix, помимо персонального рабочего стола OS X. Не пробовал, но держу пари, что даже гостевая учетная запись может оставить один из этих элементов в /tmpкаком-либо другом общедоступном каталоге.
зигг
Если вы используете систему, где другие люди имеют доступ к каталогам, которые вы используете, у вас есть большие проблемы.
TJ Luoma
@TJLuoma Тогда вам лучше никогда не использовать несколько учетных записей в любой системе Unix. /tmpи другие. прийти с территории.
Зигг
10
Вам не нужно звонить, shесли файл сценария помечен как исполняемый. В этом случае вы можете назвать его моим именем так же, как и любой другой командой из существующей оболочки.
Чтобы быть полностью подходящим, вы захотите сделать две вещи:
Отредактируйте ваш скрипт, добавив в его верхнюю часть директиву shebang :
#!/bin/sh
... Это говорит оболочке, какой интерпретатор использовать для запуска скрипта; в этом случае /bin/shисполняемый файл.
Пометьте скрипт как исполняемый вами с помощью команды 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. Я собираюсь изменить свой ответ сейчас.
Ответы:
Если вы запускаете свой сценарий из оболочки, вам на самом деле не нужен
#!/bin/sh
шебанг, как указано в этом ответе - каждая Unix-подобная система, которую я использовал, включая OS X, будет по умолчанию работать,/bin/sh
если не указан конкретный интерпретатор ( хотя это хорошая идея, поскольку не-оболочки не будут знать, как выполнить ваш сценарий, если вы не дадите шебанг.)Вам также не нужно
.sh
расширение. Вы делаете необходимость создания исполняемых разрешений, например ,(Это
$
приглашение оболочки; я использую его для иллюстрации команд, которые вы даете интерактивной оболочке. Не вводите его!)Однако я думаю, что ваша путаница заключается в том, что вы создали сценарий, например
script.sh
, в текущем каталоге, и пытаетесь выполнить его, просто набравscript.sh
. например(
^D
означает control- D. Вы найдете эту запись во многих рецензиях на использование Unix.)Тот факт, что
script.sh
в данном случае это сценарий оболочки - это только половина проблемы; Ваша настоящая проблема заключается в том, что по умолчанию оболочка не будет искать программу в текущем каталоге. Тем не менее, это работает:потому что
sh
принимает сценарий в качестве аргумента.Вы можете выполнить скрипт - или, опять же, любой исполняемый файл - в текущем каталоге, если он помечен как исполняемый (то есть
chmod +x
), указав, что вы хотите запустить тот в текущем каталоге:Вы также можете переместить скрипт в каталог на вашем
PATH
. Я рекомендую/usr/local/bin
для этого, если ваш сценарий предназначен для использования в масштабе всей системы, илиbin
каталог в вашем доме, если сценарий предназначен только для вас. Последнее требует, чтобы вы добавили$HOME/bin
, который расширяет ваш новый каталог bin, в ваш каталог,PATH
добавив следующие строки.profile
в ваш домашний каталог:Наконец, вы можете, если хотите, фактически добавить текущий каталог в свой
PATH
, что позволит вам просто перейти в каталог, содержащийscript.sh
- или любой другой исполняемый файл - и набратьвыполнить это. Однако я не рекомендую эту практику , поскольку злоумышленник теперь может заставить вас запустить произвольный исполняемый файл, поместив исполняемый скрипт (названный, скажем,
ls
) в каталог, в котором вы будете находиться. Однако, если вы действительно хотите это сделать, просто добавьте следующее к вашему.profile
:источник
sl
илиlls
илиl
... то есть, опечатки. Просто уйти.
из$PATH
. Кроме того, вы не можете (или не должны) доверять всем в вашей системе. Например, предположим, что есть какой-то эксплойт, который позволяет злоумышленнику поместить произвольный файл в какой-то каталог, но ему нужно , чтобы вы выполнили этот файл, чтобы перейти к лучшему (например, собрать данные и позвонить домой). Глубокая защита!/tmp
каком-либо другом общедоступном каталоге./tmp
и другие. прийти с территории.Вам не нужно звонить,
sh
если файл сценария помечен как исполняемый. В этом случае вы можете назвать его моим именем так же, как и любой другой командой из существующей оболочки.Чтобы быть полностью подходящим, вы захотите сделать две вещи:
Отредактируйте ваш скрипт, добавив в его верхнюю часть директиву shebang :
#!/bin/sh
... Это говорит оболочке, какой интерпретатор использовать для запуска скрипта; в этом случае
/bin/sh
исполняемый файл.Пометьте скрипт как исполняемый вами с помощью команды chmod :
chmod u+x scriptname.sh
Как только вы сделаете оба этих шага, вы сможете запустить свой скрипт, введя имя файла вашего скрипта в командной строке. Вам нужно будет находиться в том же каталоге, что и ваш скрипт, если только вы не предпримете дополнительный шаг, добавив содержащую папку в переменную PATH . Если вам не важно, какая оболочка запускает скрипт, вам не нужно указывать первый шаг,
sh
но часто лучше быть точным и установить «shebangsh».источник
/bin/sh
, хотя они не причиняют вреда.ksh
в свое время я писал множество сценариев для HP-UX, но приятно знать, что в этом нет особой необходимости.exec
syscall, вы получитеENOEXEC
(ошибка формата exec ). К сожалению об этом, @bmike, @ ChrisW.Rea. Я собираюсь изменить свой ответ сейчас.