¿Cómo redirigir la salida de un comando a un archivo cuando el comando solicitará entradas del usuario?

¿Cómo redirigir la salida de un comando a un archivo cuando el comando solicitará entradas del usuario?

Tengo un comando que solicitará al usuario algunas entradas y luego enviará el resultado a la terminal. Escribí el comando como se muestra a continuación para redirigir la salida a un archivo:

$the_command > abc.txt

Pero no funciona. El problema es que no hay ningún mensaje, el texto de esas preguntas rápidas se envía a abc.txt y no es el resultado que quiero.

Respuesta1

Su comando funciona y redirige correctamente la salida al archivo abc.txt.
La pregunta es¿Cómo solicita su script los datos de entrada?¿Y cómo estás ejecutando el script?
Veamos con dos ejemplos:

# Script_1.sh                                     # 1
echo Please, enter your firstname and lastname    # 2
read FN LN                                        # 3
echo "Hi! $LN, $FN !"                             # 4

y

# Script_2.sh                                     # 5
read -p "Enter a comment " CM                     # 6
echo  "You said $CM"                              # 7

Si ejecuta, /bin/bash Script1.sh > abc.txtno verá la pregunta "Por favor ingrese..." en su tty. Si proporciona la entrada esperada desde el teclado, encontrará el resultado de las líneas 2 y 4 de su abc.txtarchivo.

Si ejecuta /bin/bash Script2.sh > abc.txtverá la pregunta "Ingrese un comentario", pero encontrará en el abc.txtarchivo solo el resultado de la línea #7.

Nota: si ejecuta Script2,sh en un subshell

(bash Script2.sh 2>&1)> abc.txt

No verá ningún resultado en tty y lo encontrará todo en el abc.txtarchivo.
Si lo ejecutas con

bash Script2.sh 2>ccc.txt 1>ddd.txt`

Encontrará la salida estándar (línea n.° 7) en ddd.txty el error estándar (línea n.° 6) en ccc.txt.


Si quierespara redirigir solo parte de la salida de su comandotienes que modificar tu script.
Una de las formas de hacerlo es crear una función en la que mover la parte del script que generará el resultado interesante (ver más abajo). Entonces puedes llamar a esta función desde elparte principalde su script (donde originalmente estaba el código que movió a la función) redirigiendo solo esa salida al archivo de registro:

 Part_To_Redirect(){
     : # all that you want
 }

 # ... Main part of the script
 # point where it was the part that generates the output
 Part_to_Redirect "$@" > abc.txt   # this to store only that part in the file
 # Part_to_Redirect "$@" >> abc.txt  # this to append that part in the file
 # ...

Incluso deberías encontrar útilteeeso

redirige la salida a múltiples archivos,copia la entrada estándar a la salida estándary también a cualquier archivo proporcionado como argumento.

 the_command  | tee abc.txt       # To redirect Standard output
 or 
 the_command 2>&1 | tee abc.txt   # To redirect err in out and both in the file

En este caso, tendrá los resultados normales de su comando en el tty, pero al mismo tiempo guardará una copia en el archivo de registro abc.txt. Debería resultar cómodo en su caso si utiliza read -pla invocación como en el script2 the_command | tee abc.txt.

Notas y referencias:

Agregando "$@"puedespasar todo el argumentode su script a la función.

Puede que le resulte interesante leer más sobre bashredirection en muchas fuentes en Internet.

Respuesta2

De forma predeterminada, solo STDOUTse redirige y/o canaliza. Lo que desea es dejarlo STDOUTen paz y redirigir todo lo que se pasa STDIN.

Si editar the_commandes una opción, puede asegurarse de que la pregunta se envíe a la STDERRpantalla (eso debería volcarla a la pantalla independientemente de las redirecciones) y luego hacer que se haga eco de lo que el usuario escriba en la pantalla a través de STDOUT.

Respuesta3

Generalmente hay 2 canales de salida importantes: STDOUT(para salida normal) y STDERR(para mensajes de error).

El problema aquí es que la salida "normal" del comando y el texto del mensaje se escriben en STDOUT, por lo que siempre se colocan en la misma ubicación. Cuando usa su redirección, solo toma el mensaje completo STDOUT, incluido el mensaje.

Si no es posible reescribir (como se sugiere en otra respuesta de Jarmund) el comando, ¿tal vez el comando tenga una opción/marca adicional (como --output), que puede especificar algún archivo de salida en lugar de usar la redirección?

información relacionada