Różnica między + x a ./ <skrypt> i sh ./ <skrypt>

13

Czy istnieją jakieś rzeczywiste różnice między uruchomieniem skryptu

[sudo] sh ./<script>.run

zamiast

[sudo] chmod +x ./<script>.run
[sudo] ./<script>.run
użytkownik36976
źródło

Odpowiedzi:

18

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.

Florian Diesch
źródło
1
Jak powiedziałem w odpowiedzi olis: sprawdziłem plik wykonywalny, uruchamiam shebang jego / bin / sh, więc prawdopodobnie jest w porządku, nie mogę się doczekać i zobaczę, czy ktoś ma jakieś inne informacje, a następnie zaakceptuję odpowiedź
36976
7

Tak długo, jak jest to shskrypt powłoki (Dash lub równoważny), nie, nie ma zewnętrznej różnicy.

Problem .runnie 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 chmodding 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.

Oli
źródło
Ach, nie wiedziałem, że dzięki za odpowiedź, właśnie sprawdziłem plik wykonywalny, uruchamiam hash-bang to / bin / sh, więc myślę, że jest w porządku
user36976
1

Te dwie metody często działają tak samo, ale są bardzo różne.

sh ./scripturuchamia shpolecenie z argumentem ./script, który zdarza się, aby wykonać dany skrypt. nawet jeśli skrypt nie jest tak naprawdę shskryptem (zły)

./scriptwykonuje 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 filenamezawiera 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
dbr
źródło
1

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ą shlub bash, ten wiersz zostanie zinterpretowany jako komentarz i zignorowany, więc -eparametr (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 ./scriptbędzie tylko „Hello”, ale wyjście sh scriptzostanie Hellonastępnie goodbye, który nie został prawdopodobnie przeznaczony.

Nawiasem mówiąc, dlatego powinieneś zawsze używać osobnej set -einstrukcji (i tak jest to dobry pomysł - częściej, jeśli nie ma problemu w połowie skryptu, nie chcesz, aby był ignorowany).

lutzky
źródło
0

Nie

[sudo] chmod +x ./<scrupt>.runsprawia, że ​​skrypt jest wykonywalny, dzięki czemu można go uruchomić ./<script>.run.
Dzięki [sudo] sh ./<script>.runniemu możesz go uruchomić, nawet jeśli nie jest wykonywalny.

Pabi
źródło