Wie kann ich feststellen, ob ein Programm im Terminal auf stderr oder stdout druckt?

7

HINWEIS: Eine neue Zeile wird angezeigt, aber od -c zeigt sie nicht an.

Der Statusbefehl ( quodlibet --status | od -c) meines Musik-Players hat drei Status , und ich versuche, eine Bedingung basierend auf dieser Ausgabe zu schreiben. Die Ausgaben dieses Befehls sind wie folgt (können je nach Konfiguration unterschiedlich sein).

  1. Ich denke, dies wird auf stderr gedruckt, weil od -ces nicht richtig angezeigt wird, obwohl es für die anderen Befehle gilt.

    not-running
    0000000
    
  2. hielt inne

    0000000   p   a   u   s   e   d       P   a   n   e   d   B   r   o   w
    0000020   s   e   r       1   .   0   0   0       s   h   u   f   f   l
    0000040   e       o   n       0   .   2   2   8  \n
    0000053
    
  3. spielen

    0000000   p   l   a   y   i   n   g       P   a   n   e   d   B   r   o
    0000020   w   s   e   r       1   .   0   0   0       s   h   u   f   f
    0000040   l   e       o   n       0   .   2   3   2  \n
    0000054
    

Mein Ziel ist es, alles außer "nicht laufen", "angehalten" oder "spielen" zu entfernen und dies unter folgenden Bedingungen zu verwenden:

#!/bin/bash

status=$(quodlibet --status | awk '{split($0,m," "); printf "%s",m[1]}' | tr -d '\000\007\010\n')
if [ "$status" = "playing" ]; then
  quodlibet --print-playing '<artist>: <title>' | cut -c1-45
else
  echo -n "$status"
fi

In dem Fall, in dem der Player nicht ausgeführt wird, wird nach "Nicht ausgeführt" immer eine neue Zeile im Terminal gedruckt. Auch wenn ich so etwas mache

echo -n "$(quodlibet --print-playing '<artist>: <title>' | cut -c1-45)"

Wenn ich diesen Ausgang anpfeife od -c, bekomme ich das gleiche

not-running
0000000

was nicht richtig ist. Die neue Zeile wird nicht angezeigt, befindet sich jedoch im Terminal.

Fragen

  • Was verursacht das?
  • Wird der Befehl auf Standardfehler gedruckt, wenn das Programm nicht ausgeführt wird?
  • Wie kann ich das feststellen?
Michael A.
quelle

Antworten:

5

Einige Möglichkeiten, dies zu erreichen.

  1. Streams zusammenführen

    Sie können die Differenz umgehen und einfach STDERR und STDOUT zusammenführen.

    Beispiel

    quodlibet --status 2>&1 | ...
  2. benutze grep

    Sie können die Ausgabe mit den Schaltern -o& -Ereduzieren grep.

    Beispiel

    $ echo "...blah not-running blah..." | grep -Eo "not-running|paused|playing"
    not-running
    
    $ echo "...blah paused blah..." | grep -Eo "not-running|paused|playing"
    paused
    
    $ echo "...blah playing blah..." | grep -Eo "not-running|paused|playing"
    playing
    

    Dadurch wird alles außer den Zeichenfolgen ausgeschnitten, mit denen das Regex-Argument übereinstimmt grep.

  3. Bestimmen Sie den Stream-Typ

    Mit dem -tSchalter können Sie den Typ des Dateideskriptor-Streams bestimmen.

    Auszug aus der Bash-Manpage

    -t fd True, wenn der Dateideskriptor fd geöffnet ist und auf ein Terminal verweist.

    wo fd ist einer von:

    0: stdin
    1: stdout
    2: stderr

    Beispiel

    Dies erkennt, ob der Ausgang von STDOUT kommt.

    $ if [ -t 1 ]; then echo "from STDOUT"; fi
    from STDOUT
    

    Gibt "von STDOUT" zurück, da die Ausgabe durchläuft, während:

    $ (if [ -t 1 ]; then echo "from STDOUT"; fi) | cat

    Gibt nichts zurück, da die Ausgabe an gerichtet wird cat.

slm
quelle
Das Zusammenführen der Streams hat es geschafft. Ich dachte, es wäre so etwas, aber ich konnte die Syntax nicht richtig verstehen.
Michael A