.sh określając rozszerzenie?


12

Dlaczego niektóre systemy uruchamiają .shplik, podając nazwę pliku bez rozszerzenia, a inne wymagają nazwy plus rozszerzenia? W moim przypadku próbuję napisać serię poleceń zgodnie z tymi instrukcjami .

Podaję teraz rozszerzenie, ale .shlepiej byłoby móc uruchamiać polecenia bez niego.


4
Używanie .shjako rozszerzenia jest w wielu okolicznościach uważane za złą praktykę: jest sprzeczne z nazwą innych poleceń (nie uruchamiasz ls.elf), często wprowadza w błąd (jeśli zaczniesz foo.shod #!/bin/bash, to uruchomienie sh foo.shuruchomi go z innym interpreterem niż dla ), a jeśli przerobisz foo.shprogram na Python, użycie tego rozszerzenia oznacza, że ​​musisz wybrać między zachowaniem wprowadzającej w błąd nazwy a przepisaniem każdego programu, który ją wywołuje.
Charles Duffy

2
... gdzie to jest najlepszą praktyką jest Biblioteki shell, nie nakazuje z +xzestawu - gdzie foo.shjest biblioteka, która może być pozyskiwany w każdym POSIX powłoki, foo.bashmoże być pozyskiwany w bash, foo.kshw ksh, itp
Charles Duffy

Odpowiedzi:


39

Jesteś zdezorientowany .shRozszerzenie jest tylko propozycją dla ludzi, a nie ma żadnego wpływu na to, jak system obsługuje plik. Unix / Linux nie spowodował Secrets.pdf.exebłędu systemu Windows .

Oto, co się dzieje, gdy piszesz foo:

  1. Przekierowanie na STDIN, STDOUTi STDERRsą ustawione.

  2. Powłoka sprawdza swoją wewnętrzną tablicę skrótów, aby sprawdzić, czy już zna $PATHwpis dla foo. Jeśli nie istnieje, powłoka przeszukuje katalogi $PATH, szukając pliku o nazwie fooo ustawionym bicie Wykonania w swoich uprawnieniach do plików. Pierwsze foowygrane.

  3. Jeśli pierwsze dwa bajty pliku footo #!następny ciąg to nazwa tłumacza do uruchomienia. W ten sposób #!/bin/bashwprowadza skrypt Bash, skrypt #!/usr/bin/perlPerl itp.

  4. Jeśli plik zaczyna się od \177ELF, jest to binarny plik wykonywalny i ld.souruchamia go.

Przeczytaj man execvei man ld.sobardziej szczegółowe wyjaśnienia.


15
Tak, w systemie Linux możesz dwukrotnie kliknąć Secrets.pdf bez pojęcia, że ​​to plik wykonywalny;)
OrangeDog

1
@OrangeDog Wiem, że żartujesz, ale wydaje mi się, że muszę zwrócić uwagę, że wykonywalny bit ( chmod +x) prawie to rozwiązuje, prawda?
wchargin 28.04.16

3
@WChargin To zależy od tego, jak dobrze zachowuje się twój system plików (np. Zamontowany udział sieciowy lub partycja NTFS może optymalnie ustawić xbit na wszystko) i skąd pochodzi plik (każdy proces kontrolujący katalog może zostać oszukany w ustawianiu uprawnień) . Więc to łagodzi , ale nie powiedziałbym, że to rozwiązuje .
IMSoP

2
@WChargin, ale myślę, że jego punkt widzenia polega na tym, że menedżerowie plików zwykle nie pokazują bitu wykonywalnego, tj. Nie ma „wskazówki dla ludzi” jak rozszerzenia.
Paul Draper

1
Nigdy nie mylę kliknięcia, Secrets.pdf.exeponieważ zawsze wyłączam głupią hide file extensionfunkcję
phuclv 29.04.16

12

Kluczowa kwestia jest taka: rozszerzenia nie mają znaczenia w żadnym systemie systemowym podobnym do Uniksa. Nazwa pliku to po prostu nazwa i nie ma wpływu na to, czy skrypt lub skompilowany plik wykonywalny mogą być uruchomione . Programista może dodać .shrozszerzenie, aby oznaczyć, że plik jest skryptem powłoki lub .pyskryptem Pythona, ale w przeciwieństwie do systemu Windows, każdy system uniksowy nie dba o nazewnictwo, dba o uprawnienia.

