Rohr ordnet Variable zu

19

Der Einfachheit halber möchte ich tun:

echo cart | assign spo;
echo $spo  

Ausgabe: Wagen

Existiert eine solche assignAnwendung?

Mir sind alle Möglichkeiten bekannt, dies durch Substitution zu erreichen.

MageProspero
quelle
Warum möchten Sie dies ersatzlos tun?
Thanatos
Ich mag die umgekehrte polnische Schreibweise, wenn ich nur mit Pfeifen schreibe. Ich codiere viel schneller und die Qualität / Geschwindigkeit der Codes ist nicht so wichtig. Außerdem ist es beim Verketten nicht einfacher, Teile der Kette
auszukommentieren
Wenn Sie Bedenken haben, wie einfach das Debuggen ist, sollten Sie den Befehl backticks in mehrere separate Zeilen einteilen. A=$( some | command | here )mit jedem von some |, command |und herein einer eigenen Zeile.
Roaima

Antworten:

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

Würde funktionieren (speichere die Ausgabe echoohne das nachfolgende Newline-Zeichen in der spoVariablen), solange echonur eine Zeile ausgegeben wird.

Sie könnten immer tun:

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

Die folgenden Lösungen würden in bashSkripten funktionieren , jedoch nicht an der bashEingabeaufforderung:

shopt -s lastpipe
echo cat | assign spo

Oder:

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

Speichern der Ausgabe von whateverbis zu den ersten NUL-Zeichen ( bashVariablen können ohnehin keine NUL-Zeichen speichern) in $spo.

Oder:

shopt -s lastpipe
whatever | readarray -t spo

um die Ausgabe von whateverim $spo Array zu speichern (eine Zeile pro Array-Element).

Stéphane Chazelas
quelle
1
Sollte zwischen IFS=und kein Leerzeichen sein read?
Caesarsol
Alles Hagel letzte Pfeife. Außerdem wird das Randnotenset + m (ermmm oder -m) über eine Befehlszeile benötigt, da die letzte Pipe bei aktivierter Jobsteuerung nicht funktioniert.
MageProspero
17

Sie könnten so etwas tun, wenn Sie verwenden bash:

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

Leider existiert die Variable "spo" nicht außerhalb der while-do-done-Schleife. Wenn Sie in der while-Schleife das erledigen können, was Sie wollen, funktioniert das.

Sie können tatsächlich fast genau das tun, was Sie oben in ATT ksh (nicht in pdksh oder mksh) oder im fabelhaften zsh geschrieben haben:

% echo cart | read spo
% echo $spo
cart

Eine andere Lösung wäre also, ksh oder zsh zu verwenden.

Bruce Ediger
quelle
1
Sie können Koprozesse in der Korn-Shell verwenden (zB mksh): echo cart |& while read -p spo; do echo $spo; done(eigentlich besser zu verwenden while IFS= read -p -r spo; do…)
mirabilos
2

Wenn ich das Problem richtig verstehe, möchten Sie stdout an eine Variable weiterleiten. Zumindest habe ich das gesucht und bin hier gelandet. Also für diejenigen, die mein Schicksal teilen:

spa=$(echo cart)

Weist cartder Variablen zu $spa.

zack-vii
quelle
2
Das nennen sie Substitution, die das OP vermeiden wollte.
Dmitry Grigoryev
Das war nützlich für mich, ich musste es nur einer Variablen zuweisen, es war mir egal, wie es dahin kam!
Chris Marisic
1

Wenn Sie nur den aktuellen Pipe-Stream ausgeben möchten, verwenden Sie cat.

echo cart | cat 

Wenn Sie Ihre Befehlskette fortsetzen möchten, verwenden Sie den Befehl, um teedie Ausgabe zu wiederholen.

echo cart | tee /dev/tty | xargs ls

Sie können einen Alias ​​verwenden, um den Befehl zu verkürzen.

alias tout='tee /dev/tty'
echo cart | tout | xargs ls
BillThor
quelle
Warum sollten Sie die Ausgabe an eine Ebene weiterleiten cat?
Roaima
1
@roaima Einige Befehle erkennen, dass sie auf einem Terminal ausgeführt werden, und verhalten sich anders, als wenn sie auf einer Pipe ausgegeben werden. Insbesondere können sie Linien auf die aktuelle Bildschirmbreite kürzen. Für die meisten Befehle ist der Befehl cat überflüssig.
BillThor
Ah ok, ich verstehe jetzt, was Sie versuchen zu veranschaulichen. Das echo | catKonstrukt hat mich geworfen.
Roaima
1

Hier ist meine Lösung für das Problem.

# 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"
Brian Kramer
quelle