Відповіді:
Для вашого конкретного сценарію будь-який спосіб буде працювати, за винятком того, що ./script.shвимагає виконання та читання бітів, тоді bash script.shяк потрібен лише біт для читання.
Причина різниці вимог дозволів полягає в тому, як завантажується програма, що інтерпретує ваш сценарій:
./script.sh змушує вашу оболонку запустити файл так, ніби це був звичайний виконуваний файл.Оболонка розкручується і використовує системний виклик (наприклад execve), щоб змусити операційну систему виконувати файл у роздвоєному процесі. Операційна система перевірить права доступу до файлу (отже, слід встановити біт виконання) та передасть запит на завантажувач програми , який розглядає файл та визначає спосіб його виконання. У Linux компільовані виконувані файли починаються з магічного числа ELF , а сценарії починаються з #!( хешбанг ). Заголовок хешбангу означає, що файл є скриптом і його слід інтерпретувати програмою, яка вказана після хешбангу. Це дозволяє самому сценарію розповісти системі, як інтерпретувати сценарій.
З вашим сценарієм завантажувач програми виконає /bin/bashі передасть ./script.sh як аргумент командного рядка.
bash script.shзмушує вашу оболонку запускатися bashта передаватися script.shяк аргумент командного рядкаТак операційна система завантажиться bash(навіть не дивлячись script.sh, тому що це лише аргумент командного рядка). Потім створений bashпроцес інтерпретуватиме те, script.shщо він передається як аргумент командного рядка. Оскільки script.shвін читається лише bashяк звичайний файл, біт виконання не потрібно.
Я рекомендую використовувати, ./script.shхоча ви можете не знати, який інтерпретатор вимагає сценарію. Тож дозвольте завантажувачу програми визначити це для вас.
. ./script.sh- це не те саме, що bash script.sh(або ./script.sh. Розглянемо сценарій #!/usr/bin/python -V<newline> print test.
. script.sh. Але я погоджуюся з людьми, які .не дозволяють використовувати команду для скриптів, які не мали на меті викликати таким чином. Я здивований, що ніхто не згадував, що якщо скрипт містить exitкоманди, і ви його джерелом, він може вийти з системи. Менш гострою проблемою буде, якщо сценарій робить a cd, оскільки це також вплине на батьківську (інтерактивну) оболонку.
bash script.shвикликає сценарій безпосередньо за допомогою bash.
./script.shвикористовує шебанг #!/bin/bashдля визначення способу виконання.
Якщо ви дійсно хочете знати, який двійковий файл виконується, якщо ви це робите, bash script.shви могли б дізнатися which bash.
Тож у вашому прикладі це не має значення. Так, ви повинні chmod +x script.shмати можливість виконувати це безпосередньо через ./script.sh.
/bin/bashце перше bashу вашому $PATH.
#!/bin/bashпрацює лише за наявності/bin/bash
./script.sh.
Створіть файл Delete_Self.sh так:
#!/bin/rm
echo I am still here!
Запустіть цей сценарій, як sh Delete_Self.shви побачите "Я все ще тут!" відлунав назад.
Зробіть його виконуваним і запустіть так, як ./Delete_Self.shви побачите, що нічого не повторюється назад, поки сам файл Delete_Self.shне зник.
Отже, різниця полягає в тому, що:
bash script.shігнорує #! рядок, тому що bash вказаний як програма для запуску script.sh../script.shпрочитає #! рядок для визначення програми для запуску script.sh.На додаток до інших відповідей, корисне знання різниці між запуском сценарію через ./script.sh(i) та джерелом ./script.sh(ii) - версія (i) створює нову оболонку, в якій можна запустити команду, тоді як (ii) запускає її в поточна оболонка - що може бути обов'язковим, якщо виконуваний файл змінює змінні середовища, які потрібно зберегти після завершення виконання файлу. Наприклад, для активації середовища python conda необхідно використовувати наступне:
source activate my_env
NB Ще одна альтернатива тому, sourceщо ви можете зіткнутися, - це .вбудований, тобто
. activate my_env