Jeśli skrypt.sh jest po prostu czymś typowym
#!/bin/bash
echo "Hello World!"
Czy istnieje preferowany sposób uruchomienia skryptu? Myślę, że najpierw musisz go chmod, aby stał się wykonywalny?
Jeśli skrypt.sh jest po prostu czymś typowym
#!/bin/bash
echo "Hello World!"
Czy istnieje preferowany sposób uruchomienia skryptu? Myślę, że najpierw musisz go chmod, aby stał się wykonywalny?
Odpowiedzi:
W przypadku konkretnego skryptu w obu przypadkach będzie działać, z wyjątkiem tego, że ./script.shwymaga wykonania i czytelnych bitów, a bash script.shjedynie wymaga bitu czytelnego.
Przyczyna różnicy wymagań dotyczących uprawnień leży w sposobie ładowania programu, który interpretuje skrypt:
./script.sh sprawia, że powłoka uruchamia plik tak, jakby był zwykłym plikiem wykonywalnym.Powłoka sama się rozwidla i używa wywołania systemowego (np. execve), Aby system operacyjny wykonał plik w rozwidlonym procesie. System operacyjny sprawdzi uprawnienia do pliku (stąd należy ustawić bit wykonawczy) i prześle żądanie do programu ładującego , który spojrzy na plik i określi sposób jego wykonania. W Linuksie skompilowane pliki wykonywalne zaczynają się od magicznej liczby ELF , podczas gdy skrypty zaczynają się od #!( hashbang ). Nagłówek hashbang oznacza, że plik jest skryptem i musi zostać zinterpretowany przez program określony po haszu. To pozwala samemu skryptowi powiedzieć systemowi, jak interpretować skrypt.
Za pomocą skryptu moduł ładujący program uruchomi się /bin/bashi przekaże ./script.sh jako argument wiersza polecenia.
bash script.shsprawia, że twoja powłoka działa bashi przekazuje script.shjako argument wiersza poleceńSystem operacyjny się załaduje bash(nawet nie patrząc script.sh, ponieważ jest to tylko argument wiersza poleceń). Utworzony bashproces zinterpretuje następnie, script.shponieważ został przekazany jako argument wiersza polecenia. Ponieważ script.shjest odczytywany tylko bashjako zwykły plik, bit wykonania nie jest wymagany.
Zalecam ./script.shjednak użycie , ponieważ możesz nie wiedzieć, jakiego interpretera wymaga skrypt. Pozwól więc programowi ładującemu ustalić to dla Ciebie.
. ./script.shto nie to samo, co bash script.sh(lub ./script.sh. Rozważmy skrypt #!/usr/bin/python -V<nowa linia> print test.
. script.sh. Ale zgadzam się z ludźmi, którzy zniechęcają do używania .polecenia w skryptach, które nie miały być wywoływane w ten sposób. Dziwię się, że nikt o tym nie wspominał, jeśli skrypt zawiera exitpolecenia, a Ty je pozyskasz, może Cię wylogować. Mniej poważnym problemem byłoby, gdyby skrypt działał cd, ponieważ wpłynęłoby to również na powłokę nadrzędną (interaktywną).
bash script.shwywołuje skrypt bezpośrednio za pomocą bash.
./script.shużywa shebang, #!/bin/bashaby określić sposób wykonania.
Jeśli naprawdę chcesz wiedzieć, który plik binarny jest wykonywany, możesz zrobić to bash script.shz which bash.
W twoim przykładzie nie ma to znaczenia. Tak, musisz chmod +x script.shbyć w stanie wykonać go bezpośrednio przez ./script.sh.
/bin/bashjest to pierwszy bashw twoim $PATH.
#!/bin/bashdziała tylko, jeśli jest/bin/bash
./script.sh.
Utwórz plik Delete_Self.sh w następujący sposób:
#!/bin/rm
echo I am still here!
Uruchom ten skrypt, a sh Delete_Self.shzobaczysz „Nadal tu jestem!” odbiło się echem.
Spraw, by był wykonywalny i uruchom go, ponieważ ./Delete_Self.shzobaczysz, że nic nie jest odbijane ponownie, gdy Delete_Self.shsam plik zniknie.
Różnica polega na tym, że:
bash script.shzignoruje #! wiersz, ponieważ jako program do uruchamiania script.sh określono bash../script.shprzeczyta #! wiersz, aby określić program do uruchomienia script.sh.Oprócz innych odpowiedzi przydatna jest znajomość różnicy między uruchomieniem skryptu za pomocą ./script.sh(i) i źródła ./script.sh(ii) - Wersja (i) tworzy nową powłokę, w której można uruchomić polecenie, podczas gdy (ii) uruchamia go w bieżąca powłoka - która może być obowiązkowa, jeśli plik wykonywalny zmienia zmienne środowiskowe, które należy zachować po wyjściu z pliku wykonywalnego. Na przykład, aby aktywować środowisko conda Pythona, należy zastosować:
source activate my_env
Uwaga: Inną alternatywą source, którą możesz napotkać, jest .wbudowane, tj
. activate my_env