Capítulo 4. Ejecutar comandos
Este trabajo se ha traducido utilizando IA. Agradecemos tus opiniones y comentarios: translation-feedback@oreilly.com
El objetivo principal de bash (o de cualquier shell) es permitirte interactuar con el sistema operativo del ordenador para que puedas realizar lo que necesites. Normalmente eso implica ejecutar programas, por lo que el intérprete de comandos toma los comandos que escribes, determina a partir de esa entrada qué programas deben ejecutarse y los ejecuta por ti.
Echemos un vistazo al mecanismo básico de lanzamiento de trabajos y exploremos algunas de las funciones que ofrece bash para lanzar programas en primer o segundo plano, secuencialmente o en paralelo, indicar si han tenido éxito, etc.
4.1 Ejecutar cualquier ejecutable
Problema
Necesitas ejecutar un comando en un sistema Linux o Unix.
Solución
Utiliza bash y escribe el nombre del comando en la línea de comandos:
$
someprog
Debate
Esto parece bastante sencillo, y en cierto modo lo es, pero pasan muchas cosas entre bastidores que nunca ves. Lo que es importante entender sobre bash es que su funcionamiento básico es cargar y ejecutar programas. Todo lo demás es sólo escaparate para prepararse para ejecutar programas. Claro, hay variables de shell y sentencias de control para hacer bucles y if/then/else
bifurcación, y hay formas de controlar la entrada y la salida, pero todo esto es la guinda del pastel de la ejecución de programas.
Entonces, ¿de dónde saca el programa para ejecutarlo?
bash utiliza una variable del shell llamada $PATH
para localizar tu ejecutable. La variable $PATH
es una lista de directorios. Los directorios están separados por dos puntos (:). bash busca en cada uno de esos directorios un archivo con el nombre que hayas especificado. El orden de los directorios es importante: bash mira el orden en que aparecen los directorios en la variable y toma el primer ejecutable encontrado:
$ echo $PATH /bin:/usr/bin:/usr/local/bin:. $
En la variable $PATH
que se muestra aquí, se incluyen cuatro directorios. El último directorio de la lista es un único punto (llamado directorio punto, o simplemente punto), que representa el directorio actual en un sistema de archivos Linux o Unix: estés donde estés, ése es el directorio al que se refiere punto. Por ejemplo, cuando copias un archivo de algún lugar a punto (es decir, cp /other/place/file .
), estás copiando el archivo en el directorio actual. Incluir el directorio punto en tu ruta le dice a bash que busque comandos no sólo en esos otros directorios, sino también en el directorio actual (.).
Mucha gente opina que poner dot en $PATH
es un riesgo de seguridad demasiado grande: alguien podría engañarte y hacer que ejecutaras su propia versión maliciosa de un comando (por ejemplo, ls) en lugar de la que esperabas. Si el punto figurara en primer lugar, la versión de ls de otra persona sustituiría al comando ls normal, y podrías ejecutar ese comando sin saberlo. ¿No nos crees? Prueba con esto:
$ bash $ cd $ touch ls $ chmod 755 ls $ PATH=".:$PATH" $ ls $
De repente, parece que el ls no funciona en tu directorio personal. No obtienes ninguna salida. Si vas a otra ubicación (por ejemplo, cd /tmp
), ls funcionará, pero no en tu directorio personal. ¿Por qué? Porque en ese directorio hay un archivo vacío llamado ls que se ejecuta (y no hace nada: está vacío) en lugar del comando ls normal ubicado en /bin/ls. Como hemos empezado este ejemplo ejecutando una nueva copia de bash, puedes salir de este lío saliendo de esta subshell, pero quizá quieras eliminar primero el falso comando ls:
$ cd $ rm ls $ exit $
¿Puedes ver el peligro potencial de entrar en un directorio extraño con tu $PATH
configurado para buscar en el directorio de puntos antes que en cualquier otro sitio?
Si pones el punto como último directorio en tu variable $PATH
, al menos no te engañarán tan fácilmente. Por supuesto, si lo omites por completo, podría decirse que es incluso más seguro, y aún puedes ejecutar comandos en tu directorio local escribiendo un punto inicial y un carácter de barra oblicua, como en:
./myscript
La elección es tuya.
Advertencia
Nunca permitas directorios puntuales o con permisos de escritura en el $PATH
de root. Para más información sobre este tema, consulta la Receta 14.9 y la Receta 14.10.
No olvides establecer permisos de ejecución en el archivo antes de invocar tu script:
chmod +x myscript
Sólo tienes que establecer los permisos una vez. A partir de entonces, puedes invocar el script como un comando.
Una práctica habitual entre algunos usuarios de bash es crear un directorio bin personal, análogo a los directorios del sistema /bin y /usr/bin donde se guardan los ejecutables. En tu bin personal (si lo creas en tu directorio personal, su ruta es ~/bin) puedes poner copias de tus shell scripts favoritos y otros comandos personalizados o privados. Luego añade ese directorio a tu $PATH
, incluso al principio (PATH=~/bin:$PATH
). De este modo, podrás seguir teniendo tus favoritos personalizados sin el riesgo de seguridad que supone ejecutar comandos de desconocidos.
Ver también
-
Enel Capítulo 16 encontrarás más información sobre cómo personalizar tu entorno
-
Receta 14.9, "Encontrar directorios escribibles en el mundo en tu $PATH"
-
Receta 16.11, "Mantener un alijo privado de utilidades añadiendo ~/bin"
4.2 Ejecutar varios comandos en secuencia
Solución
Hay tres soluciones a este problema, aunque la primera es bastante trivial: simplemente sigue escribiendo. Un sistema Linux o Unix es lo suficientemente avanzado como para permitirte teclear mientras trabaja en tus órdenes anteriores, así que puedes simplemente seguir tecleando una orden tras otra.
Otra solución bastante sencilla es escribir esos comandos en un archivo y luego decirle a bash que ejecute los comandos del archivo, es decir, un simple script de shell. Por ejemplo, supongamos que queremos ejecutar tres comandos, largo, medio y corto, cada uno de cuyos tiempos de ejecución se refleja en su nombre. Necesitamos ejecutarlos en ese orden, pero no queremos esperar a que termine el script largo antes de teclear los otros comandos. Podríamos utilizar un script de shell (también conocido como archivo por lotes). Aquí tienes una forma primitiva de hacerlo:
$ cat > simple.script long medium short ^D # Ctrl-D, not visible $ bash ./simple.script
La tercera solución, y posiblemente la mejor, es ejecutar cada comando en secuencia. Si quieres ejecutar cada programa independientemente de que fallen los anteriores, sepáralos con punto y coma:
long ; medium ; short
Si sólo quieres ejecutar el siguiente programa si el programa precedente funcionó, y todos los programas establecen correctamente los códigos de salida, sepáralos con dobles ampersands:
long && medium && short
Debate
El ejemplo de cat era sólo una forma muy primitiva de introducir texto en un archivo: redirigimos la salida del comando al archivo llamado simple.script (para saber más sobre cómo redirigir la salida, consulta el Capítulo 2). Es mejor que utilices un editor real, pero estas cosas son más difíciles de mostrar en ejemplos como éste. A partir de ahora, cuando queramos mostrar un script, nos limitaremos a mostrar el texto como texto incorpóreo no en una línea de comandos, o bien iniciaremos el ejemplo con un comando como cat filename
para volcar el contenido del archivo a la pantalla (en lugar de redirigir la salida de nuestra escritura al archivo), y así mostrarlo en el ejemplo.
El objetivo principal de esta sencilla solución es demostrar que se puede poner más de un comando en la línea de comandos bash. En el primer caso, el segundo comando no se ejecuta hasta que sale el primero, el tercero no se ejecuta hasta que sale el segundo, y así sucesivamente, para tantos comandos como tengas en la línea. En el segundo caso, el segundo comando no se ejecuta a menos que el primero tenga éxito, el tercero no se ejecuta a menos que el segundo tenga éxito, y así sucesivamente, para tantos comandos como tengas en la línea.
Ver también
-
Capítulo 2 sobre redirigir la salida
4.3 Ejecutar varios comandos a la vez
Problema
Necesitas ejecutar tres comandos, pero son independientes entre sí y no necesitan esperar a que se completen los anteriores.
Solución
Puedes ejecutar un comando en segundo plano poniendo un ampersand (&
) al final de la línea de comandos. Así, podrías disparar los tres comandos en rápida sucesión de la siguiente manera:
$ long & [1] 4592 $ medium & [2] 4593 $ short $
O mejor aún, puedes hacerlo todo en una sola línea de comandos:
$ long & medium & short [1] 4592 [2] 4593 $
Debate
Cuando ejecutamos un comando "en segundo plano" (realmente no existe tal lugar en Linux), todo lo que eso significa en realidad es que desconectamos la entrada de teclado del comando y el shell no espera a que el comando se complete antes de dar otro prompt y aceptar más entrada de comando. La salida del comando (a menos que tomemos medidas explícitas para cambiar este comportamiento) seguirá llegando a la pantalla, por lo que en este ejemplo los tres comandos estarán intercalando salida en la pantalla.
Los bits impares de la salida numérica son el número de trabajo entre corchetes, seguido del ID del proceso del comando que acabamos de iniciar en segundo plano. En nuestro ejemplo, el trabajo 1 (proceso 4592) es el comando largo, y el trabajo 2 (proceso 4593) es el medio.
No pusimos short en segundo plano porque no pusimos un ampersand al final de la línea, así que bash esperará a que se complete antes de darnos el prompt del shell (el $
).
El número de trabajo o ID de proceso se puede utilizar para proporcionar un control limitado sobre un trabajo. Por ejemplo, podríamos matar el trabajo largo con kill %1
(ya que su número de trabajo era 1
), o podríamos especificar el número de proceso (es decir, kill 4592
) con los mismos resultados mortales.
También puedes utilizar el número de trabajo para volver a conectarte a un trabajo en segundo plano. Por ejemplo, podríamos volver a conectar el trabajo largo al primer plano de con fg %1
. Si sólo tienes un trabajo ejecutándose en segundo plano, ni siquiera necesitas el número de trabajo; basta con utilizar fg
por sí mismo.
Consejo
Si ejecutas un comando y luego te das cuenta de que tardará en completarse más de lo que pensabas, puedes pausarlo utilizando Ctrl-Z, que te devolverá a un prompt. Entonces puedes escribir bg
para desbloquear el trabajo y continuar ejecutándolo en segundo plano. Esto es básicamente añadir un &
a posteriori.
4.4 Decir si una orden ha tenido éxito o no
Debate
El estado de salida de un comando se guarda en la variable del shell referenciada con $?
. Su valor puede oscilar entre 0 y 255. Cuando escribas un script de shell, es una buena idea que tu script salga con cero si todo va bien y con un valor distinto de cero si se encuentra una condición de error. Recomendamos utilizar sólo de 0 a 127 porque el shell utiliza 128+N para denotar la muerte por la señal N. Además, si utilizas un número mayor que 255 o menor que 0, los números se envolverán. Devuelve un estado de salida con la sentencia exit
(por ejemplo, exit 1
o exit 0
). Pero ten en cuenta que sólo tienes una oportunidad de leer el estado de salida de un comando:
$ badcommand # it fails... $ echo $? 1 $ echo $? 0 $
¿Por qué el segundo echo nos da como resultado 0
? En realidad está informando sobre el estado del comando eco inmediatamente anterior. La primera vez que tecleamos echo $?
nos devolvió un 1
, que era el valor de retorno de badcommand. Pero el propio comando eco tiene éxito y, por tanto, el nuevo estado más reciente es éxito (es decir, un valor 0
). Como sólo tienes una oportunidad de comprobar el estado de salida, muchos scripts de shell asignarán inmediatamente el estado a otra variable del shell, como en:
$ badcommand # it fails... $ STAT=$? $ echo $STAT 1 $ echo $STAT 1 $
Podemos guardar el valor en la variable $STAT
y comprobar su valor más adelante.
Aunque estamos mostrando esto en ejemplos de línea de comandos, el uso real de variables como $?
se produce al escribir guiones. Normalmente puedes ver si un comando ha funcionado o no si estás viendo cómo se ejecuta en tu pantalla. Pero en un script, los comandos pueden estar ejecutándose sin supervisión.
Una de las grandes características de bash es que el lenguaje de programación es idéntico a los comandos que escribes en una ventana de terminal. Esto hace que sea mucho más fácil comprobar la sintaxis y la lógica mientras escribes tus guiones.
El estado de salida es más suele utilizarse en los scripts, y a menudo en las sentencias if
, para realizar diferentes acciones en función del éxito o el fracaso de un comando. Aquí tienes un ejemplo sencillo por ahora, pero volveremos sobre este tema en futuras recetas:
somecommand ... if (( $? )) ; then echo failed ; else echo OK; fi
(( ))
evalúa una expresión aritmética; consulta las Recetas 6.1 y 6.2.
Tampoco recomendamos utilizar números negativos. El intérprete de comandos los aceptará sin error, pero no hará lo que esperas:
$ bash -c 'exit -2' ; echo $? 254 $ bash -c 'exit -200' ; echo $? 56
4.5 Ejecutar un comando sólo si otro comando ha tenido éxito
Problema
Necesitas ejecutar algunos comandos, pero sólo quieres ejecutar ciertos comandos si otros tienen éxito. Por ejemplo, te gustaría cambiar de directorio (mediante el comando cd ) a un directorio temporal y eliminar todos los archivos. Sin embargo, no quieres eliminar ningún archivo si cd falla (por ejemplo, si los permisos no te permiten entrar en el directorio, o si escribes mal el nombre del directorio).
Solución
Puedes utilizar el estado de salida ($?
) del comando cd en combinación con una sentencia if
para hacer el rm sólo si el cd tuvo éxito:
cd mytmp if (( $? == 0 )); then rm * ; fi
Consejo
Una forma mejor de escribirlo es la siguiente, pero creemos que es más claro mostrarlo y explicarlo como lo hemos hecho:
if cd mytmp; then rm * ; fi
Debate
Obviamente, no necesitarías hacer esto si estuvieras escribiendo los comandos a mano. Verías cualquier mensaje de error del comando cd y, por tanto, no escribirías el comando rm. Pero el scripting es otra cosa, y esta prueba merece mucho la pena hacerla en un script como el de nuestro ejemplo para asegurarte de que no borras accidentalmente todos los archivos del directorio donde lo estás ejecutando.
Supongamos que ejecutas ese script desde el directorio equivocado, uno que no tenga un subdirectorio llamado mytmp. El cd fallaría, por lo que el directorio actual permanecería sin cambios. Sin la comprobación de if
(por haber fallado el cd ) el script simplemente continuaría con la siguiente sentencia. Ejecutar el rm *
eliminaría todos los archivos de tu directorio actual. Ouch. El if
merece la pena.
Entonces, ¿cómo obtiene $?
su valor? Es el código de salida del comando (ver Receta 4.4). Los programadores en lenguaje C lo reconocerán como el valor del argumento suministrado a la función exit()
; por ejemplo, exit(4);
devolvería un 4
. Para el intérprete de comandos, un código de salida de cero se considera éxito y un valor distinto de cero significa fracaso.
Si escribes scripts bash, deberás asegurarte de establecer explícitamente los valores de retorno, para que $?
se establezca correctamente desde tu script. Si no lo haces, el valor establecido será el valor del último comando ejecutado, que puede que no quieras como resultado.
4.6 Utilizar menos sentencias if
Problema
Como programador concienzudo, te tomaste muy a pecho lo que describimos en la receta anterior. Aplicaste el concepto a tu último script de shell, pero ahora te encuentras con que el script de shell es ilegible, con todas esas sentencias if
comprobando el código de retorno de cada comando. ¿No existe una alternativa?
Debate
Al separar dos comandos mediante el doble ampersands, se le indica a bash que ejecute el primer comando y que ejecute el segundo sólo si el primero tiene éxito (es decir, si su estado de salida es 0). Esto es muy parecido a utilizar una sentencia if
para comprobar el estado de salida del primer comando con el fin de proteger la ejecución del segundo comando:
cd
mytmpif
((
$?
==
0
))
;
then
rm *;
fi
La sintaxis doble-ampersand pretende recordar al operador lógico AND del lenguaje C. Si conoces la lógica (y el lenguaje C), recordarás que si evalúas la expresión lógica A AND B
, la expresión completa sólo puede ser verdadera si tanto la (sub)expresión A
como la (sub)expresión B
se evalúan como verdaderas. Si cualquiera de ellas es falsa, toda la expresión es falsa. El lenguaje C hace uso de este hecho, y cuando codifiques una expresión como if (A && B) { ... }
, evaluará primero la expresión A
. Si es falsa, ni siquiera se molestará en evaluar B
ya que el resultado global (falso) ya ha sido determinado (por ser A
falso).
¿Qué tiene que ver esto con bash? Bueno, si el estado de salida del primer comando (el que está a la izquierda de &&
) es distinto de cero (es decir, ha fallado), no se molestará en evaluar la segunda expresión: no ejecutará el otro comando.
Si quieres ser minucioso en la comprobación de errores, pero no quieres que las sentencias if
estén por todas partes, puedes hacer que bash salga cada vez que encuentre un fallo (es decir, un estado de salida distinto de cero) de cada comando de tu script (excepto en los bucles while
y en las sentencias if
, donde ya está capturando y utilizando el estado de salida) estableciendo en la bandera -e
:
set
-ecd
mytmp rm *
Si activas la bandera -e
, el shell saldrá cuando falle un comando. Si el cd de este ejemplo falla, el script saldrá y ni siquiera intentará ejecutar el comando rm *
. Sin embargo, no recomendamos hacer esto en un intérprete de comandos interactivo, porque cuando el intérprete de comandos salga hará que tu ventana del intérprete de comandos desaparezca.
Ver también
-
Enla receta 4.8, "Visualización de mensajes de error cuando se producen fallos", encontrarás una explicación de la sintaxis
||
, que es similar en algunos aspectos a la construcción&&
, pero también bastante diferente.
4.7 Ejecutar trabajos largos sin supervisión
Problema
Ejecutaste un trabajo en segundo plano, luego saliste del intérprete de comandos y te fuiste a tomar un café. Cuando volviste a para comprobarlo, el trabajo ya no se estaba ejecutando y no se había completado. De hecho, tu trabajo no había avanzado mucho. Parece haberse detenido en cuanto saliste del intérprete de comandos.
Debate
Cuando pones un trabajo en segundo plano (a través de &
, como se describe en la Receta 4.3), sigue siendo un proceso hijo del intérprete de comandos bash. Cuando sales de una instancia del intérprete de comandos, bash envía una señal de suspensión (hup) a todos sus procesos hijos. Por eso tu trabajo no se ejecutó durante mucho tiempo. En cuanto saliste de bash, mató tu trabajo en segundo plano. (Oye, te ibas; ¿cómo iba a saberlo?)
El comando nohup simplemente configura el proceso hijo para que ignore las señales de colgado. Todavía puedes matar el trabajo con el comando kill, porque kill envía una señal SIGTERM
, no una señal SIGHUP
. Pero con nohup, bash no matará inadvertidamente tu trabajo cuando salgas.
El mensaje que da nohup sobre la adición de tu salida no es más que nohup intentando ser útil. Dado que es probable que salgas del intérprete de comandos después de emitir un comando nohup, es probable que tu destino de salida desaparezca; es decir, la sesión bash de tu terminal dejará de estar activa, por lo que el trabajo no podrá escribir en STDOUT. Y lo que es más importante, escribir en un destino inexistente provocaría un fallo. Así que nohup redirige la salida por ti, añadiéndola (no sobrescribiéndola, sino añadiéndola al final) a un archivo llamado nohup. out en el directorio actual. Puedes redirigir explícitamente la salida a otro lugar en la línea de comandos, y nohup es lo suficientemente inteligente como para detectar que esto ha ocurrido y no utilizar nohup.out para tu salida.
Ver también
-
Capítulo 2 para varias recetas sobre cómo redirigir la salida, ya que probablemente quieras hacerlo para un trabajo en segundo plano.
-
Receta 10.1, ""Daemonizar" tu script" para saber más sobre la ejecución desatendida de tu script
-
Receta 17.4, "Recuperar sesiones desconectadas utilizando la pantalla"
4.8 Mostrar mensajes de error cuando se producen fallos
Debate
De forma similar a como el &&
de la Receta 4.6 le dice a bash que no se moleste en evaluar la segunda expresión si la primera es falsa, el ||
le dice al intérprete de comandos que no se moleste en evaluar la segunda expresión si la primera es verdadera (es decir, tiene éxito). Al igual que &&
, la sintaxis de ||
se remonta a la lógica y al lenguaje C, donde el resultado se determina (como verdadero) si la primera expresión de A OR B
se evalúa como verdadera, por lo que no es necesario evaluar la segunda expresión. En bash, si la primera expresión devuelve 0 (es decir, tiene éxito), sigue adelante. Sólo si la primera expresión devuelve un valor distinto de cero (es decir, si el valor de salida del comando indica un fallo) debe evaluar la segunda parte y, por tanto, ejecutar el otro comando.
Advertencia: no te dejes engañar por esto:
cmd||
printf
"%b"
"FAILED.\n"
;
exit
1
¡La salida se ejecutará en cualquiera de los dos casos! El OR sólo está entre los dos primeros comandos. Si queremos que la salida sólo se produzca en caso de error, tenemos que agruparla con el printf para que ambos se consideren una unidad. La sintaxis deseada sería
cmd||
{
printf
"%b"
"FAILED.\n"
;
exit
1
;
}
Ten en cuenta que es necesario el punto y coma después del último comando y justo antes de }
, y que la llave de cierre debe estar separada por espacios en blanco del texto que la rodea. Para más información, consulta la Receta 2.14.
Ver también
-
Receta 2.14, "Guardar o agrupar la salida de varios comandos"
-
Receta 4.6, "Utilizar menos sentencias if" para una explicación de la sintaxis de
&&
4.9 Ejecutar comandos desde una variable
Solución
Hay muchas soluciones a este problema: en eso consiste la programación de scripts. En los próximos capítulos hablaremos de varias construcciones de programación que se pueden utilizar para resolver este problema, como if/then/else
, case
declaraciones, y más. Pero he aquí un enfoque ligeramente distinto que revela algo sobre bash. Podemos utilizar el contenido de una variable (más sobre ellas en el Capítulo 5) no sólo para los parámetros, sino también para el propio comando:
FN
=
/tmp/x.xPROG
=
echo
$PROG
$FN
PROG
=
cat$PROG
$FN
Debate
Podemos asignar el nombre del programa a una variable (aquí utilizamos $PROG
), y luego, cuando hagamos referencia a esa variable en el lugar donde se esperaría un nombre de comando, bash utilizará el valor de esa variable ($PROG
) como comando a ejecutar. Analiza la línea de comandos, sustituye los valores de sus variables, y toma el resultado de todas las sustituciones y lo trata como la línea de comandos, como si se hubiera escrito así textualmente.
Advertencia
Ten cuidado con los nombres de variables que utilizas. Algunos programas, como InfoZip, utilizan variables de entorno como $ZIP
y $UNZIP
para pasar ajustes al propio programa, así que si haces algo como ZIP=/usr/bin/zip
puedes pasarte días tirándote de los pelos preguntándote por qué funciona bien desde la línea de comandos, pero no en tu script. Confía en nosotros. Aprendimos esto por las malas. Además, RTFM.
Ver también
-
En el Apéndice C encontrarás una descripción de las distintas sustituciones que se realizan en una línea de órdenes; te conviene leer algunos capítulos más antes de abordar ese tema.
4.10 Ejecutar todos los scripts de un directorio
Problema
Quieres ejecutar una serie de guiones, pero la lista cambia continuamente; siempre estás añadiendo nuevos guiones, pero no quieres modificar continuamente una lista maestra.
Solución
Pon los scripts que quieras ejecutar en un directorio, y deja que bash ejecute todo lo que encuentre. En lugar de mantener una lista maestra, utiliza simplemente el contenido de ese directorio como lista maestra. Aquí tienes un script que ejecutará todo lo que encuentre en un directorio concreto:
for
SCRIPT in /path/to/scripts/dir/*do
if
[
-f"
$SCRIPT
"
-a -x"
$SCRIPT
"
]
then
$SCRIPT
fi
done
Debate
Discutiremos el bucle for
y la sentencia if
con más detalle en el Capítulo 6, pero esto te dará una idea. La variable $SCRIPT
tomará valores sucesivos por cada archivo que coincida con el patrón comodín *, que coincide con todo lo que haya en el directorio nombrado (excepto los archivos de puntos invisibles, cuyos nombres empiezan por punto). Si se trata de un archivo (la prueba -f
) y tiene permisos de ejecución (la prueba -x
), el intérprete de comandos intentará ejecutar ese script.
En este sencillo ejemplo, no hemos proporcionado ninguna forma de especificar ningún argumento a los scripts mientras se ejecutan. Este sencillo script puede funcionar bien para tus necesidades personales, pero no se consideraría robusto; algunos podrían considerarlo francamente peligroso. Pero esperamos que te dé una idea de lo que te espera: algunas capacidades de scripting al estilo de los lenguajes de programación.
Ver también
-
Enel capítulo 6 encontrarás más información sobre los bucles
for
y las sentenciasif
Get Libro de cocina bash, 2ª edición now with the O’Reilly learning platform.
O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.