Czy istnieją jakieś rzeczywiste różnice między uruchomieniem skryptu
[sudo] sh ./<script>.run
zamiast
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
Czy istnieją jakieś rzeczywiste różnice między uruchomieniem skryptu
[sudo] sh ./<script>.run
zamiast
[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
Odpowiedzi:
Jeśli użyjesz
sh ./<script>.run
/bin/sh
(zwykle powłoka Bourne'a) zostanie użyta do uruchomienia skryptu. Oczywiście działa to tylko wtedy, gdy skrypt jest napisany dla powłoki Bourne'a. Czasami skrypty powłoki dla systemu Linux wymagają Bash zamiast powłoki Bourne'a, więc może to nie działać, nawet jeśli jest to skrypt powłoki.
Jeśli użyjesz
./<script>.run
jądro patrzy na linię shebang, aby dowiedzieć się, którego programu użyć do uruchomienia programu. To działa, nawet jeśli jest to Bash, Perl, Python lub inny skrypt.
Dlatego jest to zwykle preferowany sposób uruchamiania skryptu.
Tak długo, jak jest to sh
skrypt powłoki (Dash lub równoważny), nie, nie ma zewnętrznej różnicy.
Problem .run
nie gwarantuje, że tak jest. Może być binarny. Może to być Bash, Python, PHP lub cokolwiek innego; wszystkie mają hash-bang skryptu powłoki. Jeśli ślepo je przeforsujesz sh
, kto wie, co może się zdarzyć. Prawdopodobnie wystąpi błąd, ale może przypadkowo uruchomić szkodliwy kod, zanim dojdzie tak daleko.
Przez chmod
ding go (w celu umożliwienia wykonywania uprawnień bit), a następnie uruchomić go ./script.run
, dać mu możliwie najlepszą możliwość prowadzenia. Jeśli jest to skrypt powłoki, jego hash-bang zostanie poprawnie przeanalizowany, a jeśli jest to binarny plik wykonywalny, po prostu uruchomi się natywnie.
Te dwie metody często działają tak samo, ale są bardzo różne.
sh ./script
uruchamia sh
polecenie z argumentem ./script
, który zdarza się, aby wykonać dany skrypt. nawet jeśli skrypt nie jest tak naprawdę sh
skryptem (zły)
./script
wykonuje podany plik. Robi to, szukając linii „shebang” , aby określić, które polecenie należy uruchomić. Jeśli nie jest określony, używa sh
(to dwie metody działają czasami tak samo), ale często jest określony inny tłumacz.
Na przykład jeśli filename
zawiera następujące elementy:
#!/usr/bin/python
print "This is a Python script!"
.. następnie te dwa polecenia są bardzo różne:
$ sh script
script: line 3: print: command not found
$ chmod +x script
$ ./script
This is a Python script!
Jeśli nie ma linii shebang, obie są takie same:
$ cat script
echo "This is an sh script"
$ sh ./script
This is an sh script
$ ./script
This is an sh script
Jedną ważną różnicą jest to, czy twoja linia hashbanga ma parametry. Na przykład, jeśli skrypt zaczyna się od
#!/bin/bash -e
... i uruchamiasz go zewnętrznie za pomocą sh
lub bash
, ten wiersz zostanie zinterpretowany jako komentarz i zignorowany, więc -e
parametr (wyjście po awarii) nie zostanie przetworzony. Biorąc pod uwagę następujący skrypt:
#!/bin/bash -e
echo Hello
false
echo goodbye
Wyjście na ./script
będzie tylko „Hello”, ale wyjście sh script
zostanie Hello
następnie goodbye
, który nie został prawdopodobnie przeznaczony.
Nawiasem mówiąc, dlatego powinieneś zawsze używać osobnej set -e
instrukcji (i tak jest to dobry pomysł - częściej, jeśli nie ma problemu w połowie skryptu, nie chcesz, aby był ignorowany).