Чому мені потрібно поставити sh перед запуском .sh файлів?


16

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

Чи є спосіб уникнути цього і тим самим зберегти введення тексту?


3
Я створив папку в ~ / bin, щоб помістити свої сценарії оболонки і помістити її в свій $ PATH, а також додав Дію папки до папки ~ / bin, щоб автоматично встановити дозволи на виконання, оскільки це так просто забути зробити.
Kaydell

Відповіді:


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, що розширюється, до нового каталогу біна, до свого PATH, додаючи .profileу свій домашній каталог наступні рядки :

PATH=$HOME/bin:$PATH
export PATH

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

$ script.sh

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

PATH=.:$PATH
export PATH

Покласти '.' наприкінці $ PATH замість початку, і тепер вам не потрібно турбуватися про фантомні 'ls'. (Хоча якщо хтось може потрапити у вашу систему, у вас є більші проблеми.)
TJ Luoma

2
@TJ, але вам дійсно потрібен турбуватися про речі , як slабо llsабо l... тобто, друкарські помилки. Просто залиште .поза $PATH. Крім того, ви не можете (або не повинні) обов'язково довіряти всім у своїй системі. Наприклад, припустимо , що є якась - то експлойт , який дозволяє зловмисникові кинути довільний файл в який - небудь каталог, але вони потребують в вас , щоб виконати цей файл, щоб перерости краще використовувати (наприклад, збір даних і домашній телефон). Оборона в глибину!
Рейд

@TJLuoma Що сказав @Reid, а також пам’ятайте, що існує багато випадків використання для системи Unix за межами особистого робочого столу OS X. Я не пробував цього, але я думаю, що навіть гостьовий акаунт міг залишити один із цих предметів у /tmpбудь-якій іншій світовій директорії.
зигг

Якщо ви використовуєте систему, де інші люди мають доступ до каталогів, якими ви користуєтесь, у вас виникають більші проблеми.
TJ Luoma

@TJLuoma Тоді вам краще ніколи не використовувати кілька облікових записів у будь-якій системі Unix. /tmpта ін. приїжджайте з територією.
zigg

10

Вам не потрібно телефонувати, shякщо файл сценарію позначений як виконуваний. У такому випадку ви можете назвати це моє ім’я так само, як і будь-яка інша команда з існуючої оболонки.


Щоб бути повністю належним, вам потрібно зробити дві речі:

  1. Відредагуйте свій сценарій, щоб він містив директиву shebang у верхній частині сценарію:

    #!/bin/sh

    ... Це скаже оболонці, який інтерпретатор використовувати для запуску сценарію; у цьому випадку /bin/shвиконуваний файл.

  2. Позначте сценарій як виконуваний вами командою chmod :

    chmod u+x scriptname.sh

Після того як ви зробите обидва з них, ви зможете запустити свій скрипт, ввівши ім'я файлу сценарію в командному рядку. Вам потрібно буде знаходитися в тому ж каталозі, що і ваш сценарій, якщо ви також не зробите доданий крок додавання папки, що містить, до змінної PATH . Якщо вам не байдуже, яка оболонка запускає скрипт, вам не потрібен перший крок для вказівки, shале часто краще бути точним і встановити "шебангш".


Шебанги насправді не потрібні /bin/sh, хоча вони не шкодять.
zigg

@zigg - Ви маєте рацію. Я сподіваюся, що Кріс не проти моїх змін… Nuke або переробляти за бажанням: -0
bmike

@bmike Правки працюють для мене. Що стосується шебангів, то моя звичка полягала в тому, щоб завжди вказувати, оскільки я писав багато kshсценаріїв ще в свої дні на HP-UX - але добре знати, що це не обов'язково.
Кріс В. Реа

1
Я думаю, що мені потрібно відмовитися від попереднього твердження про необхідність shebang (хоча решта моєї відповіді все ще стоїть.) Ви можете запустити сценарій без execшебанга з оболонки, але якщо ви використовуєте syscall, ви отримуєте ENOEXEC(помилка формату exec ). Вибачте з цього приводу, @bmike, @ ChrisW.Rea. Я зараз піду редагувати свою відповідь.
zigg
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.