Я написав простий сценарій. Коли я бігав sh <myscriptname.sh>
, я отримав правильний вихід, але коли я запускався ./<myscriptname.sh>
, я отримав помилку.
Яка різниця між тим, коли я sh
і ./
?
Я написав простий сценарій. Коли я бігав sh <myscriptname.sh>
, я отримав правильний вихід, але коли я запускався ./<myscriptname.sh>
, я отримав помилку.
Яка різниця між тим, коли я sh
і ./
?
Відповіді:
Коли ви запускаєте будь-який скрипт, передаючи ім'я файлу програмі інтерпретатора скриптів, ви запускаєте програму інтерпретатора зі сценарієм як аргумент, переданий в нього. Наприклад, це виглядатиме як процес 'sh' з аргументом 'filename.sh'. sh
Інтерпретатор відкриває файл.
З іншого боку, якщо ви запускаєте сам скрипт, система викликає вказану програму інтерпретатора та подає вміст скриптів. У цьому випадку процес виглядає як "filename.sh" без аргументів.
Ви повинні переконатися, що у вас є лінія вибуху:
#!/bin/bash
# bash script here
Рядок вибуху - це найперший рядок у скрипті і починається з тих самих двох символів #!
, це те, що система читає, коли намагається виконати сценарій, а потім система передає сценарій програмі відразу після. Зауважте, що цей рядок не має нічого спільного з bash і працює так само добре, як для python та perl, хоча вони дуже різні мови. Ви б використали, #!/usr/bin/python
наприклад, а потім дотримуйтесь його за допомогою пітонного коду.
Коли у вас є сценарій, переконайтеся, що ви встановили дозволи на виконання:
chmod a+x filename.sh
Тоді ви можете запустити сценарій як власний процес:
./filename.sh
Або помістіть файл у відоме місце з приємною назвою програми, як-от /usr/sbin
і запустіть з будь-якого місця:
sudo cp filename.sh /usr/sbin/program-name
program-name
І це справді практична вигода від використання лінії чубчика з правильними дозволами - все стосується розгортання . Користувачам запускати сценарій дуже важко, якщо їм потрібно запам'ятати, з якою програмою запускати скрипт. Не забудьте дати повний шлях до сценарію кожного разу, коли вони хочуть його запустити. Якщо, наприклад, розмістити його /usr/local/bin
і зробити його виконуваним, ви можете зберегти дуже багато горя для людей, які намагаються використовувати ваш сценарій. Потім ці програми стають доступними для всіх користувачів вашого комп’ютера.
Це також добре для ідентифікації. Якщо ви перейдете в top
програму, сценарій, запущений без рядка, просто матиме ім'я інтерпретатора, тобто bash
, perl
або python
. Але якщо сценарій запускається з правильними дозволами, тоді відображається назва сценарію.
Примітка. Якщо ви хочете поширити скрипт, доступний для всіх, то створіть довідкову сторінку та пакет дебюту, щоб встановити її. Нам потрібно зменшити кількість випадкових сценаріїв в Інтернеті та збільшити кількість деб, які можна видалити.
bash
, ні sh
.
PATH
.
/usr/local/bin
це, мабуть, краще /usr/sbin
- це вказує, що програма локальна для цієї машини, а не є частиною дистрибуції.
Коротка версія:
sh
- інтерпретатор командного рядка (тире).
Запуск sh my_script
змушує тире інтерпретувати сценарій.
./
намагається з’ясувати, який перекладач використовувати, переглянувши перший рядок. Наприклад #!/bin/bash
, або навіть #!/bin/ruby
(на відміну від запуску ruby my_script
).
./
нічого не знаходить, це метод виконання системи, який розглядає перші два байти файлу.
sh
а файл містить ша-баг, чи означає це, що ша-баг буде ігнорований чи він відкриє оболонку, де також sh
посилання, а потім, можливо, якусь іншу оболонку чи що вона робить :)?
Різниця, яку ви робите,
з sh
, ви запускаєте програму, яка інтерпретуватиме рядки у вашому сценарії так само, як ви б їх ввели в інтерактивний запит терміналу,
з ./
ви робите ярлик за умови , що сценарій якраз тут , в поточному каталозі ви сидите , і це буде виконуваним файлом (наприклад , тому що ви виданий chmod +x myscript.sh
), заощаджуючи дорогоцінний час для майбутніх часів :-)
sh
файл не обов'язково повинен бути виконаним.
Є три основні причини, через які ви можете отримати помилку:
chmod +x <myscriptname.sh>
щоб виправити це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 <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, але не перекладач, який фактично використовується.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Ні /usr/sbin
, це для несуттєвих адміністративних інструментів, /usr/local/bin
це кращий вибір, якщо ви не хочете мати ~/bin/
, але sudo
бажано уникати якнайбільше уникання .
~/.profile
вже є код для додавання ~/bin
, якщо він існує, до PATH
. З іншого боку, не ставте розширення на сценарії.
ls ~/bin/|wc -l = 428
) Я поклав туди багато речі;)
/bin
і /usr/bin
побачите, що вони не використовують розширення.