Verallgemeinern irgendwelche Shells das Konzept von Pipes auf mehrere parallele Pipelines? Wäre für die Unterstützung eine Änderung des Betriebssystemkernels erforderlich?

Verallgemeinern irgendwelche Shells das Konzept von Pipes auf mehrere parallele Pipelines? Wäre für die Unterstützung eine Änderung des Betriebssystemkernels erforderlich?

Wenn ich an der Befehlszeile arbeite, ertappe ich mich häufig dabei, dass ich dieselbe Operation für eine Reihe verschiedener Instanzen angebe, die durch einen Eingabestream angegeben werden, und dann deren Ausgaben auf eine bestimmte Art und Weise neu kombinieren möchte.

Zwei Anwendungsfälle von gestern:

  1. Ich wollte die Themen einer Reihe von SSL-Zertifikaten sehen, die in einer PEM-Datei gebündelt sind.

     cat mypemfile.crt |
     (openssl x509 -noout -text | fgrep Subject:)
    

    zeigt mir nur das erste an. Ich muss die Zertifikate aufteilen und für jedes davon denselben Befehl ausführen und dann die Ergebnisse verketten. csplitkann sie aufteilen, aber nur in Dateien. Das ist mühsam.

    Warum kann ich nicht einfach sagen

     cat mypemfile.crt |
     csplit-tee '/BEGIN/ .. /END/' |
     on-each ( openssl x509 -noout -text | fgrep Subject: ) |
     merge --cat
    

    ?

  2. Wir betreiben eine JupyterHub-Instanz, die Notebook-Server als Docker-Container abspaltet. Ich möchte ihre zeitgestempelten Protokolle sehen. Für einen Container ist das ganz einfach:

     sudo docker logs -t -f $container_id
    

    (Das -tfügt einen Zeitstempel hinzu und das -fhält die Pipe offen, wie tail -f.)

    Es ist ganz einfach, die Protokolle aller Container nach Zeitstempeln sortiert aufzulisten:

     sudo docker ps | awk '{print $1}' |
     while read container_id
     do
       sudo docker logs -t $container_id
     done |
     sort
    

    oder

     sudo docker ps | awk '{print $1}' |
     xargs -n1 sudo docker logs -t |
     sort
    

    oder

     sudo docker ps | awk '{print $1}' |
     parallel sudo docker logs -t {} |
     sort
    

    Aber keine dieser Möglichkeiten ermöglicht mir die Nutzung der -fOption zum Überwachen der Protokolle beim Eintreffen.

    Warum kann ich nicht einfach

     sudo docker ps | awk '{print $1}' |
     csplit-tee /./ |
     on-each (xargs echo | sudo docker logs -t -f) |
     merge --line-by-line --lexicographically
    

    oder

     sudo docker ps | awk '{print $1}' |
     parallel --multipipe sudo docker logs -t -f {} |
     merge --line-by-line --lexicographically
    

    ?

Dies erfordert natürlich

  1. Spezifische Shell-Unterstützung. Vielleicht bräuchten wir ein eindeutiges „Multi-Pipe“-Symbol.
  2. Neue Tools ( csplit-tee, on-eachund merge) zum Aufteilen und Zusammenführen von Pipelines.
  3. Eine feste Konvention zum Angeben beliebig vieler Eingabe- und Ausgabedateideskriptoren innerhalb von Tools, sodass diese Shell sie als parallele Pipelines behandelt.

Wurde dies bereits getan? Oder etwas Gleichwertiges, das ich auf meine Anwendungsfälle anwenden kann?

Ist dies ohne spezifische Kernel-Unterstützung machbar? Ich weiß, dass der Kernel normalerweise eine feste maximale Anzahl offener Dateideskriptoren hat, aber eine Implementierung kann dies umgehen, indem sie nicht blind versucht, sie alle auf einmal zu öffnen.

Ist es machbar, wenn man weiß,GNU parallelist machbar?

Antwort1

Mit GNU Parallel:

cat mypemfile.crt |
  parallel --pipe -N1 --recstart '-----BEGIN' 'openssl x509 -noout -text | fgrep Subject:'

Ungetestet:

sudo docker ps | awk '{print $1}' |
  sudo parallel -j0 --lb docker logs -t -f {}

sudo docker ps | awk '{print $1}' |
  sudo parallel -j0 --tag --lb docker logs -t -f {}

Antwort2

Nein, das kann die Shell nicht. Eine Pipe ist einfach ein Datenstrom von einer Quelle zu einem Ziel, normalerweise in verschiedenen Prozessen.

Schauen wir uns Ihr erstes Beispiel an:

cat mypemfile.crt |
(openssl x509 -noout -text | fgrep Subject:)

Sie möchten, dass die Eingabedatei entlang der Zeilen mit BEGIN und END aufgeteilt wird, catder Inhalt ist Ihnen jedoch egal, und Pipes weisen ohnehin keine außerhalb der Grenzen liegenden Angaben zu Datensatztrennzeichen auf.

Dies ließe sich zwar durch spezielle Konventionen in der Quelle und dem Ziel einer Pipe erreichen, allerdings ginge dadurch der Hauptvorteil einer Pipe verloren, nämlich die Möglichkeit, Programme als Bausteine ​​für Aufgaben zu kombinieren, die von ihren Autoren nicht vorhergesehen wurden.

In diesem speziellen Beispiel wäre es viel einfacher, die Änderung so vorzunehmen, openssldass mehrere Zertifikate in einem Stream verarbeitet werden, als die Änderung so vorzunehmen, openssldass mehrere Streams verarbeitet werden UND diese Änderung so vorzunehmen, catdass diese mehreren Streams bereitgestellt werden.

verwandte Informationen