Jakie jest rozszerzenie pliku Bash?


84

Napisałem skrypt bash w edytorze tekstu, jakie rozszerzenie mam zapisać mój skrypt, aby mógł działać jako skrypt bash? Stworzyłem skrypt, który teoretycznie powinien uruchomić serwer ssh. Zastanawiam się, jak sprawić, by skrypt wykonywał się po kliknięciu. Używam systemu OS X 10.9.5.


4
Skrypt powłoki nie wymaga żadnego konkretnego rozszerzenia. Po prostu wykonaj to jakobash myscript
anubhava

7
Zwykle jest .sh, ale rozszerzenie nie musi w ogóle istnieć. Linux to nie Windows. Program, który ma zinterpretować twój skrypt, jest określony w jego pierwszej linii, tak powinno być #!/bin/bash. Może nawet zawierać parametry.
Havenard,

1
@anubhava Jak mógłbym uruchomić mój skrypt, gdybym tylko dwukrotnie go kliknął, a nie wpisał „bash myscript”
Amedeo

2
@Amedeo, który byłby nagłówkiem twojego pliku z linią #!/bin/bash.
Havenard,

4
Brak rozszerzeń: rozszerzenia Commandname są uważane za szkodliwe .
gniourf_gniourf

Odpowiedzi:


110

Nie zgadzając się z innymi odpowiedziami, istnieje powszechna konwencja używania .shrozszerzenia dla skryptów powłoki - ale nie jest to przydatna konwencja. Lepiej w ogóle nie używać rozszerzenia. Zaleta możliwości stwierdzenia, że foo.shjest to skrypt powłoki ze względu na jego nazwę, jest minimalna, a płacisz za to utratą elastyczności.

Aby skrypt bash był wykonywalny, musi mieć na górze linię shebang :

#!/bin/bash

i użyj chmod +xpolecenia, aby system rozpoznał go jako plik wykonywalny. Następnie należy go zainstalować w jednym z katalogów wymienionych w pliku $PATH. Jeśli skrypt zostanie wywołany foo, możesz go uruchomić z wiersza poleceń powłoki, wpisując foo. Lub jeśli znajduje się w bieżącym katalogu (typowym dla skryptów tymczasowych), możesz wpisać ./foo.

Ani powłoka, ani system operacyjny nie zwracają uwagi na rozszerzenie nazwy pliku. To tylko część nazwy. A nie dając mu specjalnego rozszerzenia, zapewniasz, że każdy (użytkownik lub inny skrypt), który go używa, nie musi dbać o to, jak został zaimplementowany, czy jest to skrypt powłoki (sh, bash, csh, czy cokolwiek) , skrypt Perla, Pythona lub Awk albo binarny plik wykonywalny. System jest specjalnie zaprojektowany, aby można było wywołać skrypt zinterpretowany lub plik wykonywalny binarny bez znajomości lub dbałości o sposób jego zaimplementowania.

Systemy podobne do UNIX zaczynały od czysto tekstowego interfejsu wiersza poleceń. GUI, takie jak KDE i Gnome, zostały dodane później. W systemie graficznym z interfejsem użytkownika zazwyczaj można uruchomić program (ponownie, niezależnie od tego, czy jest to skrypt, czy binarny plik wykonywalny), na przykład dwukrotnie klikając ikonę, która się do niego odnosi. Zwykle powoduje to odrzucenie wszystkich danych wyjściowych, które program może wydrukować, i nie pozwala na przekazywanie argumentów wiersza poleceń; jest znacznie mniej elastyczny niż uruchamianie go z zachęty powłoki. Ale w przypadku niektórych programów (głównie klientów GUI) może to być wygodniejsze.

Skryptów powłoki najlepiej się nauczyć z wiersza poleceń, a nie z graficznego interfejsu użytkownika.

(Niektóre narzędzia zrobić zwrócić uwagę na rozszerzeniach Na przykład kompilatory zazwyczaj używają rozszerzenia w celu określenia języka kod jest napisany w. .cDla C .cpp. Dla C ++, itp Konwencja ta nie ma zastosowania do plików wykonywalnych)

Należy pamiętać, że UNIX (i systemy podobne do UNIX) to nie Windows. MS Windows na ogół używa rozszerzenia pliku, aby określić, jak go otworzyć / wykonać. Binarne pliki wykonywalne muszą mieć .exerozszerzenie. Jeśli masz powłokę podobną do systemu UNIX zainstalowaną w systemie Windows, możesz skonfigurować system Windows tak, aby rozpoznawał .shrozszerzenie jako skrypt powłoki i używać powłoki do otwierania go; Windows nie ma #!konwencji.


