2010-07-20 11 views
8

E 'possibile aggiungere spazi a sinistra di ogni output a stdout (e stderr se possibile) quando eseguo comandi in uno script di shell bash?Aggiunta di spazi allo stdout

mi piacerebbe fare qualcosa di simile:

#!/bin/bash 
echo Installing: Something 
echo " => installing prerequisite1" 

## INSERT MAGICAL LEFT SPACES COMMAND HERE ## 

apt-get install -q -y prerequisite 

## ANOTHER MAGICAL CANCELLING LEFT SPACES COMMAND HERE ## 

echo " => installing prerequisite2" 
# ... the padding again ... 
wget http://abc.com/lostzilla.tar.gz 
tar vzxf lostzilla.tar.gz 
cd lostzilla-1.01 
./configure 
make && make install 
# ... end of padding ... 

echo Done. 

Qualche idea?

MODIFICA: Aggiunti virgolette al comando echo, altrimenti non verranno riempiti.

risposta

10

Sì, è possibile citare per le cose semplici:

echo ' => installing prerequisite1' 

e pipe l'output attraverso sed per cose complesse:

tar vzxf lostzilla.tar.gz 2>&1 | sed 's/^/ /' 

Il 2>&1 mette stdout e stderr sul flusso stdout e la sed sostituisce ogni marcatore di inizio riga con tre spazi.

Quanto bene funzionerà su qualcosa come wget che non è sicuro per tutti i tipi di manipolazioni del cursore.

Esempio illustrato di seguito:

pax> ls -1 p* 
phase1.py 
phase1.sh 
phase2.py 
phase2.sh 
primes.c 
primes.exe 
primes.sh 
primes.stat 

pax> ls -1 p* | sed 's/^/ /' 
    phase1.py 
    phase1.sh 
    phase2.py 
    phase2.sh 
    primes.c 
    primes.exe 
    primes.sh 
    primes.stat 

Un trucco che ho usato in passato è quello di garantire che gli script stessi prendono cura del rientro:

#!/bin/bash 
if [[ "${DONT_EVER_SET_THIS_VAR}" = "" ]] ; then 
     export DONT_EVER_SET_THIS_VAR=except_for_here 
     $0 | sed 's/^/ /' 
     exit 
fi 
ls -1 p* 

Ciò rieseguire il script con indentazione tramite sed se non lo sta già facendo. In questo modo, non devi preoccuparti di cambiare tutte le tue istruzioni di output. Un po 'di trucco, lo so, ma tendo a fare solo ciò che è necessario per gli script di shell veloci e sporchi.

+0

Posso usare wget -q per omettere l'output. Ma immagino che la tua idea sia molto bella. Lo proverò. Grazie! – kolrie

+1

Da 'wget (1)', sulla barra di avanzamento: "Se l'output non è un TTY, la barra" punto "verrà utilizzata per impostazione predefinita." Ho dato un colpo e ha funzionato bene. Grazie per il trucco pulito. – sarnold

2

A seconda di come il comando scrive su stdout, si può solo trattino con un semplice script awk:

$ echo -e 'hello\nworld' | awk '{print " ",$0}' 
    hello 
    world 
4

Se si desidera attivare la spaziatura e disattivare, utilizzare il seguente script awk:

#!/usr/bin/gawk -f 

/^#SPACEON/ { spaces=1; } 
/^#SPACEOFF/ { spaces=0; } 
!/^#SPACE/ { 
    if(spaces) { 
     print " " $0; 
    } else { 
     print $0; 
    } 
} 

Si noti che ci sono lievi problemi con il tuo bash scipt. In particolare, l'uso di => nelle istruzioni echo invierà il carattere = al file "installazione".

#!/bin/bash 

echo Installing: Something 
echo '=> installing prerequisite1' 

echo '#SPACEON' 

echo You would see apt-get install -q -y prerequisite 

echo '#SPACEOFF' 
echo '=> installing prerequisite2' 
echo '#SPACEON' 


echo You would see wget http://abc.com/lostzilla.tar.gz 
echo You would see tar vzxf lostzilla.tar.gz 
echo You would see cd lostzilla-1.01 
echo You would see ./configure 
echo You would see make \&\& make install 

echo '#SPACEOFF' 
echo Done. 

Combinando i due mi dà:

$ ./do-stuff | ./magic-spacing 
Installing: Something 
=> installing prerequisite1 
    You would see apt-get install -q -y prerequisite 
=> installing prerequisite2 
    You would see wget http://abc.com/lostzilla.tar.gz 
    You would see tar vzxf lostzilla.tar.gz 
    You would see cd lostzilla-1.01 
    You would see ./configure 
    You would see make && make install 
Done. 

Dove-roba è lo script bash e la magia spaziatura è il mio script awk sopra.

+0

Sarebbe possibile incorporare lo snippet awk nello script bash facendo qualcosa come/usr/bin/gawk -F << EOF ... EOF? Lo proverò! – kolrie

+0

@kolrie - Potresti, ma dovresti reindirizzare lo stdout in questo snippet di awk incorporato. Forse mettendo il corpo principale in una funzione e poi reindirizzando l'output della funzione nello snippet? – bstpierre

1

Piuttosto non-magica è possibile utilizzare printf per effettuare le seguenti operazioni:

# space padding for single string 
printf "%-4s%s\n" "" "=> installing prerequisite1" 

# space padding for single command output 
# use of subshell leaves original IFS intact 
(IFS=$'\n'; printf " %s\n" $(command ls -ld * 2>&1)) 

# note: output to stderr is unbuffered 
(IFS=$'\n'; printf " %s\n" $(command ls -ld * 1>&2)) 

E 'anche possibile raggruppare comandi racchiudendoli tra parentesi graffe e lo spazio-DiPAD la loro produzione in questo modo:

{ 
cmd1 1>&2 
cmd2 1>&2 
cmd3 1>&2 
} 2>&1 | sed 's/.*/ &/' 
0

E 'possibile reindirizzare stdout script stderr/shell a livello utilizzando exec ...

( 
exec 1>&2 
command ls -ld * 
) 2>&1 | sed 's/^/ /' 
0

Usa python pyp (The Pyed Piper):

ls -ld | pyp "' '+p" 
+0

Sebbene questo codice possa rispondere alla domanda, fornire un contesto aggiuntivo riguardo a _how_ e/o _why_ risolve il problema migliorerebbe il valore a lungo termine della risposta. –

Problemi correlati