2009-04-18 2 views
12

Il manuale indica che il raccordo a T è un "raccordo per tubi". I casi mi [1] confondono:Unix: uso confuso del comando Tee

1. caso

echo "foo bar" | sudo tee -a /path/to/some/file 

2. caso

:w !sudo tee % 

E 'difficile capire la logica del T dai casi. Come funziona la maglietta?

+0

': w sudo tee%' http://stackoverflow.com/a/7078429/739331 –

risposta

7

tee viene normalmente utilizzato per dividere l'output di un programma in modo che possa essere visualizzato e salvato in un file. Il comando può essere utilizzato per acquisire l'output intermedio prima che i dati vengano modificati da un altro comando o programma. Il comando tee legge lo standard input, quindi scrive il suo contenuto sullo standard output. Simultaneamente copia il risultato nel file specificato (s) o variabili

tee [OPTION]... [FILE]... 

Per esempio

tee [ -a ] [ -i ]... [ File ]... 
  • -a accoda l'output alla fine del file invece di scrivere su di esso.

  • -i Ignora interrupt.

enter image description here

Con sudo e aggiungendo al file con il vostro esempio nella questione

ls -l | sudo tee -a file.txt 
+1

Forse, puoi mostrare come reindirizza l'output anche a 'less' quando usi già' sudo'. –

12

tee copie stdin-stdout (come cat) e inoltre scrive di tutto per il file denominato. Usandolo in questo modo con sudo consente di spingere le informazioni in una modalità privilegiata e, allo stesso tempo, monitorare se le cose giuste sono andate lì.

Si noti inoltre, che a causa del modo in cui viene gestito il reindirizzamento nel guscio quasi equivalente

sudo echo "foo bar" > /path/to/some/file 

non funziona, dal momento che il reindirizzamento sarebbe fatto da parte dell'utente chiamante e non dall'utente sudo bersaglio .

+0

Cosa succede se i dati di stdout sono troppo grandi come spinge i dati in un file? per taglia o per periodo? – Shantesh

0

tee riflette semplicemente l'output in un file che può essere specificato come argomento per tee.

Nel caso in cui si mostri Tee è chiamato come superutente (tramite sudo) ed è un solo scopo scrivere un file come utente super invece se l'utente che fa l'eco.

33

tee viene utilizzato per dividere una pipeline di comandi, che consente di salvare l'output di un comando in un file e inviarlo insieme lungo la pipeline. Nel primo esempio che ha dato ::

echo "foo bar" | sudo tee -a /path/to/some/file 

"foo bar" sarà eco sullo standard output e aggiunto al /path/to/some/file. Pensa a tee come una "T" in una pipe, dividendo l'output in altri due pipe.

+4

Ecco da dove viene il nome :-) – Joey

2

Ricordate che l'obiettivo di tee non è limitato ai file regolari, ma può essere di dispositivi, FIFO, ecc Inoltre, è possibile reindirizzare ad un altro tee invocazione, e così via. :-)

1

Trovo che il comando tee sia molto utile nel debug degli script di shell che contengono pipeline lunghe. Questa è la fine di uno spaventoso script di shell che è in ritardo da un decennio per una riscrittura in Perl, ma funziona ancora. (E 'stato modificato l'ultima volta nel 1998, come accade.)

# If $DEBUG is yes, record the intermediate results. 
if [ "$DEBUG" = yes ] 
then 
    cp $tmp.1 tmp.1 
    cp $tmp.2 tmp.2 
    cp $tmp.3 tmp.3 
    tee4="| tee tmp.4" 
    tee5="| tee tmp.5" 
    tee6="| tee tmp.6" 
    tee7="| tee tmp.7" 
fi 

# The evals are there in case $DEBUG was yes. 
# The hieroglyphs on the shell line pass on any control arguments 
# (like -x) to the sub-shell if they are set for the parent shell. 
for file in $* 
do 
    eval sed -f $tmp.1 $file    $tee4 | 
    eval sed -f $tmp.3      $tee5 | 
    eval sh ${-+"-$-"}      $tee6 | 
    eval sed -f $tmp.2      $tee7 | 
    sed -e '1s/^[ ]*$/[email protected]/' -e '/^[email protected]/d' 
done 

I tre script sed che vengono eseguiti sono orribile - non ho intenzione di mostrare loro. Questo è anche un uso semi-decente di eval. I normali nomi di file temporanei ($ tmp.1, ecc.) Sono preservati da un nome fisso (tmp.1, ecc.) E i risultati intermedi sono conservati in tmp.4 .. tmp.7. Se stavo aggiornando il comando, userebbe '"[email protected]#"' invece di '$*' come mostrato. E, quando eseguo il debug, non c'è un solo file nell'elenco degli argomenti, quindi il calpestamento dei file di debug non è un problema per me.

Si noti che se è necessario, è possibile creare più copie dell'input contemporaneamente; non è necessario alimentare un comando tee in un altro.

Se qualcuno ne ha bisogno, ho una variante di tee denominata tpipe che invia copie dell'output a più pipeline anziché a più file. Continua anche se una delle pipeline (o output standard) termina presto. (Vedi il mio profilo per informazioni di contatto.)

3

spiegazioni per i casi

1. l'escalation dei permessi con il sudo- e -tee comandi

L'esempio non è circa appena logica , piuttosto convenzione. It mostra la convenzione di degenerare permesso:

echo "Body of file..." | sudo tee root_owned_file > /dev/null 

Questo esempio mostra tee utilizzato per bypass un limite intrinseco nel comando sudo. sudo non è in grado di convogliare lo standard output in un file. Con che scarica il flusso stdout in /dev/null, sopprimiamo anche l'output speculare nella console.

2. eseguendo sudo-comandi con Vim

Dal momento che è possibile utilizzare Sudo-comandi con Vim, è possibile utilizzare il comando se si è dimenticato di lanciare come sudo. È utile in posti come /etc/init.d/, dove troverete file di sola lettura.

Logic con il tee-comando di

E 'come un ramo in Git, o meglio, per favore, vedi the T analogy by Rick Copeland. Speriamo che l'esempio modificato (original) aiuta a capire il suo utilizzo:

curl "http://en.wikipedia.org/wiki/Pipeline_(Unix)" | tee original_site | sed 's/[^a-zA-Z ]/ /g' | tr 'A-Z ' 'a-z\n' | grep '[a-z]' | sort -u | comm -23 - /usr/share/dict/words 
0

comando tee crea semplicemente N + 1 non di file, 1 copia passò a stdout e altri agli argomenti forniti al tee (cioè file) dove N : numero di documenti passati a T