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.