Añadiendo una redirección a una matriz de comandos bash
Estoy almacenando un comando para ejecutarlo en un arreglo de bash, ejemplo:
declare -a cmd=("sudo" "dnf" "update")
"${cmd[@]}"
Última comprobación de expiración de metadatos: hace 0:24:45 en Fri 07 Jan 2022 03:35:34 PM EST.
Resolución de dependencias.
Nada por hacer.
¡Completo!
Ahora, digamos que quiero redirigir la salida para que sea menos ruidosa. Esto funciona:
"${cmd[@]}" &>/dev/null
Pero preferiría almacenar la redirección con el arreglo de comandos para poder agregarla/eliminarla como cualquier otro comando en el arreglo:
declare -a cmd=("sudo" "dnf" "update" "&>/dev/null")
"${cmd[@]}"
Última comprobación de expiración de metadatos: hace 0:29:14 en Fri 07 Jan 2022 03:35:34 PM EST.
No se encuentra ninguna coincidencia para el argumento: &>/dev/null
La salida no se está redirigiendo, el último elemento del arreglo simplemente se está pasando como un argumento normal. ¿Existe alguna manera de hacer que esto funcione (es decir, uso juicioso de eval) o una estrategia mejor?
Declaración XY:
Estoy intentando usar condicionales para hacer que mi programa no muestre salida. Puedo hacer esto con:
silent=true
cmd=("sudo" "dnf" "update")
if "$silent"; then
"${cmd[@]}" &>/dev/null
else # Ser ruidoso
"${cmd[@]}"
fi
Esto resulta en mucho código duplicado a lo largo de mi programa (cada operación de depuración necesita varias líneas de ejecución de comandos). En cambio, preferiría agregar la redirección al arreglo, de la siguiente manera:
silent=true
cmd=("sudo" "dnf" "update")
"$silent" && cmd+=("&>/dev/null")
"${cmd[@]}"
Esta estrategia funciona muy bien para funciones y argumentos, pero no para redirecciones. Aunque puedo aplicar banderas –quiet a algunos programas para lograr esto, en algunos casos me gustaría redirigir stderr, redirigir a un archivo, etc.
davy.ai
Para lograr esto, puedes usar la función de sustitución de procesos del shell Bash con el comando
echo
para construir una nueva cadena de comandos que incluya la redirección:En esta solución, utilizamos
echo
para construir una nueva cadena de comandos que añade> /dev/null
al final de la cadena de comandos original. La cadena resultante se ejecuta usandoeval
. El comandoeval
evalúa la cadena resultante como si se escribiera en la línea de comandos, permitiéndonos redirigir la salida según lo deseado.Ten en cuenta que el uso de
eval
puede ser arriesgado si no tienes cuidado, por lo que es importante asegurarse de que la cadena de comandos resultante sea segura para ejecutar. En este caso, estamos construyendo la cadena nosotros mismos y no confiamos en la entrada del usuario, por lo que debería ser seguro. Sin embargo, ten cuidado al usareval
con datos no confiables.