Napisałem prosty skrypt. Kiedy uruchamiam sh <myscriptname.sh>
, mam prawidłowe wyjście, ale kiedy uruchamiam ./<myscriptname.sh>
, pojawia się błąd.
Jaka jest różnica między tym, co robię, sh
a czym ./
?
Napisałem prosty skrypt. Kiedy uruchamiam sh <myscriptname.sh>
, mam prawidłowe wyjście, ale kiedy uruchamiam ./<myscriptname.sh>
, pojawia się błąd.
Jaka jest różnica między tym, co robię, sh
a czym ./
?
Odpowiedzi:
Po uruchomieniu dowolnego skryptu poprzez przekazanie nazwy pliku do programu interpretera skryptów, uruchamiasz program interpretera ze skryptem jako przekazanym argumentem. Na przykład wyglądałoby to na proces „sh” z argumentem „nazwa_pliku.sh”. sh
Interpreter jest otwarcie pliku.
Z drugiej strony, jeśli uruchomisz sam skrypt, system wywołuje określony program interpretera i podaje zawartość skryptu. W takim przypadku proces wygląda jak „nazwa_pliku.sh” bez argumentów.
Powinieneś upewnić się, że masz linię huku:
#!/bin/bash
# bash script here
Linia Bang jest pierwszą linią w skrypcie i zaczyna się od tych samych dwóch znaków #!
, to jest to, co system czyta, gdy próbuje wykonać skrypt, a następnie system przekazuje skrypt do programu natychmiast po tym. Zauważ, że ten wiersz nie ma nic wspólnego z bash i działa równie dobrze dla Pythona i Perla, mimo że są to bardzo różne języki. Użyłbyś #!/usr/bin/python
na przykład, a następnie podążał za nim kod python.
Po otrzymaniu skryptu upewnij się, że masz ustawione uprawnienia do wykonywania:
chmod a+x filename.sh
Następnie możesz uruchomić skrypt jako własny proces:
./filename.sh
Lub umieść plik w znanej lokalizacji z ładną nazwą programu, na przykład /usr/sbin
i uruchom z dowolnego miejsca:
sudo cp filename.sh /usr/sbin/program-name
program-name
Jest to naprawdę praktyczna zaleta korzystania z linii Bang z odpowiednimi uprawnieniami - chodzi o wdrożenie . Bardzo trudno jest zmusić użytkowników do uruchomienia skryptu, jeśli muszą pamiętać, z jakim programem uruchomić skrypt. Pamiętaj, aby podać pełną ścieżkę do skryptu za każdym razem, gdy chcą go uruchomić. Gdzie, /usr/local/bin
na przykład, umieszczenie go i wykonanie, może zaoszczędzić okropnego smutku osobom próbującym użyć twojego skryptu. Programy te stają się następnie dostępne dla wszystkich użytkowników na twoim komputerze.
Jest także dobry do identyfikacji. Jeśli pójdziesz do top
programu, prowadzony przez skrypt bez linii huk po prostu mieć nazwę interpreter znaczy bash
, perl
albo python
. Ale jeśli skrypt jest uruchamiany z odpowiednimi uprawnieniami, wyświetla się nazwa skryptu.
Uwaga: Jeśli chcesz rozpowszechniać skrypt, który jest dostępny dla wszystkich, utwórz stronę podręcznika i pakiet deb, aby go zainstalować. Musimy zmniejszyć liczbę losowych skryptów online i zwiększyć liczbę debów, które można odinstalować.
bash
nie jest sh
.
PATH
.
/usr/local/bin
jest prawdopodobnie lepszy /usr/sbin
- wskazuje, że program jest lokalny dla tej maszyny, a nie częścią dystrybucji.
Krótka wersja:
sh
to interpreter wiersza poleceń (myślnik).
Uruchomienie sh my_script
powoduje, że dash interpretuje skrypt.
./
próbuje dowiedzieć się, którego interpretatora użyć, patrząc na pierwszą linię. Np. #!/bin/bash
Lub nawet #!/bin/ruby
(w przeciwieństwie do biegania ruby my_script
).
./
nic nie znajduje, to metoda wykonania systemu, która sprawdza pierwsze dwa bajty pliku.
sh
a plik zawiera sha-bang, czy to oznacza, że sha-bang zostanie zignorowany, czy też otworzy powłokę, w której sh
również linki, a może może inną powłokę lub co ona robi :)?
Różnica, którą robisz, to
z sh
, używasz programu, który zinterpretuje wiersze w skrypcie tak jak byś wpisywane je na interaktywnej wierszu terminalu,
ze ./
robisz skrót przy założeniu, że skrypt jest właśnie tu, w bieżącym katalogu ty siedzisz w I będzie to plik wykonywalny (bo na przykład jesteś wydane chmod +x myscript.sh
), co pozwala zaoszczędzić bezcenny czas dla przyszłych czasów :-)
sh
plik nie musi koniecznie być wykonywalny.
Istnieją trzy główne powody, dla których możesz otrzymać błąd:
chmod +x <myscriptname.sh>
to naprawićnoexec
”) /usr/local/bin
#!
wierszu wystąpił błąd, #!/bin/sh
lub#!/bin/bash
Jeśli pierwsza linia wygląda poprawnie, ale nadal nie działa, upewnij się, że plik nie ma zakończeń linii DOS.
Błąd wyglądałby mniej więcej tak:
$ ./myscript.sh
bash: ./myscript.sh: /bin/bash^M: bad interpreter: No such file or directory
Można to naprawić poprzez uruchomienie dos2unix <myscriptname.sh>
, lub jeśli nie masz, że
perl -p -i -e 's/\r\n$/\n/' <myscriptname.sh>
.
Odpowiedź brzmi: sh to nazwa bardzo popularnej powłoki. Ale przestarzałe i zastąpione innymi. Obecnie sh jest powiązany z innymi powłokami zainstalowanymi na komputerze. np. mam tam bash. Uruchamianie dowolnej powłoki z sh zwykle wyzwala tryb „kompatybilności” z oryginalnym zachowaniem „powłoki”.
Więc rozwiązanie jest dość proste. Spójrz, co kryje się za poleceniem sh (ls -al / bin / sh), i umieść #! / Bin / cokolwiek_funkcja w pierwszym wierszu (lub jeśli w skrypcie jest coś takiego edytuj).
Alternatywnie może występować pewien błąd w samym skrypcie. Podobnie jak zależność spełniana przez sh, ale nie faktycznie używany interpreter.
mkdir ~/bin ; cp myscript.sh ~/bin/
echo "export PATH="$PATH:/home/$USER/bin" >> ~/.profile ; source ~/.profile ;
Nie /usr/sbin
, to w przypadku nieistotnych narzędzi administracyjnych, /usr/local/bin
jest lepszym wyborem, jeśli nie chcesz ~/bin/
, ale sudo
wskazane jest unikanie jak największej ilości.
~/.profile
ma już kod do dodawania ~/bin
, jeśli istnieje, do PATH
. Z drugiej strony, nie umieszczaj rozszerzeń w skryptach.
ls ~/bin/|wc -l = 428
)
/bin
i /usr/bin
zobaczysz, że nie używają one rozszerzeń.