2
Mam na celu to, o czym wspomniałeś w czwartym akapicie. Uruchamiam mój skrypt po kliknięciu ikony, która go dotyczy.
Amedeo,

2
@Amedeo: W takim razie zależy to od środowiska graficznego. W tym, którego używam (Cynamon pod Ubuntu), dwukrotne kliknięcie ikony wykonywalnego skryptu zachęca mnie do uruchomienia go w terminalu, wyświetlenia w edytorze lub uruchomienia bez terminala. Robi to niezależnie od rozszerzenia pliku.
Keith Thompson

4
(Necro) Jeśli pominiesz rozszerzenie, nie możesz mieć folderu o tej samej nazwie. Na przykład masz deploy.sh(lub deploy.bash) i folder deployz dodatkową logiką wdrażania. Jeśli zmienisz nazwę skryptu na prostą deploy, spowoduje to konflikt nazw. Nazywanie plików lub folderów w inny sposób utrudnia zarządzanie i prawdopodobnie sortowanie plików ( lsw edytorach itp.). Oczywiście shebang jest - ostatecznie - wyznacznikiem. Ale rozszerzenia plików mają swoje właściwe miejsce.
Kafoso

2
@Kafoso: Nie sądzę, abym kiedykolwiek czuł potrzebę posiadania skryptu i katalogu o tej samej nazwie. Gdybym to zrobił, mógłbym zadzwonić do katalogu Deploy, chociaż może to powodować problemy podczas kopiowania do systemu plików bez rozróżniania wielkości liter.
Keith Thompson

2
Na komputerze Mac dwukrotne kliknięcie plików zawsze otwiera je w domyślnej aplikacji. Dlatego pomocne jest posiadanie .shrozszerzenia, aby skrypt otwierał się w wybranym edytorze. Jeśli chcesz uruchomić skrypt po dwukrotnym kliknięciu, nadaj mu .commandrozszerzenie, a po dwukrotnym kliknięciu uruchomi się w Terminalu.
BallpointBen

18

Nie potrzebujesz żadnego rozszerzenia (lub możesz wybrać dowolne, ale .shjest to przydatna konwencja).

Powinieneś rozpocząć skrypt od #!/bin/bash(ta pierwsza linia jest rozumiana przez execve (2) syscall) i powinieneś uczynić swój plik wykonywalnym przez chmod u+x. więc jeśli twój skrypt jest w jakimś pliku $HOME/somedir/somescriptname.sh, musisz wpisać go raz

 chmod u+x  $HOME/somedir/somescriptname.sh

w terminalu. Zobacz chmod (1) dla polecenia i chmod (2) dla syscall.

O ile nie wpisujesz całej ścieżki do pliku, powinieneś umieścić ten plik w jakimś katalogu wymienionym w twoim PATH(zobacz environment (7) i execvp (3) ), który możesz ustawić na stałe w swoim, ~/.bashrcjeśli twoja powłoka logowania jest bash)

Przy okazji, możesz napisać swój skrypt w jakimś innym języku, np. W Pythonie, zaczynając go za pomocą #!/usr/bin/python, lub w Ocaml, zaczynając od #!/usr/bin/ocaml...

Wykonywanie skryptu przez dwukrotne kliknięcie (na co? Nie powiedziałeś!) To problem ze środowiskiem graficznym i może być specyficzny dla pulpitu (może być inny w przypadku Kde, Mate, Gnome, .... lub IceWM lub RatPoison). Być może przeczytanie specyfikacji EWMH pomoże ci uzyskać lepszy obraz.

Być może uczynienie skryptu wykonywalnym za pomocą chmodmoże sprawić, że będzie można go kliknąć na pulpicie (najwyraźniej Quartz na MacOSX). Ale wtedy prawdopodobnie powinieneś sprawić, by dawał wizualną informację zwrotną.

A kilka komputerów nie ma żadnego pulpitu, w tym własnego, gdy uzyskujesz do niego dostęp zdalnie za pomocą ssh .

Uważam, że uruchamianie skryptu powłoki przez kliknięcie nie jest dobrym pomysłem. Prawdopodobnie chcesz mieć możliwość podania argumentów do swojego skryptu powłoki (i jak byś to zrobił, klikając?) I powinieneś przejmować się jego wynikami. Jeśli jesteś w stanie napisać skrypt powłoki, możesz użyć interaktywnej powłoki w terminalu. Że to najlepszy i najbardziej naturalny sposób wykorzystania skryptu. Dobre interaktywne powłoki (np. Zsh lub fish lub być może niedawne bash) mają pyszne i konfigurowalne funkcje autouzupełniania i nie będziesz musiał dużo pisać (naucz się używać tabklawisza klawiatury). Ponadto skrypty i programy są często częściami poleceń złożonych (potoki itp.).

