Відповіді:
Якщо ви використовуєте
sh ./<script>.run
/bin/sh
(зазвичай оболонка Bourne) буде використовуватися для запуску сценарію. Звичайно, це працює лише в тому випадку, якщо сценарій написаний для оболонки Bourne. Іноді для скриптів оболонки для Linux потрібен Bash замість оболонки Bourne, тому це може не працювати, навіть якщо це сценарій оболонки.
Якщо ви використовуєте
./<script>.run
ядро розглядає рядок shebang, щоб дізнатися, яку програму використовувати для запуску програми. Отже, це працює, навіть якщо це сценарій Bash, Perl, Python або якийсь інший сценарій.
Таким чином, це, як правило, кращий спосіб запуску сценарію.
Поки це sh
сценарій оболонки (тире або еквівалентний), немає, зовнішньої різниці немає.
Проблема .run
не гарантує, що це так. Це може бути двійковим. Це може бути Bash або Python або PHP чи будь-що інше; всі вони мають сценарій оболонки хеш-баг. Якщо ви сліпо змусите це sh
, хто знає, що може статися. Це, ймовірно, помилка, але він може випадково запустити шкідливий код, перш ніж дістатися так далеко.
Увімкнувши chmod
його (щоб увімкнути біт дозволу на виконання), а потім запустивши його ./script.run
, ви надаєте йому найкращу можливу можливість запуску. Якщо це сценарій оболонки, його хеш-баг буде проаналізований належним чином, і якщо це двійковий виконуваний файл, він просто запускатиметься на початковому рівні.
Два способи часто можуть діяти однаково, але сильно відрізняються.
sh ./script
запускає sh
команду з аргументом ./script
, який трапляється виконувати даний скрипт .. навіть якщо сценарій насправді не є sh
сценарієм (погано)
./script
виконує заданий файл. Це робиться, шукаючи рядок "shebang", щоб визначити, яку команду запустити. Якщо не визначено, він використовує sh
(це обидва способи діють іноді однаково), але часто вказується інший перекладач.
Наприклад, якщо він filename
містить наступне:
#!/usr/bin/python
print "This is a Python script!"
.. тоді дві команди сильно відрізняються:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Якщо немає лінії шебанга, два є однаковими:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Важлива відмінність полягає в тому, якщо у вашої лінії хешбангу є параметри. Наприклад, якщо сценарій починається з
#!/bin/bash -e
... і ви запускаєте його зовнішньо, використовуючи sh
або bash
, цей рядок буде інтерпретуватися як коментар та ігноруватися, тому -e
параметр (вихід при відмові) не буде оброблений. Отже, враховуючи наступний сценарій:
#!/bin/bash -e
echo Hello
false
echo goodbye
Вихід для ./script
буде просто "Привіт", але за результатом sh script
буде Hello
слідувати те goodbye
, що, ймовірно, не було призначено.
Це, до речі, саме тому завжди слід використовувати окремий set -e
вислів (все одно це гарна ідея - частіше за все, якщо є проблема середнього сценарію, ви не хочете, щоб його ігнорували).