subshell no se crea si ejecuta commands sin una ruta de acceso?

Estoy leyendo el libro " Linux Command Line y Shell Scripting Bible " 3ª edición. En la página 279, aquí cito:

"La sustitución de commands crea lo que se llama una subshell para ejecutar el command incluido.Una subshell es una shell secundaria separada generada desde la shell que ejecuta la secuencia de commands.Por lo tanto, las variables que cree en la secuencia de commands no están disponibles para el command subshell.

También se crean subsets si ejecuta un command desde el símbolo del sistema utilizando la ruta ./ , pero no se crean si acaba de ejecutar el command sin una ruta de acceso. "

La última frase me confunde. He probado con un script simple que exporta algunas variables; las variables no durarían después de que la secuencia de commands existiera, sin embargo la secuencia de commands se invocará, desde ./ path, o poner el script en /usr/bin y ejecutarlo sin una ruta. Me parece que no hay ninguna diferencia en cómo se invocó con respecto a subshell.

¿Qué me perdí?

"La sustitución de commands crea lo que se llama una subshell para ejecutar el command incluido.Una subshell es una shell secundaria separada generada desde el shell que ejecuta la secuencia de commands.

Se trata de construcciones como:

 echo "$(date) `uname -r`" 

En este ejemplo estoy invocando dos subcapas utilizando las dos diferentes notas soportadas para subcapas. La primera subshell ejecuta el command date y la segunda subshell ejecuta el command uname . El command echo es ejecutado por el shell original después de que ambos subsets hayan finalizado.

Debido a ello, las variables que cree en el script no están disponibles para el command subshell.

Aquí el autor lo consiguió al revés. Las variables creadas antes de invocar el subshell están disponibles para el subshell. Las variables creadas dentro de la subshell sólo están disponibles para la subshell y desaparecerán una vez que la subshell termine.

También se crean subsets si ejecuta un command desde el símbolo del sistema utilizando la ruta ./, pero no se crean si acaba de ejecutar el command sin una ruta de acceso. "

Es muy poco claro lo que el autor está tratando de decir aquí. Si invoca un command externo, sucederá lo siguiente independientemente de si se invoca con o sin una ruta de acceso:

  • El shell fork s para crear un nuevo process.
  • El process hijo recién creado realiza cualquier networkingirección de E / S que pueda haber especificado.
  • El process secundario ejecve el command externo en cuyo punto los processs dejan de ser un shell y se convierte en lo que sea el progtwig externo. (Que, por supuesto, podría ser un script de shell).

Es un process nuevo, por lo que cualquier variable establecida por el command externo no estará disponible para el process padre como lo haría si hubiera sido una subshell.

El autor podría haberse referido a uno de los tres escenarios siguientes:

  • El command externo es un script de formatting incorrecto, en cuyo caso el shell de llamada puede estar trabajando alnetworkingedor del formatting incorrecto haciendo una conjetura acerca de qué shell utilizar para interpretar el script. (Este escenario es tan impnetworkingecible, que recomiendo encarecidamente no depender de él. La forma correcta de encontrar el intérprete es tener una línea #! Al principio del script.)
  • Puede estar invocando un command interno como read , que sintácticamente se parece a un command externo encontrado al search en el PATH . Pero a pesar de que sintácticamente se ve igual, se comportará de manera diferente. Dado que read establecerá una variable destinada a ser utilizada por los siguientes commands, read sí tiene que suceder en el process actual sin ninguna llamada de fork . (Incluso los commands internos que podrían ser invocados como subprocess de forma segura se hacen mejor en el process actual por razones de performance.
  • Puede estar utilizando commands de shell utilizando . file . file o . file source file . En este caso el file no es un script, pero es algo similar. Todos los commands del file serán invocados por el shell actual sin necesidad de llamar al fork . (Pero, por supuesto, los commands dentro del file podría desencadenar llamadas de fork ). En este caso cualquier #! la línea en el file se ignoraría y cualquier variable establecida por file estaría disponible para su shell actual.