Verwenden Sie die Ausgabe des Bash-Befehls (mit Pipe) als Parameter für einen anderen Befehl

9

Ich suche nach einer Möglichkeit, die Ausgabe eines Befehls (say command1) als Argument für einen anderen Befehl (say command2) zu verwenden.

Ich habe dieses Problem beim Versuch, grep die Ausgabe von who -Befehl, aber mit einem Muster von einem anderen Befehlssatz (tatsächlich tty piped zu sed ).

Kontext:

Wenn tty anzeigt:

%Vor%

Und who wird angezeigt:

%Vor%

Ziel:

Ich möchte nur die Zeile (n) bezüglich "pts / 5" Also habe ich tty wie folgt auf sed umgeleitet:

%Vor%

Test:

Der versuchte folgende Befehl funktioniert nicht:

%Vor%

Mögliche Lösung:

Ich habe herausgefunden, dass das Folgende gut funktioniert:

%Vor%

Aber ich bin mir sicher, dass die Verwendung von eval vermieden werden könnte.

Als letzter Seitenknoten: Ich habe festgestellt, dass das Argument "-m" für who genau das liefert, was ich möchte (bekomme nur die Zeile von who , die mit dem aktuellen Benutzer verknüpft ist). Aber ich bin immer noch neugierig darauf, wie ich diese Kombination von Pipes und Befehlsverschachtelung zum Funktionieren bringen könnte ...

    
CDuv 09.03.2012, 14:30
quelle

4 Antworten

5

Sie können dies tun, ohne auf sed mit Hilfe von Bash Variable Mangling zurückzugreifen, obwohl @ruakh dies unterstreicht funktioniert nicht in der Single-Line-Version (ohne das Semikolon, das die Befehle trennt). Ich verlasse diesen ersten Ansatz, weil ich denke, dass es interessant ist, dass es nicht in einer einzigen Zeile funktioniert:

%Vor%

Dies setzt zuerst die Ausgabe von tty in eine Variable und löscht dann die führende /dev/ für die Verwendung von grep. Aber ohne das Semikolon TTY ist nicht in der Umgebung bis zu dem Moment Bash macht die Variable Expansion / Mangling für Grep.

Hier ist eine Version, die funktioniert, weil sie eine Subshell mit der bereits modifizierten Umgebung erzeugt (die TTY hat):

%Vor%

Das Ergebnis bleibt in $WHOLINE .

    
Eduardo Ivanec 09.03.2012, 14:36
quelle
7

Normalerweise verwendet man xargs , um die Ausgabe eines Befehls zu einem anderen Befehl zu machen. Zum Beispiel:

%Vor%

Aber ... während das deine Frage war, ist es nicht das, was du wirklich wissen willst.

Wenn es dir nichts ausmacht, dein tty in einer Variablen zu speichern, kannst du bash variable mangling benutzen, um deine Substitution zu machen:

%Vor%

(Sie möchten das -w, wenn Sie auf pts / 6 sind, sollten Sie die Anmeldungen von pts / 60 nicht sehen.)

Sie können dies nur in einer Variablen tun, denn wenn Sie versuchen, den Befehl tty in eine Pipe zu schreiben, denkt er, dass er nicht mehr mit einem Terminal verbunden ist.

%Vor%

Beachten Sie, dass in dieser Antwort bisher nichts spezifisch für bash ist. Da Sie bash verwenden, können Sie dieses Problem auch umgehen, indem Sie die Prozesssubstitution verwenden. Zum Beispiel, während dies nicht funktioniert:

%Vor%

Das heißt:

%Vor%     
ghoti 09.03.2012 14:49
quelle
5

@ Eduardos Antwort ist richtig (und während ich dies geschrieben habe, sind ein paar andere gute Antworten aufgetaucht), aber ich würde gerne erklären, warum der ursprüngliche Befehl fehlschlägt. Wie üblich ist set -x sehr nützlich, um zu sehen, was tatsächlich passiert:

%Vor%

Es ist oben nicht vollständig explizit, aber was passiert, ist, dass tty "not a tty" ausgibt. Dies liegt daran, dass es ein Teil der Pipeline ist, der die Ausgabe von who zugeführt wird, so dass ihre Standardeingabe in der Tat nicht tty ist. Dies ist der wahre Grund, warum die Antworten der anderen funktionieren: Sie erhalten tty aus der Pipeline, so dass es Ihr tatsächliches Terminal sehen kann.

Übrigens, Ihr vorgeschlagener Befehl ist grundsätzlich korrekt (außer für das Pipeline-Problem), aber unnötig komplex. Verwenden Sie nicht echo $(tty) , es ist im Wesentlichen das gleiche wie nur tty .

    
Gordon Davisson 09.03.2012 14:52
quelle
2

Du kannst es so machen:

%Vor%     
anubhava 09.03.2012 14:41
quelle