GNU/Linux >> Linux Esercitazione >  >> Linux

Perché una variabile è visibile in una subshell?

Il Learning Bash Book afferma che una subshell erediterà solo variabili di ambiente e descrittori di file, ecc., e che non erediterà variabili che non vengono esportate:

$ var=15
$ (echo $var)
15
$ ./file # this file include the same command echo $var

$

Come so, la shell creerà due subshell per () e per ./file , ma perché nel () case la subshell identifica il var variabile anche se non è esportata e nel ./file caso non l'ha identificato?

# Strace for () 
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25617
# Strace for ./file
clone(child_stack=0, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7f24558b1a10) = 25631

Ho provato a usare strace per capire come ciò avvenga e sorprendentemente ho scoperto che bash utilizzerà gli stessi argomenti per la chiamata di sistema clone, quindi questo significa che sia il processo biforcato in () e ./file dovrebbe avere lo stesso spazio degli indirizzi di processo del genitore, quindi perché in () case è la variabile visibile alla subshell e lo stesso non accade per il ./file caso, anche se gli stessi argomenti si basano sulla chiamata di sistema clone?

Risposta accettata:

Il libro Learning Bash è sbagliato. Le subshell ereditano tutte le variabili. Anche $$ (il PID della shell originale) viene mantenuto. Il motivo è che per una subshell, la shell si limita a eseguire il fork e non esegue una nuova shell (al contrario, quando si digita ./file , viene eseguito un nuovo comando, ad es. un nuovo guscio; nell'output di strace, guarda execve e simili). Quindi, in pratica, è solo una copia (con alcune differenze documentate).

Nota:questo non è specifico per bash; questo vale per qualsiasi shell.


Linux
  1. Perché l'utente mysql ha la shell bash in /etc/passwd?

  2. Perché find -exec mv {} ./target/ + non funziona?

  3. Aggiungi una riga al file /etc/hosts con lo script della shell

  4. Quando dovrei usare /dev/shm/ e quando dovrei usare /tmp/?

  5. I siti web dovrebbero vivere in /var/ o /usr/ in base all'utilizzo consigliato?

Perché /bin/sh punta a /bin/dash e non a /bin/bash??

Che cos'è Subshell in Linux?

/proc/cpuinfo e /proc/meminfo in Linux

Comprendere i file /proc/mounts, /etc/mtab e /proc/partitions

Cos'è un file .sh?

Perché sono necessari < o > per usare /dev/tcp