Korzystam ze skryptu bash w terminalu , więc wychodzę z błędu
set -o errexit
zabija mój terminal, co jest niesamowicie denerwujące, ponieważ muszę zamknąć terminal, otworzyć inny i zresetować niektóre zmienne.
Do tej pory za pomocą
command || return
wiersze w skrypcie robią dokładnie to, co chcę
set -o errexit
robić ... Ale chcę, żeby zrobiono to dla całego skryptu; nie tylko jedna linia / polecenie
Mam plik pełen poleceń do konfigurowania witryny i wolałbym nie wykonywać poleceń || powrót
dla każdej linii w pliku
Czy istnieje inna opcja zestawu lub coś, co po prostu „powróci” zamiast wychodzić z terminala?
- Dla jasności chciałbym zabić skrypt i pozostawić terminal w tym samym stanie, co naciśnięcie klawiszy Ctrl + C, aby zabić usługę uruchomioną w terminalu. command || return
robi to. Ale nie chcę przyczepiać się || return
do każdej linii w pliku. Więc szukam czegoś podobnego set -o errexit
, co nie spowoduje zamknięcia terminala
--- Uwaga: Tworzenie głupiego skryptu zawierającego dwie linie (super.sh):
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
I umieszczenie set -o errexit
na górze create.sh,
działa dokładnie tak, jak tego oczekuję. Jednak naprawdę głupie jest tworzenie pliku zawierającego dwie linie, aby wywołać inny skrypt bash, zamiast wywoływać go z terminala. Uhghhh
oto kilka przykładów:
w super.sh
#!/bin/bash
create_path=~/Desktop/site_builder/create.sh
source $create_path blah
w create.sh
#!/bin/bash
set -o errexit
#line below this is a line that fails and will cause the script to stop and return to the terminal as expected
sed "s/@@SITE_NAME@@/$dirname"
~/Desktop/site_builder/template_files/base.html > ~/Desktop/$dirname/templates/base.html # a line with a stupid error
w terminalu:
$ bash super.sh
wynik zgodny z oczekiwaniami:
my-mac$
To działa. Co za irytujące rozwiązanie.
I chce , najlepiej, aby wykonać to, co znajduje się w głupiej pliku super.sh z terminala, a nie pliku super.sh: D, bez konieczności wyłączania terminala na mnie. Oto, co dzieje się z tym, co próbuję zrobić:
polecenie terminala:
my-mac$ source $create_path blah
w create.sh nadal mam set -o errexit
Oto wynik na terminalu
sed: 1: "s/@@SITE_NAME@@/blah": unterminated substitute in regular expression
Saving session...
...copying shared history...
...saving history...truncating history files...
...completed.
[Process completed]
A następnie terminal jest zamrożony. Ctrl + C nie działa, podobnie jak Ctrl + D
Jeśli zamiast tego set -o errexit
, jeśli po prostu używam command || return
instrukcji wszędzie w pliku create.sh, to dostaję dokładnie to, czego chcę, wykonując wiersze w supser.sh bezpośrednio na terminalu (zamiast wywoływać super.sh z terminalu). Ale to też nie jest praktyczne rozwiązanie.
Uwaga: Podobała mi się odpowiedź @terdona dotycząca po prostu odradzania powłoki potomnej, więc skończyłem po prostu odradzaniem powłoki podrzędnej za pomocą skryptu zamiast terminala, jak pokazał w swojej odpowiedzi za pomocą nawiasów klamrowych ( )
wokół całego skryptu. Jego odpowiedź też działa.
source $file_path argument
Skrypt jest wykonywany w tej samej powłoce, z której gosource
command || return
Odpowiedzi:
Po prostu źródło pliku z bezpiecznym:
... wtedy ogólne polecenie nie zawiedzie, nawet jeśli
source
nie.źródło
source file || true
nie robi tego,source file || return
Jills-MBP:~ jillr$ source ~/Desktop/site_builder/create.sh blah || true
po prostu wykonuje następną część skryptu po awarii, więc zwraca wartość zamiast prawdy. Jedyne, co zadziałało, tocommand || return
instrukcje w rzeczywistym pliku dla wszystkich poleceń, co jest głupie. Nie wiem, czy rzucenie tego wszystkiego w funkcję, a następnie wywołaniefunction || return
na końcu pliku również by się przydało.|| return
wydasz polecenie, które się nie powiedzie, tak, ono zwróci. Myślałem, że próbujemy powstrzymać twoją główną / rodzicielską powłokę przed wyjściem?Jest to jedyna rzecz, która działa dla tego, co musiałem osiągnąć (stworzenie środowiska wirtualnego, następnie aktywacja go, a następnie instalacja wymagań ze skryptu bash):
spawnuje powłokę podrzędną / potomną ze skryptu, jak w:
stupid_file.sh
uruchom plik stupid_file używając:
KONIEC.
** bierze ukłon **
(podziękowania dla Jeffa i Terdona)
źródło
bash $create_path blah
i sprawdzić, czy nadal się kończy, wykonuje tę samą procedurę i nadal poprawnie instaluje elementy w moim środowisku wirtualnym. Nie ma czasu.(...)
, ponieważ wszystkie przypisania w nawiasach wpływają tylko na tę podpowłokę.foo=3; (foo=5); echo "$foo"
source file
z terminala i oczekuję takich samych rezultatów. Ponieważ to nigdy nie działało. Jedyne czasy, kiedy otrzymuję te same wyniki, to jawne utworzenie sub-powłoki, czy to przez terminal, czy ze skryptu. Mogę jednak użyćbash
zamiastsource
do wykonania skryptu i uzyskać te same wyniki, ale tylko wtedy, gdy wykonam skrypt bezpośrednio w powłoce pomocniczejpip install -r $apath/requirements.txt
w tym aktywowanym środowisku. Właśnie dlatego użyłem źródła do wywołania skryptuW ramach prostego obejścia można uruchomić powłokę w bieżącej powłoce i źródle. Coś jak:
Otwórz nowy terminal i ustaw wszystko tak, jak chcesz. Wspomniałeś o niektórych zmiennych środowiskowych i tym podobnych. Ustaw je tutaj.
W tym terminalu uruchom nową powłokę. Na przykład
bash
.Rób swoje. Źródło skryptu. Jeśli wyjdzie, zostaniesz wrzucony do pierwszej skorupy i wszystko jest nadal ustawione. Po prostu uruchom
bash
ponownie i wrócisz do pracy.Aby to zilustrować, stworzyłem ten skrypt, który zawiedzie, jeśli spróbujesz go zdobyć:
Zobaczmy, co się stanie, jeśli rozpocznę zagnieżdżoną sesję powłoki, a następnie ją źródła (zwróć uwagę, że używam przenośnej nazwy dla
source
polecenia.
;source
to bashism):Jak widać, błąd składniowy spowodował zamknięcie skryptu źródłowego, co z kolei spowodowało zamknięcie mojej sesji powłoki, ale ponieważ była to sesja zagnieżdżona, po prostu wylądowałem z powrotem w oryginalnej, macierzystej powłoce ze wszystkimi ustawionymi zmiennymi . Teraz po prostu uruchom ponownie nową powłokę i możesz wrócić do pozyskiwania skryptu.
źródło
create_path=~/Desktop/site_builder/create.sh
w powłoce nadrzędnej, ponieważ robię to tak często. Potrzebuję go do wywołania source $ create_path [argument] w celu wykonania skryptu.export
. Ale to, co opisujesz, naprawdę ma bardzo niewielki sens. Brzmi coraz bardziej jak problem XY . Możesz opublikować nowe pytanie wyjaśniające, jaki jest twój cel końcowy. Założę się, że możemy dać ci lepsze rozwiązanie niż wszystkie te dziwne pozyskiwanie.