PS. Używam Uniksa od 1986 roku, a Linuksa od 1993 roku. Nigdy nie uruchamiałem własnych programów ani skryptów, klikając. Dlaczego powinienem?


3
OK, więc utworzyłem swój skrypt w edytorze tekstu. Zapisuję plik na pulpicie. Po kliknięciu skryptu, który jest zapisany na moim pulpicie, chcę, aby faktycznie był uruchamiany po kliknięciu go.
Amedeo,

6
Nie wiem, jaki jest twój pulpit (KDE, Gnome, MATE, ...). Gorąco zachęcam do używania wiersza poleceń w terminalu, zwłaszcza do uruchamiania skryptów (prawdopodobnie chcesz podać im kilka argumentów; jak byś to zrobił na pulpicie?). Jeśli potrafisz zakodować skrypt powłoki, powinieneś być w stanie interaktywnie używać powłoki w terminalu
Basile Starynkevitch

2
Chodzi mi o to, że jeśli kodujesz skrypt powłoki, powinieneś przyzwyczaić się do używania wiersza poleceń w terminalu.
Basile Starynkevitch

2
Rozumiem, że to dla projektu, nad którym pracuję. Chcę, aby skrypt wykonywał się po kliknięciu. Próbuję uniknąć używania terminala do uruchomienia skryptu.
Amedeo,

3
Używałbym chmod +xraczej niż chmod u+x, chyba że istnieje konkretny powód, aby ograniczyć wykonywanie do właściciela.
Keith Thompson

2

po prostu .sh.

Uruchom skrypt w następujący sposób:

./script.sh

EDYCJA: Jak powiedział anubhava, rozszerzenie tak naprawdę nie ma znaczenia. Jednak ze względów organizacyjnych nadal zaleca się używanie rozszerzeń.


6
Jeśli uruchamiasz skrypt, generalnie nie masz powodu, by przejmować się tym, w czym jest on napisany. Skrypt bash i binarny plik wykonywalny są wykonywane w ten sam sposób. Dodanie .shsufiksu do wykonywalnego skryptu jest generalnie bezużytecznym bałaganem.
Keith Thompson,

1
tak, ale jak powiedziałem w swoim redagowaniu - to konwencja porządkowania skryptów - nie więcej ?!
Marc Anton Dahmen

5
Widzę wiele skryptów z .shrozszerzeniem (i mniej z .bashrozszerzeniem), ale nie jestem przekonany, że jest to w ogóle przydatne. Jeśli foo.shnadam skryptowi nazwę, a później zdecyduję się ponownie zaimplementować go w Perlu, mogę albo zmienić nazwę (i edytować wszystko, co go używa), albo zostawić wprowadzające w błąd rozszerzenie. Jeśli nadam nazwę foo, nie mam tego problemu.
Keith Thompson,

@KeithThompson Sam przychodzi mi do głowy zastosowanie, nie obchodzi mnie, w jakim języku jest napisany skrypt. Nie mogę mówić w imieniu Perla, ale bardzo by mnie obchodziło, czy skrypt jest napisany w Pythonie lub Bashu. Ogólnie mogę założyć, że skrypt Bash będzie działał bez względu na wszystko, ale skrypty Python mają zależności, a Python 2 i Python 3 nie są ze sobą kompatybilne. Myślę też, że ważne jest rozróżnienie między skompilowanymi plikami binarnymi i skryptami (które nie miałyby żadnych rozszerzeń), ponieważ mają różne potrzeby w zakresie zależności (np. Plik binarny może wymagać bibliotek i być skompilowany dla AMD64 i działać tylko na tym).
jrh

@jrh Jasne, czasami ma to znaczenie (i możesz to sprawdzić, uruchamiając head -1 script.foolub file script.foo). Ale jeśli wszystko jest poprawnie zainstalowane i skonfigurowane, w 99% przypadków chcę, aby polecenie wykonało to, co powinno. Dla mnie to nie uzasadnia konieczności bycia świadomym przyrostka .pylub .bashprzyrostka za każdym razem, gdy go uruchamiam.
Keith Thompson

2

Wiem, że to jest teraz dość stare, ale czuję, że to dodaje do tego, o co pytano.

Jeśli używasz komputera Mac i chcesz mieć możliwość uruchomienia skryptu, klikając go dwukrotnie, musisz użyć .commandrozszerzenia. Również tak samo jak wcześniej, aby plik był wykonywalny z chmod -x.

Jak wspomniano wcześniej, nie jest to aż tak przydatne.


1