Liczy się uprawnienie do pliku nadane plikowi. Które możesz sprawdzić

ls -l /path/to/file

Uruchamianie plików wykonywalnych

Aby uruchomić skrypt, jest na ogół kilka sposobów.

  • Jeśli twój bieżący katalog jest taki sam jak skrypt, a skrypt ma uprawnienia do wykonywania, możesz go tak uruchomić ./my_script_name. .Oznacza katalog bieżący.
  • Jeśli bieżący katalog jest inny, a skrypt ma uprawnienia do wykonywania, możesz go uruchomić, podając pełną ścieżkę: /home/user/bin/my_script_name

(Dwie powyższe metody polegają na ustawieniu uprawnień do wykonywania; nie $PATHma znaczenia , czy plik jest częścią zmiennej. Nie ma znaczenia również obecność #!linii; bez niej skrypt zostanie wykonany przez otwartą powłokę, którą otworzyłeś. Jeśli mam cshskrypt) bez tej linii i spróbuj uruchomić ją bash z ./my_script.csh, to się nie powiedzie)

  • Jeśli twój skrypt znajduje się w katalogu, który jest częścią $PATHzmiennej, możesz go uruchomić, wywołując nazwę. Możesz wywołać chmodpolecenie w wierszu polecenia, wpisując jego nazwę, ponieważ znajduje się w /binfolderze. /binjest zawsze częścią $PATHzmiennej. W tym przypadku ważne są uprawnienia do wykonywania i lokalizacja skryptu
  • Podanie interpretera jako polecenia i skryptu jako argumentu. W ten sposób skrypt będzie służył jako plik wejściowy do interpretera.
  • Pozyskiwanie pliku. Znak . filename.shlub source filename.shsprawi, że skrypt będzie traktowany tak, jakby był wprowadzany z klawiatury, tj. Tak, jakby był wpisany bezpośrednio w linii poleceń. W tym przypadku uprawnienia do wykonywania i lokalizacja nie mają znaczenia

Przykłady

Przykład 1, działający z tłumaczem, w celu wykonania uprawnień

$-> ls -l abc.py                                                               
-rw-rw-r-- 1 xieerqi xieerqi 44 Apr 27 22:39 abc.py
$-> python abc.py                                                              
a
b
c

Przykład # 2, działający z ./zestawem uprawnień do plików wykonywalnych, zestaw linii shebang.

$-> cat abc.py                                                                 
#!/usr/bin/env python
for letter in 'a' 'b' 'c' :
   print letter
$-> ls -l abc.py
-rwxrwxr-x 1 xieerqi xieerqi 66 Apr 27 23:02 abc.py*
$-> ./abc.py                                                                   
a
b
c

Przykład # 3, działanie bez zestawu linii shebang (kończy się niepowodzeniem, ponieważ bash nie może odczytać skryptów w języku Python; żadna linia shebang nie przyjmuje bieżącej powłoki jako interpretera)

$-> cat abc.py                                                                 
for letter in 'a' 'b' 'c' :
   print letter
$-> ./abc.py                                                                   
./abc.py: 2: ./abc.py: Syntax error: word unexpected (expecting "do")

Przykład # 4, uruchamianie skryptu, który ma uprawnienia do wykonywania ustawia folder formularza, który jest częścią $PATHzmiennej

#  /home/xieerqi/bin is part of my path variable
$-> echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/microchip/xc16/v1.25/bin:/opt/microchip/xc32/v1.40/bin:/opt/microchip/xc8/v1.35/bin:/home/xieerqi/bin:/home/xieerqi/bin/sh

$-> # current directory is /home/xieerqi
$-> pwd
/home/xieerqi
$-> # move the file to ~/bin
$-> mv ~/abc.py ~/bin/abc.py
$-> # now I can run it just by calling the name
$-> abc.py
/home/xieerqi/bin/abc.py: 2: /home/xieerqi/bin/abc.py: Syntax error: word unexpected (expecting "do")
$-> # Syntax error because again, no interpreter specified.                    
$-> # must add #!/usr/bin/env python
$-> vi /home/xieerqi/bin/abc.py          
$-> # after adding the line with vi text editor, we can run
$-> abc.py                                                                     
a
b
c

Przykład # 5, usuwanie rozszerzenia, nadal działa, ponieważ rozszerzenia nie mają znaczenia, ale mają uprawnienia i są częścią $PATH:

$-> mv ~/bin/abc.py  ~/bin/abc                                                 
$-> abc
a
b
c

Uruchomiłem polecenie i dostaję to „-rwxr-x ---”. Co chcę, aby wartość była czytana i jak mogę ją zmienić?
Philip Kirkbride

A może mówisz, że powinienem po prostu zmienić nazwę „filename.sh” na „filename”?
Philip Kirkbride

1
@PhilipKirkbride Nazwa nie ma znaczenia. Jak uruchamiasz swoje polecenie? Gdzie to jest ? Czy katalog jest częścią twojego PATH?
Sergiy Kolodyazhnyy

@ PhilipKirkbride Pozwól mi rozwinąć moją odpowiedź za minutę, aby była jaśniejsza.
Sergiy Kolodyazhnyy

1
Przyjrzeć się man chmod, w jaki sposób ustawić uprawnienia
Nick Mertin

6

Dobre wyjaśnienia już tutaj. Chciałem tylko dodać, że idealnie nie powinieneś używać rozszerzeń plików dla plików wykonywalnych.

Zwykle musisz osiągnąć coś stosunkowo łatwego i zaczynasz od małego skryptu powłoki. Z biegiem czasu zaczynasz dodawać coraz więcej funkcji do skryptu, dopóki nie nadejdzie czas, że stanie się niemożliwy do utrzymania lub potrzebujesz funkcji, których nie można łatwo uzyskać za pomocą skryptu powłoki i myślisz o przepisaniu tego skryptu powłoki w innym języku (python , perl, ...?).

Przepisywanie od zera jest zwykle uważane za błąd, ale w przypadku skryptów może to mieć sens, ponieważ zwykle nie są one tak duże lub mają wiele funkcji. Załóżmy jednak, że można napisać od nowa w innym języku, zachowując funkcjonalność i parametry / flagi początkowego skryptu powłoki.

Użytkownicy tego skryptu nie muszą być świadomi tej zmiany języka, będą wykonywać to samo polecenie i będzie nadal działać.

Jeśli twój skrypt został nazwany do-something.sh, może dalej być do-something.sh, ale teraz jest napisany w Pythonie (na przykład), więc twoja początkowa wskazówka jest teraz całkowicie myląca.


4

Aby uruchomić pliki bez rozszerzenia, zwykle nie musisz wiele robić, po prostu upewnij się, że masz (w przypadku skryptów bash) właściwą linię shebang w pierwszej linii:

#!/bin/bash

wtedy również trzeba zrobić plik wykonywalny dla systemu przez

chmod 755 yourfilename

To samo, co przy użyciu chmod +x yourfilenameliczb, które można łatwo wyjaśnić.

Jest to liczba potrójna z dodanych ósemek, pierwsza liczba oznacza użytkownika, druga dla grupy, a trzecia dla innych, więcej na ten temat można znaleźć tutaj .

A jeśli jesteś w tym samym katalogu co skrypt, nie zapomnij użyć ./tego w ten sposób:

./yourfilename

Próbowałem tego. Niestety nie ma różnicy od oryginalnych wyników.
Philip Kirkbride

@ PhilipKirkbride spójrz na moją poprawioną odpowiedź, która prawdopodobnie rzuci więcej światła.
Videonauth,

0

Sufiks .sh może przeszkadzać, ponieważ aby go uruchomić, należy wpisać myscript.sh zamiast po prostu myscript, który nie będzie działał. Lepiej po prostu nazwać go „myscript” bez sufiksu .sh, a szybkie użycie polecenia „file” powie ci, czy jest to binarny plik wykonywalny (format ELF na linuksie), skrypt powłoki, czy jakikolwiek inny skrypt.

QDOS (szybki i brudny system operacyjny, później przemianowany przez IBM na „DOS” po tym, jak Mirosoft dokonał piracji i nielegalnie go sprzedał) oraz inne tanie ripoffy CP / M, w tym Windows, pomieszają to wszystko, ponieważ w tych systemach nie ma coś takiego jak wykonywanie uprawnień do plików. Doprowadziło to do niezliczonych f'up bezpieczeństwa w ciągu ostatnich 30-40 lat. Właściwie kilka minut temu dostałem kilka śmieciowych wiadomości z dureńskim plikiem zip o nazwie MYPICTURE.JPG.zip :)

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.