Zrobiłem folder w ~ / bin, w którym mogę umieścić moje skrypty powłoki i umieściłem go na mojej $ PATH, a także podłączyłem akcję folderu do folderu ~ / bin, aby automatycznie ustawić uprawnienia do wykonywania, ponieważ tak łatwo o tym zapomnieć.
Kaydell,
Odpowiedzi:
22
Jeśli uruchamiasz swój skrypt z powłoki, tak naprawdę nie potrzebujesz #!/bin/shshebang, jak opisano w tej odpowiedzi - każdy system uniksopodobny, którego używałem, w tym OS X, ustawi się domyślnie, /bin/shjeśli nie zostanie określony konkretny interpreter ( ale to dobry pomysł, ponieważ inne niż powłoki nie będą wiedziały, jak wykonać skrypt, chyba że podasz shebang.)
Nie potrzebujesz również .shrozszerzenia. Ci zrobić konieczność ustalenia uprawnień wykonywalnych, np
$ chmod +x script.sh
(Jest $to znak zachęty powłoki; używam go do zilustrowania poleceń wydawanych interaktywnej powłoce. Nie wpisuj jej!)
Myślę jednak, że masz problem z tym, że utworzyłeś skrypt, np. script.shW bieżącym katalogu, i próbujesz go wykonać, po prostu pisząc script.sh. na przykład
$ cat >script.sh
echo hello, world
^D
$ chmod +x script.sh
$ script.sh
-bash: script.sh: command not found
( ^Doznacza control- D. Ten zapis znajdziesz w wielu artykułach o używaniu Uniksa).
Fakt, że script.shw tym przypadku jest to skrypt powłoki, to tylko połowa problemu; Twoim problemem jest to, że domyślnie powłoka nie przeszuka programu w bieżącym katalogu. Działa to jednak:
$ sh script.sh
hello, world
ponieważ shbierze skrypt za argument.
Możesz wykonać skrypt - lub ponownie dowolny plik wykonywalny - w bieżącym katalogu, jeśli jest oznaczony jako plik wykonywalny (tj. chmod +x), Określając, że chcesz uruchomić ten w bieżącym katalogu:
$ ./script.sh
hello, world
Możesz także przenieść skrypt do katalogu na swoim PATH. Polecam /usr/local/binto, jeśli skrypt ma być używany w całym systemie lub binkatalog w domu, jeśli skrypt jest tylko dla Ciebie. Ten ostatni wymaga dodania $HOME/bin, które rozwija się do nowego katalogu bin, do twojego PATHpoprzez dodanie następujących linii do twojego .profilew katalogu domowym:
PATH=$HOME/bin:$PATH
export PATH
Na koniec możesz, jeśli chcesz, faktycznie dodać bieżący katalog do swojego PATH, co pozwoli ci po prostu przejść do katalogu zawierającego script.sh- lub dowolny inny plik wykonywalny - i wpisać
$ script.sh
wykonać to. Jednak nie zalecam tej praktyki , ponieważ osoba atakująca może teraz nakłonić cię do uruchomienia dowolnego pliku wykonywalnego, upuszczając skrypt wykonywalny (o nazwie, powiedzmy, ls) w katalogu, w którym się znajdziesz. Jeśli jednak naprawdę chcesz to zrobić, po prostu dodaj do swojego .profile:
Połóż '.' na końcu $ PATH zamiast na początku i teraz nie musisz się martwić o fantomowe „ls”. (Chociaż jeśli ktoś może dostać się do twojego systemu, masz większe problemy.)
TJ Luoma,
2
@TJ, ale nie trzeba się martwić o rzeczy, jak sli llsczy l... to znaczy, literówek. Wystarczy wyjechać .poza $PATH. Ponadto niekoniecznie (lub nie należy) ufać wszystkim w systemie. Na przykład, załóżmy, że istnieje jakiś exploit, który umożliwia atakującemu upuść dowolny plik do jakiegoś katalogu, ale muszą Państwo wykonać ten plik, aby eskalować do lepszego wykorzystania (np, zbierać dane i telefon domowy). Obrona w głębi!
Reid,
@TJLuoma Co powiedział @Reid, a ponadto należy pamiętać, że istnieje wiele przypadków użycia systemu Unix poza osobistym pulpitem OS X. Nie próbowałem tego, ale założę się, że nawet konto gościa może zostawić jeden z tych przedmiotów w /tmpinnym katalogu z możliwością zapisu na całym świecie.
zigg
Jeśli korzystasz z systemu, w którym inne osoby mają dostęp do używanych przez Ciebie katalogów, masz większe problemy.
TJ Luoma,
@TJLuoma Najlepiej nigdy nie używaj wielu kont w żadnym systemie uniksowym. /tmpi in. przyjechać z terytorium.
zigg
10
Nie musisz dzwonić, shjeśli plik skryptu jest oznaczony jako wykonywalny. W takim przypadku możesz nazwać to moim imieniem, tak jak każde inne polecenie z istniejącej powłoki.
Aby być w pełni poprawnym, będziesz chciał zrobić dwie rzeczy:
Zmodyfikuj skrypt, tak aby zawierał dyrektywę shebang na górze skryptu:
#!/bin/sh
... To powiedziałoby powłoce, którego interpretera użyć do uruchomienia skryptu; w tym przypadku /bin/shplik wykonywalny.
Oznacz skrypt jako wykonywalny za pomocą komendy chmod :
chmod u+x scriptname.sh
Po wykonaniu obu tych czynności możesz uruchomić skrypt, wpisując nazwę pliku skryptu w wierszu polecenia. Musisz znajdować się w tym samym katalogu co skrypt, chyba że wykonasz dodatkowy krok dodawania folderu zawierającego do zmiennej PATH . Jeśli nie obchodzi Cię, która powłoka uruchamia skrypt, nie musisz określać kroku pierwszego, shale często lepiej jest być precyzyjnym i ustawić „shebangsh”.
Shebangs nie są w rzeczywistości potrzebne /bin/sh, chociaż nie ranią.
zigg
@zigg - masz rację. Mam nadzieję, że Chris nie będzie miał nic przeciwko moim edycjom… Nuke lub ponownie edytuj zgodnie z potrzebami: -0
bmike
@bike Edycje działają dla mnie. Jeśli chodzi o shebangi, moim nawykiem było zawsze sprecyzowanie, ponieważ kiedyś pisałem wiele kshskryptów na HP-UX - ale dobrze wiedzieć, że nie jest to absolutnie konieczne.
Chris W. Rea
1
Myślę, że muszę wycofać się z mojego wcześniejszego stwierdzenia o konieczności shebang (choć reszta mojej odpowiedzi wciąż jest ważna). Możesz uruchomić skrypt bez shebang z powłoki, ale jeśli użyjesz execsyscall, dostaniesz ENOEXEC(błąd formatu exec ). Przepraszam za to, @bmike, @ ChrisW.Rea. Zamierzam teraz edytować moją odpowiedź.
Odpowiedzi:
Jeśli uruchamiasz swój skrypt z powłoki, tak naprawdę nie potrzebujesz
#!/bin/sh
shebang, jak opisano w tej odpowiedzi - każdy system uniksopodobny, którego używałem, w tym OS X, ustawi się domyślnie,/bin/sh
jeśli nie zostanie określony konkretny interpreter ( ale to dobry pomysł, ponieważ inne niż powłoki nie będą wiedziały, jak wykonać skrypt, chyba że podasz shebang.)Nie potrzebujesz również
.sh
rozszerzenia. Ci zrobić konieczność ustalenia uprawnień wykonywalnych, np(Jest
$
to znak zachęty powłoki; używam go do zilustrowania poleceń wydawanych interaktywnej powłoce. Nie wpisuj jej!)Myślę jednak, że masz problem z tym, że utworzyłeś skrypt, np.
script.sh
W bieżącym katalogu, i próbujesz go wykonać, po prostu piszącscript.sh
. na przykład(
^D
oznacza control- D. Ten zapis znajdziesz w wielu artykułach o używaniu Uniksa).Fakt, że
script.sh
w tym przypadku jest to skrypt powłoki, to tylko połowa problemu; Twoim problemem jest to, że domyślnie powłoka nie przeszuka programu w bieżącym katalogu. Działa to jednak:ponieważ
sh
bierze skrypt za argument.Możesz wykonać skrypt - lub ponownie dowolny plik wykonywalny - w bieżącym katalogu, jeśli jest oznaczony jako plik wykonywalny (tj.
chmod +x
), Określając, że chcesz uruchomić ten w bieżącym katalogu:Możesz także przenieść skrypt do katalogu na swoim
PATH
. Polecam/usr/local/bin
to, jeśli skrypt ma być używany w całym systemie lubbin
katalog w domu, jeśli skrypt jest tylko dla Ciebie. Ten ostatni wymaga dodania$HOME/bin
, które rozwija się do nowego katalogu bin, do twojegoPATH
poprzez dodanie następujących linii do twojego.profile
w katalogu domowym:Na koniec możesz, jeśli chcesz, faktycznie dodać bieżący katalog do swojego
PATH
, co pozwoli ci po prostu przejść do katalogu zawierającegoscript.sh
- lub dowolny inny plik wykonywalny - i wpisaćwykonać to. Jednak nie zalecam tej praktyki , ponieważ osoba atakująca może teraz nakłonić cię do uruchomienia dowolnego pliku wykonywalnego, upuszczając skrypt wykonywalny (o nazwie, powiedzmy,
ls
) w katalogu, w którym się znajdziesz. Jeśli jednak naprawdę chcesz to zrobić, po prostu dodaj do swojego.profile
:źródło
sl
ills
czyl
... to znaczy, literówek. Wystarczy wyjechać.
poza$PATH
. Ponadto niekoniecznie (lub nie należy) ufać wszystkim w systemie. Na przykład, załóżmy, że istnieje jakiś exploit, który umożliwia atakującemu upuść dowolny plik do jakiegoś katalogu, ale muszą Państwo wykonać ten plik, aby eskalować do lepszego wykorzystania (np, zbierać dane i telefon domowy). Obrona w głębi!/tmp
innym katalogu z możliwością zapisu na całym świecie./tmp
i in. przyjechać z terytorium.Nie musisz dzwonić,
sh
jeśli plik skryptu jest oznaczony jako wykonywalny. W takim przypadku możesz nazwać to moim imieniem, tak jak każde inne polecenie z istniejącej powłoki.Aby być w pełni poprawnym, będziesz chciał zrobić dwie rzeczy:
Zmodyfikuj skrypt, tak aby zawierał dyrektywę shebang na górze skryptu:
#!/bin/sh
... To powiedziałoby powłoce, którego interpretera użyć do uruchomienia skryptu; w tym przypadku
/bin/sh
plik wykonywalny.Oznacz skrypt jako wykonywalny za pomocą komendy chmod :
chmod u+x scriptname.sh
Po wykonaniu obu tych czynności możesz uruchomić skrypt, wpisując nazwę pliku skryptu w wierszu polecenia. Musisz znajdować się w tym samym katalogu co skrypt, chyba że wykonasz dodatkowy krok dodawania folderu zawierającego do zmiennej PATH . Jeśli nie obchodzi Cię, która powłoka uruchamia skrypt, nie musisz określać kroku pierwszego,
sh
ale często lepiej jest być precyzyjnym i ustawić „shebangsh”.źródło
/bin/sh
, chociaż nie ranią.ksh
skryptów na HP-UX - ale dobrze wiedzieć, że nie jest to absolutnie konieczne.exec
syscall, dostanieszENOEXEC
(błąd formatu exec ). Przepraszam za to, @bmike, @ ChrisW.Rea. Zamierzam teraz edytować moją odpowiedź.