En Advanced Bash-Scripting Guide , en ejemplo 27-4 , séptima línea desde la parte inferior, he leído esto:
Una función se ejecuta como un subproceso.
Hice una prueba en Bash y parece que la declaración anterior es incorrecta.
Búsquedas en este sitio, Bash Man y mi motor de búsqueda no aportan ninguna luz.
¿Tiene la respuesta y le gustaría explicar?
Comentarios
- Como se señaló, esa guía es extremadamente engañosa. En su lugar, recomiendo la Wooledge Bash Guide .
- Un hecho importante es que » Bash » evita crear subcapas. Son costosos, tienen su propio entorno y afectan el rendimiento del script y la forma en que fluye el código (muchas veces, de manera inconveniente, para lidiar con sus particularidades). El estado actual de Bash es producto de una evolución, una evolución del código. Quiero decir, la primera versión de Bash usa más subcapas *** que la actual. Este tipo de inconsistencia parece razonable. *** Si quieres una prueba, no puedo ‘ darte. Yo ‘ lo he derivado de páginas web, comentarios … Yo ‘ leí esa declaración en algún lugar hace algún tiempo.
Respuesta
La Guía avanzada de secuencias de comandos Bash no siempre es confiable y sus secuencias de comandos de ejemplo contienen prácticas desactualizadas como el uso de efectivamente desaprobado las comillas inversas para la sustitución de comandos, es decir, `command`
en lugar de $(command)
.
En este caso particular, es descaradamente incorrecto.
La sección sobre Funciones de Shell en el Bash (canónico) el manual definitivamente establece que
Las funciones de shell se ejecutan en el contexto de shell actual; no se crea ningún proceso nuevo para interpretarlos.
Comentarios
- » Advanced Bash-Scripting Guide generalmente no es confiable » Muy cierto.
- ¿Puede dar referencias para respaldar su primera oración?
- @WillVousden, ¿cómo se vería una referencia aquí? ¿Un montón de ejemplos de las deficiencias técnicas de la guía ‘? ¿Un documento en el que los expertos de la comunidad de bash han señalado previamente que no es confiable? ¿Ayudaría si un miembro de stackoverflow con una insignia dorada en bash estuviera de acuerdo en un comentario? : p
- @WillVousden No ‘ creo que lo que quieres existe en una forma confiable. Mendel Cooper ha actualizado y solucionado problemas con la guía en el pasado, pero no hay un rastreador de errores público o una lista de erratas. (Quizás esa sea la declaración más condenatoria que puedo hacer). Entonces, cuando encontramos un defecto (percibido o real), todo lo que podemos hacer es enviar un correo electrónico al autor y esperar lo mejor.
- @WillVousden, .. .si desea un historial de cuánto tiempo ha sido el consenso en el canal freenode #bash de que se debe evitar el ABS, consulte wooledge.org/ ~ greybot / meta / abs : el segundo campo de cada línea es la marca de tiempo y el primero es el nombre de usuario; ‘ espero que la afirmación de que los nombres de usuario en cuestión son personas muy respetadas sea suficiente.
Responder
Las funciones de llaves se ejecutarán dentro del proceso de shell de llamada, a menos que necesiten su propia subcapa que es:
- cuando las ejecuta en segundo plano con
&
- cuando los ejecuta como un enlace en una canalización
Redirecciones o env extra. las variables no forzarán una nueva subcapa:
hw(){ echo hello world from $BASHPID echo var=$var } var=42 hw >&2 echo $BASHPID #unexports var=42 and restores stdout here
Si define la función entre paréntesis en lugar de curlies:
hw()( echo hello world from $BASHPID ) hw echo $BASHPID
siempre se ejecutará en un nuevo proceso.
La sustitución de comandos $()
también siempre crea procesos en bash (pero no en ksh si ejecutas incorporados en su interior).
Comentarios
- No ‘ no sabía
f() (...)
está permitido. ¿Hay otras definiciones además de{...}
y(...)
? En Bash, I ‘ todavía no estoy interesado en otros. - @tomas Puede usar la sintaxis
function hw { echo hello world; }
(no es necesario()
si escribefunction
y puede especificar redireccionamientos justo después del}
o)
como enhw(){ echo error; } >&2
. Eso ‘ s al respecto. - Esto es la respuesta en la que pensé inmediatamente, y es absolutamente correcta.Debería votarse como la respuesta correcta.
f()(...)
siempre ejecuta un shell propio, mientras quef(){...}
no lo hace. - NB Las funciones bash aceptan cualquier comando compuesto, por lo que
foo() [[ x = x ]]
también es una definición de función válida. Sin embargo, si miras la función contype foo
, ‘ verás que esto sigue siendo azúcar sintáctico parafoo() { [[ x = x ]]; }
. Lo mismo ocurre con las funciones de subshell:bar() ( : )
se convierte enbar() { ( : ); }
. - @kojiro nice +1. ‘ no sabía eso
Responder
El comando en La pregunta de ese ejemplo se ve así:
echo ${arrayZ[@]/%e/$(replacement)}
El ejemplo posterior dice:
# $( ... ) is command substitution. # A function runs as a sub-process.
Siendo caritativo con ABS Guide, lo que aparentemente querían escribir es que la función se ejecuta dentro de una sustitución de comando y el comando dentro de una sustitución de comando se ejecuta en una subshell .
Comentarios
- Eso ‘ es muy engañoso. Gracias por su interpretación.
- @tomas » muy engañoso. » Sí, muy. A diferencia de la Guía de ABS, Greg ‘ s Wiki es una excelente fuente de información avanzada de bash.
- Saludos. ¿Cuál ‘ es tu opinión sobre este: wiki.bash-hackers.org/start ?
- @tomas No tengo conocimiento de primera mano de eso.
- @tomas, … mi propia opinión sobre el wiki de bash-hackers es que ‘ es una fuente excelente. Yo ‘ no lo he revisado tan exhaustivamente como la wiki de Wooledge, pero tiende a ser preciso y escrito con precisión.