Dash equivalente di auto-reindirizzamento dell'output dello script


9

In Bash puoi reindirizzare tutti i futuri output stdout dello script attualmente in esecuzione . Ad esempio con questo script,

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

Questo finirà in 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

Ma questo è specifico di Bash e il dirigente nudo con reindirizzamento non sembra funzionare in Dash.

Syntax error: redirection unexpected

Come posso farlo funzionare in Dash, o possibilmente in entrambe le shell?


Potresti chiarire di cosa hai bisogno esattamente? Puoi reindirizzare con >in dash. Mi rendo conto che sembri chiedere qualcos'altro, ma non riesco proprio a capire di cosa si tratti.
terdon

@terdon ho ampliato la spiegazione.
Alex B,

Risposte:


6

Puoi semplicemente fare:

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

Puoi farlo con qualsiasi shell.

Se non ti piace il modo in cui appare, forse fai avvolgere lo script in una funzione.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff

L'ultima riga dovrebbe essere run ${1+"$@"} || do stufftale da mantenere gli argomenti.
Adam Katz,

@AdamKatz - buon punto, execpt ${1+"$@"}non fa nulla "$@" . Aveva comunque altri problemi.
Mikeserv,

"$@"passerà ""quando non ci sono argomenti mentre ${1+"$@"}passerà una stringa vuota quando non ci sono argomenti. Ciò è estremamente importante per molti programmi, poiché analizzano ""come argomento vuoto mentre una stringa vuota (non quotata) non viene affatto interpretata come argomento.
Adam Katz,

@AdamKatz - una shell Bourne molto vecchia potrebbe (e non mi aspetterei di trovare dashsu un tale sistema) , ma per il resto "$@"è unica in quanto un caso zero-args non sostituisce un argomento null per le shell POSIX.
Mikeserv,

1
@AdamKatz - in realtà era un bug anche nel vecchio bsh e non avrebbe mai dovuto funzionare così. Alla fine è stato risolto, ma non so se dovrebbe essere ancora necessario in un Solaris 10, per esempio. Hai ragione circa $ * - non mostra le stesse proprietà ordinate dell'espansione - la sua unicità unica riguarda i contenuti variabili della sua espansione, anche se sarà sempre qualcosa "${@+is especially cool $@}" . Ma non è praticamente molto diverso dalla vecchia ${1+”$@"}soluzione dopotutto. Se hai un ksh93:"${1+quoted" not quoted "quoted again}"
mikeserv

5

La sostituzione del processo può essere facilmente simulata con pipe denominate.

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

In effetti, le pipe denominate sono uno dei meccanismi (l'altro essere /dev/fd) con cui è possibile implementare la sostituzione del processo bash.


Il più versatile secondo me: potrei usare tee per reindirizzare su più flussi senza soluzione di continuità. Solo una cosa: non dimenticare di eliminare il logger_input creato alla fine di uno script.
lauhub,

2

Non credo sia possibile dash. Per quanto ne so dalla sua manpagina , non ha supporto per la sostituzione del processo.

Per ovviare al problema, potresti provare ciò che mikserv ha suggerito , oppure puoi reindirizzare tutto su un file, quindi dopo che lo script è finito (presumibilmente si tratta di uno script), aggiungi il contenuto di quel file al logger:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

In effetti, la sostituzione di processo - o ciò che altre shell chiamano sostituzione di processo - è più facile rispetto ad dashaltre shell. La sostituzione del processo equivale a un argomento che punta a un /dev/fd/[num]collegamento a una pipe anonima. dashdocumenta qui con pipe anonime piuttosto che generare file temporanei come fanno la maggior parte delle altre shell. Quindi cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nnon è solo funzionalmente equivalente, puoi anche nominare te stesso. Tuttavia, il tuo punto è ben fatto sull'andare dall'altra parte: devi aprire un nuovo fd exece avviare un processo che lo legge.
Mikeserv,

2
@mikeserv: in che senso è cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"più facile" di cat <(get output)?
ruakh,

@mikeserv: comporta molte regole da ricordare; forse sei semplicemente diventato così abituato a loro che non te ne accorgi.
ruakh,

@ruakh - beh, certo. < >reindirizzamenti delle shell. in pratica, se fai solo due di questi, puoi accumulare anche le seguenti righe. Ma sì, hai ragione - mi piacciono i documenti qui. Tuttavia, quante cose potrebbero essere necessarie da ricordare, penso che sia più facile quando funzionano universalmente. Quindi molte persone non hanno molto da usare per altre shell e quindi non fa differenza per loro. Non sono tra questi.
Mikeserv,

1
@mikeserv: non solo heredocs, ma anche /dev/fd/3(in quella forma precisa), e i dettagli di ciò che accade agli spazi bianchi. . . e del resto, il fatto che l'intero approccio funzioni affatto in Dash, quando non funziona in altre shell che hanno tutti i componenti, significa che l'approccio globale è una regola speciale da ricordare. (Questo mi ricorda i tentativi di creare un inglese semplificato con meno vocabolario; ritagliano parole come persistere , ma ignorano gli idiomi altrettanto difficili come continuare .)
ruakh
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.