2011-05-08 10 views
6

shell actual esWill() construir siempre iniciar una subshell?

$ echo $$ 
23173 

Nota a los padres de ps es shell actual

$ (ps -o pid,ppid,cmd) 
    PID PPID CMD 
8952 23173 ps -o pid,ppid,cmd 
23173 23169 bash 

Pero aquí, el padre del PS es el subnivel (bash)

$ (echo hello ; ps -o pid,ppid,cmd) 
hello 
    PID PPID CMD 
8953 23173 bash 
8954 8953 ps -o pid,ppid,cmd 
23173 23169 bash 

Es fiesta haciendo optimizaciones? ¿Cómo es que un eco extra marcó la diferencia y generó una subcapa en el tercer caso?

+1

Sugerencia: puede usar 'ps -H' para obtener un árbol de procesos que lo aclare un poco más para ver qué sucede, sin tener que conectar PID y PPID usted mismo. (Sin embargo, eso no cambia la pregunta subyacente, simplemente hace que sea un poco más fácil de ver). –

+1

Para hacer un mejor análisis, prefiera $ BASHPID sobre $$ – sehe

+0

Tenga en cuenta que si desea agrupar sin una subcadena, use '{corchetes ; } ' Sin embargo, requieren un poco de sintaxis adicional (espacio en blanco, punto y coma). –

Respuesta

6

Sí, lo que está viendo es una optimización. Técnicamente, la construcción (…) siempre inicia una subcadena, por definición. La mayoría de las veces, la subshell se ejecuta en un subproceso separado. Esto garantiza que todo lo hecho en la subshell permanezca en la subshell. Si bash puede garantizar esta propiedad de aislamiento, es libre de usar cualquier técnica de implementación que quiera.

En el fragmento (ps -o pid,ppid,cmd), es obvio que nada puede influir en el shell primario, por lo que hay una optimización en bash que hace que no se bifurque un proceso separado para la subshell. El fragmento (echo hello ; ps -o pid,ppid,cmd) es demasiado complejo para que el optimizador reconozca que no se necesita ninguna subcapa.

Si experimenta con ksh, notará que su optimizador es más agresivo. Por ejemplo, tampoco bifurca un subproceso para (echo hello ; ps -o pid,ppid,cmd).

+0

¿Tiene un enlace en el código bash impl de cómo el optimizador decide renunciar? Veo un comportamiento similar [sin la] (https://unix.stackexchange.com/q/401020/212862) '(...)' sintaxis. También [con el] (https://stackoverflow.com/q/46860926/5771861) '{...; } 'sintaxis. Algunas veces se puede evitar la subshell intermedia, pero cuando eso ocurre exactamente me parece que la implementación depende de mí. Alternativamente, ¿el comportamiento de optimización está oficialmente documentado? –

+0

@Hakan Mire el código fuente. No está documentado y varía de una versión a otra. – Gilles

1

Una subshell que consiste en un único comando simple en lugar de una lista o canalización de más de un comando podría implementarse simplemente "ejecutando" el comando, es decir, reemplazando la subshell con el proceso para el comando llamado. Si la subshell es más compleja que un simple ejecutivo no es posible, la subshell debe permanecer para administrar la secuencia de comandos.

De su diagnóstico es imposible diferenciar entre una optimización de bash donde una subcapa que consiste en un comando simple está optimizada para una bifurcación "directa" y ejecutiva del comando llamado o una bifurcación de una subshell seguida de un ejecutivo de el comando llamado. Esto no es sorprendente ya que la diferencia es (¿casi?) Completamente académica.

Cuestiones relacionadas