es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

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.

Tags:  , , ,

Answer

  1. Avatar for 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:

    silent=true
    cmd=("sudo" "dnf" "update")
    if "$silent"; then
      newcmd=$(echo "${cmd[@]}" "> /dev/null") # construir nueva cadena de comandos
      eval "$newcmd" # ejecutar nueva cadena de comandos usando eval
    else # Ser ruidoso
      "${cmd[@]}"
    fi
    

    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 usando eval. El comando eval 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 usar eval con datos no confiables.

Comments are closed.