Invia stdout e stderr a file, syslog e terminale


8

Per alcune macchine cloud che sto avviando, sto cercando di accedere a un file specifico, a syslog e al terminale / console.

Nella parte superiore degli script di installazione / cloud-init della mia macchina, ho quanto segue:

#!/bin/bash
exec &> >(tee "/tmp/box-setup.log" | logger -t box-setup)
apt-get install -y some-package

Funziona perfettamente con l'invio di output a un file e syslog, ma non viene inviato all'output al terminale.

In generale non avere un output terminale non è un grosso problema tranne quando sto eseguendo il debug da una console remota. Quando ciò accade, sono completamente cieco perché la console è vuota durante l'esecuzione dello script bash.

Esiste un modo semplice per utilizzare il bashreindirizzamento o altro per reindirizzare contemporaneamente tutti gli output (output standard con errore standard) a un file, syslog e il terminale?

Sto eseguendo Ubuntu 16.04.

Risposte:


8

Aggiungi una sostituzione di processo nidificata e un'altra teecome:

exec &> >(tee >(tee "/tmp/box-setup.log" | logger -t box-setup))

Il primo teeall'interno della sostituzione del processo principale invia STDOUT / STDERR al terminale e anche alla sostituzione del processo nidificata, l' teeinterno che salva il contenuto nel file /tmp/box-setup.loge la pipe viene utilizzata per inviare anche l'output allo loggerSTDIN.


sono confuso su più invocazioni di tee, andrà a n flussi, non dovrebbe essere equivalente? exec &> >(tee /tmp/box-setup.log >(logger -t box-setup))
ThorSummoner,

3

Sono completamente cieco perché la console è vuota durante l'esecuzione dello script bash.

Potresti voler risolvere questo problema in un modo diverso: esegui il tuo script bash in background, ed esegui less /tmp/box-setup.loge premi F per continuare ad aggiornare lo schermo mentre le linee vengono aggiunte al file che sta guardando (come tail -f).

Se l'esecuzione dello script in background è un problema, utilizzare tmuxo screenper ottenere più sessioni multiplexate su una connessione ssh. Usa lo stesso lesscomando in un'altra shell.


Il problema originale:

teepuò copiare su più destinazioni. Rendi uno di loro il terminale, usando il /dev/ttyfile speciale. Penso che si riferisca sempre al controllo del processo attuale. O probabilmente meglio, /dev/stderrpoiché lo teestderr è ancora collegato allo stderr della shell. (Questo ti permette di mettere a tacere lo script con &> / dev / null).

exec &> >(tee /dev/stderr "/tmp/box-setup.log" | logger -t box-setup)

A proposito, questo è equivalente ma più efficiente di (tee /dev/stderr | tee "/tmp/box-setup.log" | logger ...).

Sarebbe possibile usare un po 'di clonazione del descrittore di file per dare teelo stdout dello script originale, piuttosto che stderr.


1

Aggiungi /dev/stderr(la tua scelta) come output a tee.

exec &> >(tee /dev/stderr "/tmp/box-setup.log" | logger -t box-setup)

L'output standard e l'errore standard verranno uniti. Non c'è modo di tenerli separati se si desidera preservare il loro ordine, che di solito è desiderabile. Non importa se entrambi vanno nello stesso posto (ad es. Il terminal) comunque.


teeLo stdout è il pipe al logger, non il terminale. È stderra quel punto che è ancora il terminale, basato sul exec &> >(tee /dev/stderr > /dev/null)funzionamento come previsto in una shell interattiva. stderrsembra un'idea migliore della mia /dev/ttyidea, poiché ti consente di chiudere facilmente la sceneggiatura con un reindirizzamento, se lo desideri.
Peter Cordes,
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.