Puncte:0

Rulați o comandă în fundal, dar obțineți un cod de ieșire diferit de zero *imediat* când `Nu există un astfel de fișier sau director`

drapel cn

Trebuie să rulez o comandă (necunoscută) în fundal, astfel:

nohup some_command &

Deoarece o astfel de comandă va rula și (sper că) se va finaliza în fundal, nu pot obține imediat starea ei de ieșire; asta este în ordine.

Cu toate acestea, trebuie să obțin o stare de ieșire „eroare”. imediat în cazul în care unele_comandă nu este găsit (adică atunci când mesajul de eroare de la bash este Nu există un astfel de fișier sau director sau comanda nu a fost găsită).

Care pot fi cele mai scurte și simple alternative pe care le pot folosi?


Câteva informații de fundal pentru întrebările puse în comentarii: Acesta este un program GUI „frontend” care interacționează cu utilizatorul. Utilizatorul introduce o comandă (de exemplu, gedit some_file) și programul meu GUI execută această comandă și revine imediat la o buclă pentru a accepta următoarea comandă de la utilizator. Deci, comanda introdusă ar trebui să ruleze „detașat” din programul GUI. Cu toate acestea, dacă utilizatorul introduce o comandă greșită (de exemplu, geditxyz) Doresc să avertizez imediat utilizatorul că comanda nu este găsită.

drapel ar
Trebuie să folosiți atât `nohup` la început, cât și `&` la sfârșit? Va funcționa dacă folosești una sau alta?
raj avatar
drapel cn
raj
Prin „obține” starea de ieșire, vrei să spui să-l obții în mod programatic (pentru a-l folosi mai târziu într-un script) sau doar să îl afișezi pe terminal? Pentru că în al doilea caz, bash o face de la sine dacă setați `set -b`. Încercați să tastați `nohup inexistent &` și veți obține imediat rezultatul ca `[1]+ Exit 127 nohup nonexistent`.
Puncte:3
drapel cn

Deoarece o astfel de comandă va rula și (sperăm că) se va finaliza în fundal, nu pot obține starea ei de ieșire; asta este în ordine.

Această afirmație este incorectă pentru început:

#!/bin/bash
unele_comandă &
pid="$!"
așteptați -n „$pid”
echo "Starea a fost ${?}."

Dacă doriți să fiți notificat imediat, puteți folosi câteva trucuri bazate pe semnal.

Manipularea de SIGCHLD ar fi cea mai evidentă opțiune, dar (1) suportul său în Bash este buggy și (2) în ciuda set -b, capcană handlerii vor aștepta de fapt limitele de comandă.

Acestea fiind spuse, următoarea cea mai bună opțiune (care întrerupe, de asemenea, procesarea în prim-plan de lungă durată imediat când unele_comandă fails) este (un echivalent al) generarea unui Ctrl+C pentru întregul grup de procese. Acesta este livrat și acționat imediat, shell-ul în sine poate gestiona semnalul și poate continua, dacă se dorește, în timp ce procesul din prim-plan va ieși, probabil, implicit etc.

#!/bin/bash
set -e

handler() {
  echo „eșecul comenzii semnalat”
  capcană - INT
}
manevrător de capcane INT

fundal() {
  local -ir pid="$1"
  schimb
  „$@” || kill -INT -- -"$pid"
}
fundal „$$” some_command &

# sarcină în prim-plan de lungă durată
ecou „înainte de procesare lungă”
dormi 5 || ecou „procesare lungă întreruptă”
ecou „după procesare lungă”

Încercați să înlocuiți unele_comandă cu (de ex.) dormi 2 pentru a testa cazul „de succes”.

FedKad avatar
drapel cn
Multumesc pentru raspuns. Este foarte aproape de ceea ce am nevoie, dar totuși „oarecum complex”. De asemenea, am clarificat afirmația mea anterioară adăugând cuvântul **imediat**.

Postează un răspuns

Majoritatea oamenilor nu înțeleg că a pune multe întrebări deblochează învățarea și îmbunătățește legătura interpersonală. În studiile lui Alison, de exemplu, deși oamenii își puteau aminti cu exactitate câte întrebări au fost puse în conversațiile lor, ei nu au intuit legătura dintre întrebări și apreciere. În patru studii, în care participanții au fost implicați în conversații ei înșiși sau au citit transcrieri ale conversațiilor altora, oamenii au avut tendința să nu realizeze că întrebarea ar influența – sau ar fi influențat – nivelul de prietenie dintre conversatori.