Salida directa de un comando a un archivo que incluye el comando original, e imprimir en el terminal


8

Cuando ejecuto algunas pruebas, necesito ejecutar una serie de comandos. Sería extremadamente útil para mí y me ahorraría mucho tiempo si hubiera una manera de hacer todas estas cosas:

  • Ejecute el comando que necesito ejecutar
  • Redireccionar toda la salida del comando a un archivo especificado
  • Incluye el comando original en el archivo especificado
  • Imprima la salida del comando original en la terminal

La gente me ha sugerido usar tee, que hace un gran trabajo al imprimir en la terminal, así como enviarlo a un archivo pero no incluye el comando original. Con lo que me gustaría terminar es con un archivo donde la primera línea es el comando que ejecuté, y luego debajo está el resultado del comando.

Alguien sugirió esto:

echo "ls -l" | xargs -I{} bash -c "echo >> output.file; eval {} >> output.file"

Pero esto no imprime la salida en el terminal ni incluye el comando original en el archivo.

Agradecería cualquier idea.



No encontré esto en mi búsqueda, no exactamente lo mismo, pero probablemente me habría llevado a la respuesta.
shaneoh

Sí, y es por eso que dije casi el duplicado. Pero para ser sincero con mi opinión, podría tomar casi cualquier solución a partir de ahí y utilizarla con tuberías tee.
Sergiy Kolodyazhnyy

Respuestas:


14

Eso es lo teeque estás buscando.

ls -l | tee outfile

imprime la salida de ls -lstdout (es decir, el terminal) y la guarda en el archivo outfileal mismo tiempo. Pero : no escribe el nombre del comando ni en stdout ni en el archivo. Para lograr eso, solo echoel nombre del comando antes de ejecutar el comando y canalizar ambas salidas a tee:

( echo "ls -l" && ls -l ) | tee outfile

Es engorroso escribir, así que ¿por qué no definir una función?

both(){ ( echo "$@" && "$@" ) | tee outfile ;}

Después de eso puedes correr

both ls -l

para obtener el resultado deseado. Ponga la función en su ~/.bashrcpara tenerla definida en cada nueva terminal.

Si desea poder especificar el archivo de salida como primer argumento como en

both output ls -l

en cambio hazlo:

both(){ ( echo "${@:2}" && "${@:2}" ) | tee "$1" ;}

Si no desea que se sobrescriba el archivo de salida, sino que se anexe, agregue la -aopción tee.


9

Puede utilizar el scriptcomando que creará un archivo de texto mecanografiado de todo lo impreso en su terminal. Crea un caparazón bifurcado y registrará todo hasta que salga de ese caparazón.

$ script my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
Script done on Tue 28 Nov 2017 09:46:27 AM UTC

Entonces, si cat my_outputobtengo el mismo resultado:

$ cat my_output
Script started on Tue 28 Nov 2017 09:46:15 AM UTC
$ whoami
ajefferiss
$ exit
exit

Script done on Tue 28 Nov 2017 09:46:27 AM UTC

6

Puede usar la función de depuración del shell junto con tee:

( set -x; command1 args...; command2 args ) 2>&1 | tee output.log
  • ( ... )inicia un sub-shell que le permite "recopilar" las secuencias de salida de todos los comandos ejecutados dentro del sub-shell. También contiene el efecto del setcomando a continuación para este sub-shell.

  • set -xhabilita la xopción de shell que imprime todos los comandos que ejecuta el shell en la secuencia de error estándar antes de ejecutarlos.

  • 2>&1 redirige el flujo 2 (error estándar) al flujo 1 (salida estándar).

  • | redirige el flujo de salida estándar del comando izquierdo al flujo de entrada estándar del comando derecho.

  • tee FILEcopia la secuencia de entrada estándar al archivo FILEy a la salida estándar.

Si su secuencia de comandos ya está en un archivo de script, tendría más sentido ejecutarlo así:

bash -x /path/to/script args... 2>&1 | tee output.log
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.