Dash equivalente a la redirección automática de la salida del script

9

En Bash puede redirigir todos los resultados stdout futuros del script que se está ejecutando actualmente . Por ejemplo con este script,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Esto terminará en syslog:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Pero esto es específico de Bash y el ejecutivo desnudo con redirección no parece funcionar en Dash.

Syntax error: redirection unexpected

¿Cómo puedo hacer que funcione en Dash, o posiblemente en ambos shells?

Alex B
fuente
¿Podría aclarar qué necesita exactamente? Puede redirigir con >en el tablero. Me doy cuenta de que parece que estás pidiendo algo más, pero no puedo decir qué es.
terdon
@terdon He ampliado la explicación.
Alex B

Respuestas:

6

Solo puedes hacer:

{ commands
....
} | logger -t my_awesome_script

Puedes hacerlo con cualquier shell.

Si no le gusta cómo se ve, tal vez haga que el script se ajuste a sí mismo en una función.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff
mikeserv
fuente
Esa última línea debe ser run ${1+"$@"} || do stuffpara que se mantengan los argumentos.
Adam Katz
@AdamKatz: buen punto, execpt ${1+"$@"}no hace nada "$@" . Tuvo otros problemas de todos modos.
mikeserv
"$@"pasará ""cuando no haya argumentos, mientras ${1+"$@"}que pasará una cadena vacía cuando no haya argumentos. Esto es muy importante para muchos programas, ya que se analizan ""como un argumento vacío, mientras que una cadena vacía (sin comillas) no se interpretaría como un argumento en absoluto.
Adam Katz
@AdamKatz: un shell Bourne muy antiguo podría (y no esperaría encontrarlo dashen dicho sistema) , pero por lo demás "$@"es único, ya que un caso de cero argumentos no sustituye a un argumento nulo para los shells POSIX.
mikeserv 02 de
1
@AdamKatz: en realidad era un error incluso en el viejo bsh y nunca debería haber funcionado así. Finalmente se solucionó, pero no sé si aún debería ser necesario en un Solaris 10, por ejemplo. Tienes razón sobre $ * -, duerma exhiben las mismas propiedades ordenadas de expabsion - sus pertenece onky singularidad de los contenidos variables de su expansión, aunque siempre será something.in mi opinión, "${@+is especially cool $@}" . Pero no es prácticamente muy diferente de la antigua ${1+”$@"}solución después de todo. Si tienes un ksh93:"${1+quoted" not quoted "quoted again}"
mikeserv
5

La sustitución de procesos se simula fácilmente con tuberías con nombre.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

De hecho, las canalizaciones con nombre son uno de los mecanismos (el otro ser /dev/fd) con el que se puede implementar la sustitución de procesos bash.

chepner
fuente
El más versátil en mi opinión: podría usar tee para redirigir a varias transmisiones sin problemas. Solo una cosa: no olvide eliminar el logger_input creado al final de un script.
lauhub
2

No creo que esto sea posible en dash. Por lo que puedo ver en su manpágina , no tiene soporte para la sustitución de procesos.

Como solución alternativa, puede probar lo que sugirió mikserv , o puede redirigir todo a un archivo y luego, una vez que haya finalizado su secuencia de comandos (presumiblemente esto está en una secuencia de comandos), agregue el contenido de ese archivo al registrador:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script
terdon
fuente
De hecho, la sustitución del proceso, o lo que otros shells llaman sustitución del proceso, es más fácil que en dashotros shells. La sustitución de procesos solo equivale a un argumento que apunta a un /dev/fd/[num]enlace a una tubería anónima. dashhace documentos aquí con canalizaciones anónimas en lugar de generar archivos temporales como la mayoría de los shells. Por cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nlo tanto, no solo es funcionalmente equivalente, incluso puede nombrar el fd usted mismo. Aún así, su punto está bien hecho en el sentido contrario: debe abrir un nuevo fd con execun proceso en segundo plano que lo lea.
mikeserv
2
@mikeserv: ¿En qué sentido es cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"más fácil" que cat <(get output)?
ruakh
@mikeserv: implica muchas reglas para recordar; tal vez simplemente te has acostumbrado tanto que no te das cuenta.
ruakh
@ruakh: bueno, claro. < >redirecciones de shell. Básicamente, si solo haces dos de esos, también puedes apilar en las siguientes líneas. Pero sí, tienes un punto: me gustan los documentos aquí. Aún así, creo que es más fácil recordar tantas cosas que es más fácil cuando funcionan universalmente. Por otra parte, muchas personas no tienen mucho uso para otros proyectiles, por lo que no les importa. Simplemente no estoy entre ellos.
mikeserv
1
@mikeserv: no solo heredocs, sino también /dev/fd/3(en esa forma precisa), y los detalles de lo que sucede con los espacios en blanco. . . y para el caso, el hecho de que todo este enfoque funcione en Dash, cuando no funciona en otros shells que tienen todos los componentes, significa que el enfoque general es una regla especial para recordar. (Esto me recuerda los intentos de crear un inglés simplificado con menos vocabulario; cortan palabras como persistir , pero ignoran modismos tan difíciles como continuar ).
ruakh