Wenn der Statuscode unbrauchbar ist, gibt es überhaupt eine Möglichkeit, eine Pipeline basierend auf der Ausgabe von stdout zu erstellen?
Ich würde es vorziehen, wenn die Antwort nicht den Anwendungsfall, sondern die Frage im Rahmen des Shell-Scripting anspricht. Ich versuche, das spezifischste im Repository verfügbare Paket zu finden, indem ich den Namen basierend auf den Länder- und Sprachcodes errate.
Nehmen Sie zum Beispiel dies,
$PACKAGE1=hunspell-en-zz
$PACKAGE2=hunspell-en
Die erste Vermutung ist angemessener, existiert aber möglicherweise nicht. In diesem Fall möchte ich hunspell-en
( $PACKAGE2
) zurückgeben, da die erste Option hunspell-en-zz
( $PACKAGE1
) nicht vorhanden ist.
Pipelines von apt-cache
Der Befehl apt-cache
gibt Erfolg zurück (der von der Shell als Exit-Code Null definiert wird), wenn der Befehl ausgeführt werden kann (aus den Dokumenten von apt-cache
).
apt-cache gibt bei normalem Betrieb Null zurück, bei Fehler dezimal 100.
Dies erschwert die Verwendung des Befehls in einer Pipeline. Normalerweise erwarte ich, dass das Paket-Suchäquivalent eines 404 zu einem Fehler führt (wie es bei curl
oder passieren würde wget
). Ich möchte suchen, ob ein Paket vorhanden ist, und wenn nicht, auf ein anderes Paket zurückgreifen, wenn es vorhanden ist .
Dies gibt nichts zurück, da der erste Befehl Erfolg zurückgibt (so dass die rhs in ||
nie ausgeführt werden)
apt-cache search hunspell-en-zz || apt-cache search hunspell-en
apt-cache search
mit zwei Argumenten
Dies gibt nichts zurück, da apt-cache
UND seine Argumente,
apt-cache search hunspell-en-zz hunspell-en
Aus den Dokumenten von apt-cache
Separate Argumente können verwendet werden, um mehrere Suchmuster anzugeben, die zusammengefügt werden.
Da eines dieser Argumente eindeutig nicht existiert, gibt dies nichts zurück.
Die Frage
Wie lautet die Shell-Sprache, um Konventionen wie die zu behandeln, bei apt-cache
denen der Rückkehrcode für die Aufgabe unbrauchbar ist? Und Erfolg wird nur durch das Vorhandensein von Ausgabe auf STDOUT bestimmt?
Ähnlich zu
make find schlägt fehl, wenn nichts gefunden wurde
beide haben das gleiche Problem. Die dort gewählte Antwort erwähnt,
find -z
welche Lösung hier leider nicht anwendbar und anwendungsfallspezifisch ist. Es wird keine Redewendung erwähnt oder eine Pipeline ohne Verwendung der Nullterminierung erstellt (keine Option aktiviertapt-cache
).
quelle
hunspell-en
es das gibt? Wie auch immer, Sie können verwendenapt-cache policy
und grep für^$PACKAGENAME:
.hunspell-ar
existieren und es keine Ländernamenpakete gibt. Ich muss das genaueste Paket für ein bestimmtes Land und eine bestimmte Sprache finden.find
ist genau wieapt-cache
in dieser Hinsicht - nutzloser Rückkehrcode, Erfolg basiert auf Ausgabe.-z
die hier leider keine Lösung darstellen, sodass das anwendungsfallspezifische Problem nicht anwendbar ist. Und es gibt keine Erwähnung einer Redewendung oder des Aufbaus einer Pipeline ohne Verwendung der Nullterminierung (keine Optionapt-cache
)find
, dass man es verwendet-print0
und damit grep-z
. Da apt-cache keine nullterminierte Ausgabe liefert, benötigen Sie keine-z
.Antworten:
Erstellen Sie eine Funktion, die einen Befehl akzeptiert und true zurückgibt, wenn eine Ausgabe vorliegt.
Für diesen Anwendungsfall wird es also so funktionieren:
quelle
r printf '\n\n\n'
dies false zurückgeben würde. Mit Muscheln anders alszsh
,r printf '\0\0\0'
wäre auch falsch zurück. So wäre esr printf '\0a\0b\0c'
mit einigen Muscheln.Soweit ich weiß, gibt es keine Standardmethode für Fälle, in denen der Erfolg eines Befehls durch das Vorhandensein einer Ausgabe bestimmt wird. Sie können jedoch Problemumgehungen schreiben.
Sie können beispielsweise die Ausgabe des Befehls in einer Variablen speichern und dann prüfen, ob diese Variable leer ist oder nicht:
Ich denke, dies beantwortet die Frage allgemein, aber wenn wir über
apt-cache search
einige Lösungen sprechen , fallen mir diese ein.Ich habe ein Skript, das die Paketverwaltung erleichtert. Einige seiner Funktionen sind folgende:
Mit diesen können Sie mehrere Suchvorgänge in einem einzigen Befehl durchführen. Zum Beispiel:
Jede Funktion durchsucht die Datenbank auf unterschiedliche Weise, sodass die Ergebnisse je nach verwendeter Funktion variieren können:
quelle
Ich würde das nicht elegant nennen, aber ich denke, es könnte den Job machen:
Ich habe leider keine Debian-Maschine zum Testen. Ich habe die
-n
Option "Nur Namen" hinzugefügt, umapt-cache
zu versuchen, die Suchergebnisse einzuschränken, da Sie anscheinend größtenteils sicher sind, wonach Sie suchen.Kann ausgeführt werden wie:
quelle
-q
leisen Option herumzuspielen ? Die Manpage ist nicht sehr ausführlich, aber vielleicht ändert sie die Rückgabewerte?Muru hat dies in den Kommentaren klargestellt und gibt den
grep
Status 1 zurück, wenn keine Eingabe erfolgt. Sie könnengrep .
dem Stream also etwas hinzufügen. Wenn keine Eingabe vorhanden ist, die dem Muster entspricht.
, wird der Statuscode geändert:Für den Anwendungsfall sieht das so aus. Im Folgenden gibt es keine,
-pl-pl
so dass es zurückfällt und zurückkehrthunspell-pl
Oder,
Es gibt ein
-en-US
so kehrt es zurückhunspell-en-us
.Siehe auch,
quelle
grep .
Gibt true zurück, wenn die Eingabe mindestens eine (bei einigen Implementierungen vollständig begrenzte) Zeile enthält, die mindestens ein (bei den meisten Implementierungen gut geformtes) Zeichen enthält, und ansonsten die leeren Zeilen entfernt.grep '^'
würde besser funktionieren, um zu überprüfen, ob es eine Ausgabe gibt, obwohl bei einigen Implementierungen immer noch false zurückgegeben werden könnte, wenn die Eingabe eine nicht begrenzte Zeile ist (und diese Zeile entfernen könnte, oder bei anderen Implementierungen true zurückgeben, aber die fehlende neue Zeile hinzufügen). Einige grep-Implementierungen drosseln auch den NUL-Charakter.Sie könnten Folgendes definieren:
Und dann:
Einige
awk
Implementierungen können NUL-Zeichen in der Eingabe verschlucken.Im Gegensatz dazu
grep '^'
funktioniert das oben Gesagte garantiert für eine Eingabe, die nicht mit einem Zeilenumbruch endet, sondern die fehlende Zeilenumbruchzeile hinzufügt.Um dies zu vermeiden und auf Systeme portierbar zu sein, auf denen
awk
Drosseln auf NUL vorhanden sind, können Sieperl
stattdessen Folgendes verwenden :Mit
perl
können Sie auch eine Variante definieren, die beliebige Dateien eleganter behandelt:Dies begrenzt die Speichernutzung (wie bei Dateien, die keine Zeilenumbrüche enthalten, wie z. B. große Dateien mit geringer Dichte).
Sie können auch Varianten erstellen wie:
oder:
(Beachten Sie, dass die Definition von Leerzeichen zwischen den
awk
Implementierungen unterschiedlich ist. Einige beschränken sich auf Leerzeichen und Tabulatoren, andere enthalten vertikale ASCII-Zeichen wie CR oder FF, andere berücksichtigen die Leerzeichen des Gebietsschemas.)Idealerweise möchten Sie unter Linux den
splice()
Systemaufruf verwenden, um die Leistung zu maximieren. Ich kenne keinen Befehl, der es verfügbar machen würde, aber Sie könnten immerpython
Folgendes verwendenctypes
:(Beachten Sie, dass entweder
has_output
stdin oder stdout (oder beides) eine Pipe sein muss, damitsplice()
es funktioniert.)quelle
Ich würde vorschlagen, sehr grundlegende integrierte Funktionen der Shell zu verwenden:
Hier ist der einfachste Testfall:
Dann könnten Sie es leicht mit dem
||
Konstrukt verwenden, an das Sie gewöhnt sind:Diese einfache Funktion funktioniert mit Ihrem
apt_cache
Verhalten so, wie Sie es möchten, unabhängig von der Anzahl der Argumente.quelle
ck_command echo 'asdf' | cat
gibt nichts aus.