La pipe assegna una variabile


19

Per semplicità vorrei fare:

echo cart | assign spo;
echo $spo  

Uscita: carrello

Esiste una simile assignapplicazione?

Sono a conoscenza di tutti i modi per farlo utilizzando la sostituzione.


Perché vuoi farlo senza sostituzione?
Thanatos,

Mi piace il flusso di notazione polacco inverso quando si scrive solo con pipe. Sono molto più veloce nella codifica e la qualità / velocità dei codici non è così importante. Inoltre, quando concatenato, non è più facile commentare parti della catena ed echeggiare l'output corrente piuttosto che cancellare le zecche ecc.
MageProspero

Se sei preoccupato della facilità di debug, considera di inserire il comando backticks su una serie di righe separate. A=$( some | command | here )con ciascuno di some |, command |e heresulla propria linea.
roaima,

Risposte:


11
echo cart | { IFS= read -r spo; printf '%s\n' "$spo"; }

Funzionerebbe (memorizzerà l'output echosenza il carattere di nuova riga finale nella spovariabile) purché echorestituisca solo una riga.

Puoi sempre fare:

assign() {
  eval "$1=\$(cat; echo .); $1=\${$1%.}"
}
assign spo < <(echo cart)

Le seguenti soluzioni funzionerebbero negli bashscript, ma non al bashprompt:

shopt -s lastpipe
echo cat | assign spo

O:

shopt -s lastpipe
whatever | IFS= read -rd '' spo

Per memorizzare l'output di un whatevermassimo di primi caratteri NUL (le bashvariabili non possono comunque memorizzare caratteri NUL) in $spo.

O:

shopt -s lastpipe
whatever | readarray -t spo

per memorizzare l'uscita whateverdella $spo matrice (una riga per elemento dell'array).


1
non dovrebbe esserci uno spazio tra IFS=e read?
caesarsol,

Tutti salutano l'ultima pipa. Inoltre è necessario impostare una nota laterale + m (ermmm o -m) da una riga di comando, poiché l'ultima pipe non funziona con il controllo del lavoro attivo.
MageProspero,

17

Potresti fare qualcosa del genere, se usi bash:

echo cart | while read spo; do echo $spo; done

Sfortunatamente, la variabile "spo" non esisterà al di fuori del ciclo while-do-done. Se riesci a ottenere ciò che vuoi fare all'interno del ciclo while, funzionerà.

Puoi effettivamente fare quasi esattamente quello che hai scritto sopra in ATT ksh (non in pdksh o mksh) o nel favoloso zsh:

% echo cart | read spo
% echo $spo
cart

Quindi, un'altra soluzione sarebbe usare ksh o zsh.


1
Puoi usare i coprocessi in Korn Shell (ad es. mksh): echo cart |& while read -p spo; do echo $spo; done(In realtà è meglio usarli while IFS= read -p -r spo; do…però)
mirabilos

2

Se capisco correttamente il problema, si desidera reindirizzare stdout a una variabile. Almeno quello era quello che stavo cercando e sono finito qui. Quindi per coloro che condividono il mio destino:

spa=$(echo cart)

Assegna cartalla variabile $spa.


2
Questo è ciò che chiamano sostituzione, che l'OP ha voluto evitare.
Dmitry Grigoryev,

Mi è stato utile, avevo solo bisogno di assegnarlo a una variabile, non mi importava come ci fosse arrivato!
Chris Marisic,

1

Se si desidera solo eseguire l'output del flusso di pipe corrente, utilizzare cat.

echo cart | cat 

Se vuoi continuare la tua catena di comandi, prova a usare il teecomando per fare eco all'output.

echo cart | tee /dev/tty | xargs ls

È possibile utilizzare un alias per abbreviare il comando.

alias tout='tee /dev/tty'
echo cart | tout | xargs ls

Perché dovresti voler convogliare l'output in una pianura cat?
roaima,

1
@roaima Alcuni comandi riconoscono che sono in esecuzione su un terminale e si comportano in modo diverso rispetto a quelli che stanno emettendo su una pipe. In particolare, possono troncare le linee alla larghezza attuale dello schermo. Per la maggior parte dei comandi, il comando cat è ridondante.
BillThor,

Ah ok, vedo ora cosa stavi cercando di illustrare. Il echo | catcostrutto mi ha gettato.
roaima,

1

Ecco la mia soluzione al problema.

# assign will take last line of stdout and create an environment variable from it
# notes: a.) we avoid functions so that we can write to the current environment
#        b.) aliases don't take arguments, but we write this so that the "argument" appears
#            behind the alias, making it appear as though it is taking one, which in turn
#            becomes an actual argument into the temporary script T2.
# example: echo hello world | assign x && echo %x outputs "hello world"
alias assign="tail -1|tee _T1>/dev/null&&printf \"export \\\$1=\$(cat _T1)\nrm _T*\">_T2&&. _T2"
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.