TL; DR - Jeśli użytkownik (niekoniecznie twórca) skryptu używa interfejsu GUI, zależy to od używanej przeglądarki plików. Finder MacOS będzie wymagał .shrozszerzenia w celu wykonania skryptu. Gnome Nautilus rozpoznaje jednak poprawnie wykonane skrypty z .shrozszerzeniem lub bez niego .

Wiem, że wielokrotnie mówiono o powodach za i przeciw używaniu rozszerzeń w skryptach bash, ale nie tak bardzo, dlaczego lub dlaczego nie używać rozszerzeń, ale mam to, co uważam za dobrą zasadę.

Jeśli jesteś typem, który wskakuje do basha i wychodzi z niego i ogólnie używasz terminala lub tworzysz narzędzie dla kogoś, kto nie używa terminala, dodaj .shrozszerzenie do swoich skryptów bash. W ten sposób użytkownicy tego skryptu mają możliwość dwukrotnego kliknięcia tego pliku w przeglądarce plików GUI w celu uruchomienia skryptu.

Jeśli jesteś typem, który głównie wykonuje całą lub większość swojej pracy w terminalu, nie przejmuj się dodawaniem żadnych rozszerzeń do swoich skryptów bash. Nie służyłyby one żadnemu celowi w terminalu, zakładając, że już skonfigurowałeś swój ~/.bashrcplik, aby wizualnie odróżniać skrypty od katalogów.

Edytować:

W przeglądarce plików Gnome Nautilus z 4 plikami testowymi (każdy z uprawnieniami do wykonania pliku) z głupio prostym poleceniem bash otwierającym okno terminala ( gnome-terminal):

  1. Plik bez rozszerzenia z #!/bin/bashw pierwszym wierszu.

    Zadziałało poprzez dwukrotne kliknięcie pliku.

  2. Plik z .shrozszerzeniem z #!/bin/bashw pierwszym wierszu.

    Zadziałało poprzez dwukrotne kliknięcie pliku.

  3. Plik bez rozszerzenia z NO #!/bin/bashw pierwszym wierszu.

    Zadziałało po dwukrotnym kliknięciu pliku ... technicznie, ale GUI nie wskazywało, że był to skrypt powłoki. Mówiło się, że to zwykły plik tekstowy.

  4. Plik z .shrozszerzeniem z NO #!/bin/bashw pierwszym wierszu.

    Zadziałało poprzez dwukrotne kliknięcie pliku.

Jednak, jak mądrze zauważył Keith Thompson w komentarzach do tej odpowiedzi, poleganie na używaniu .shrozszerzenia zamiast bash shebang w pierwszej linii pliku ( #!/bin/bash) może powodować problemy.

Innym jednak, pamiętam, kiedy wcześniej korzystałem z MacOS, że nawet poprawnie działała (czy to słowo?) Skrypty bash bez .shrozszerzenia nie mogły być uruchamiane z GUI na MacOS. Chciałbym jednak, żeby ktoś poprawił mnie w komentarzach. Jeśli to prawda, udowodniłoby, że istnieje co najmniej jedna przeglądarka plików, w której .shrozszerzenie ma znaczenie.


Z jakiej przeglądarki plików GUI korzystasz (lub, co ważniejsze, z jakiej przeglądarki korzystają Twoi użytkownicy)? Czy używa rozszerzenia, aby zdecydować, jak uruchomić skrypt?
Keith Thompson

Cóż, platforma, na której mam największe doświadczenie, to MacOS. W Finderze użytkownik decyduje, które aplikacje skojarzyć z danym rozszerzeniem. Teraz jestem na Linuksie i używam Gnome, ale nie mam czasu do eksperymentowania, jak przeglądarka plików Nautilus Gnome współdziała z plikami bez jeszcze rozszerzenia.
Ryan Hart

Jeśli masz wykonywalny skrypt z .shsufiksem #!/bin/bashw pierwszym wierszu, czy przeglądarka plików GUI będzie go używać shdo wywołania (ignorując shebang)? Jeśli tak, może to spowodować pewne problemy. (Odpowiedź może być inna dla różnych przeglądarek.)
Keith Thompson

Dobre punkty. Zaktualizowałem powyższą odpowiedź o kilka rzeczywistych testów, które właśnie przeprowadziłem.
Ryan Hart

Ciekawe, ale ... Powiedziałeś, że to „zadziałało”. Dla każdego z 4 przypadków testowych dobrze byłoby wiedzieć, czy wywołał go z /bin/bashlub /bin/sh(ten drugi jest domyślny dla skryptu bez shebang). Jeśli /bin/shjest dowiązaniem symbolicznym do /bin/bash(co jest dość powszechne), możesz to stwierdzić, patrząc na wartość $0. (Ponadto, jeśli bash jest wywoływany tak sh, jak ustawia POSIXLY_CORRECT=y.)
Keith Thompson,
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.