Le funzioni vengono eseguite come sottoprocessi in Bash?

In Advanced Bash-Scripting Guide , in esempio 27-4 , settima riga dal basso, ho letto questo:

Una funzione viene eseguita come un sottoprocesso.

Ho fatto un test in Bash e sembra che laffermazione precedente sia sbagliata.

Ricerche su questo sito, Bash Man e il mio motore di ricerca non portano luce.

Hai la risposta e vorresti spiegarla?

Commenti

  • Come notato, quella guida è estremamente fuorviante. Consiglio invece la Wooledge Bash Guide .
  • Un fatto importante è che ” Bash ” evita di creare subshell. Sono costosi, hanno il tuo ambiente e quelli influenzano le prestazioni dello script e il modo in cui scorre il codice (molte volte, inconvenientemente, per gestire le loro particolarità). Lo stato attuale di Bash è il prodotto di unevoluzione, unevoluzione del codice. Voglio dire, la prima versione di Bash usa più subshell *** di quella attuale. Questo tipo di incoerenza sembra essere ragionevole. *** se vuoi una prova, non posso ‘ dartela. ‘ lho derivata da pagine web, commenti … ‘ ho letto quella dichiarazione qualche tempo fa.

Risposta

La Guida avanzata di scripting di Bash non è sempre affidabile e i suoi script di esempio contengono pratiche obsolete come luso del ha effettivamente ritirato i backtick per la sostituzione dei comandi, ovvero `command` anziché $(command).

In questo caso particolare, è palesemente errato.

La sezione sulle Funzioni della shell nel Bash (canonico) il manuale afferma definitivamente che

Le funzioni della shell vengono eseguite nel contesto della shell corrente; non viene creato alcun nuovo processo per interpretarli.

Commenti

  • ” Advanced Bash-Scripting Guide è generalmente inaffidabile ” Molto vero.
  • Puoi fornire riferimenti per supportare il tuo prima frase?
  • @WillVousden come sarebbe un riferimento qui? Alcuni esempi delle carenze tecniche della ‘? Un documento in cui gli esperti della comunità bash hanno precedentemente notato che è inaffidabile? Sarebbe utile se un membro di stackoverflow con un badge doro in bash fosse daccordo in un commento? : p
  • @WillVousden Non ‘ penso che quello che vuoi esista in una forma affidabile. Mendel Cooper ha aggiornato e risolto problemi con la guida in passato, ma non esiste un bug tracker pubblico o un elenco di errata. (Forse questa è laffermazione più dannosa che posso fare.) Quindi, quando troviamo un difetto (percepito o reale) tutto ciò che possiamo fare è inviare une-mail allautore e sperare per il meglio.
  • @WillVousden, .. .se vuoi una cronologia di quanto tempo il consenso nel canale freenode #bash è stato che lABS dovrebbe essere evitato, vedi wooledge.org/ ~ greybot / meta / abs – il secondo campo in ogni riga è il timestamp e il primo è il nome utente; ‘ mi auguro che laffermazione che i nomi utente in questione siano persone molto rispettate sia sufficiente.

Risposta

Le funzioni parentesi graffe verranno eseguite allinterno del processo della shell chiamante, a meno che non necessitino della propria subshell che è:

  • quando vengono eseguite in background con &
  • quando li esegui come collegamento in una pipeline

Reindirizzamenti o env extra. le variabili non forzeranno una nuova sottoshell:

hw(){ echo hello world from $BASHPID echo var=$var } var=42 hw >&2 echo $BASHPID #unexports var=42 and restores stdout here 

Se definisci la funzione con parentesi invece di curve:

hw()( echo hello world from $BASHPID ) hw echo $BASHPID 

verrà sempre eseguito in un nuovo processo.

Sostituzione del comando $() crea sempre processi in bash (ma non in ksh se esegui dei comandi incorporati al suo interno).

Commenti

  • Non ‘ sapevo f() (...) è consentito. Esistono altre definizioni oltre a {...} e (...)? In Bash, I ‘ non mi piacciono ancora gli altri.
  • @tomas Puoi utilizzare la sintassi function hw { echo hello world; } (non è necessario () se digiti function e puoi specificare i reindirizzamenti subito dopo il } o ) come in hw(){ echo error; } >&2. Questo è ‘.
  • Questo è la risposta a cui ho pensato subito, ed è assolutamente corretta.Dovrebbe essere votata come risposta corretta. f()(...) esegue sempre una propria shell, mentre f(){...} no.
  • NB le funzioni bash accettano qualsiasi comando composto, quindi foo() [[ x = x ]] è anche una definizione di funzione valida. Tuttavia, se guardi la funzione con type foo ‘ vedrai che questo è ancora zucchero sintattico per foo() { [[ x = x ]]; }. Lo stesso vale per le funzioni subshell: bar() ( : ) diventa bar() { ( : ); }.
  • @kojiro nice +1. ‘ non sapevo che

Rispondi

Il comando in la domanda di quellesempio è simile a:

echo ${arrayZ[@]/%e/$(replacement)} 

Lesempio successivo afferma:

# $( ... ) is command substitution. # A function runs as a sub-process. 

Essendo caritatevoli con ABS Guide, ciò che apparentemente intendevano scrivere è che la funzione viene eseguita allinterno di una sostituzione di comando e il comando allinterno di una sostituzione di comando viene eseguita in una subshell .

Commenti

  • Questo ‘ è molto fuorviante. Grazie per la tua interpretazione.
  • @tomas ” molto fuorviante. ” Sì, molto. A differenza della Guida ABS, Greg ‘ s Wiki è unottima fonte di informazioni bash avanzate.
  • Saluti. Qual è la tua ‘ opinione su questo: wiki.bash-hackers.org/start ?
  • @tomas Non ne ho una conoscenza di prima mano.
  • @tomas, … la mia opinione sul wiki di bash-hackers è che ‘ è unottima fonte. Non ‘ lho esaminato in modo completo come il wiki di Wooledge, ma tende ad essere accurato e scritto con precisione.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *