Wie kann man feststellen, welcher Parameter einem Befehl mit einem Redirectioin-Operator übergeben wird?

9

Das funktioniert:

$ echo "notify-send HALLO" | jetzt

Das geht nicht:

$ at now <echo "Benachrichtigen-Senden HALLO"

Es heißt "Datei oder Verzeichnis nicht gefunden".

Ich verstehe, dass es eine -fOption für diesen Befehl gibt, mit der ich die Datei liefern kann, die zu einem bestimmten Zeitpunkt ausgeführt werden soll.

Das brachte mich zum Nachdenken ... Woher weiß ich im Allgemeinen, für welchen Parameter die Umleitungsoperatoren den Wert liefern?

vlad-ardelean
quelle
5
Ihre Frage ist nicht sehr klar. Was meinst du mit "welcher Parameter"? Ihr Problem ist wahrscheinlich, dass Sie das (fälschlicherweise) denken foo | barund bar < foogleichwertig sind. Sie sind nicht.
Terdon

Antworten:

16

Sie verwenden hier zwei verschiedene Dinge und sollten ein drittes verwenden. Mal sehn:

  1. |: Dies ist der Pipe- Operator. Er dient dazu, die Ausgabe eines Prozesses als Eingabe an einen anderen zu übergeben:

    foo | bar

    Dadurch wird das Programm ausgeführt foound seine Ausgabe als Eingabe an das Programm übergeben bar.

  2. >, <, >>Und <<: Dies sind die Umleitungsoperatoren dienen sie Daten zu / von senden Dateien :

    • foo > bar: führt das Programm aus foound speichert seine Ausgabe in der Datei bar , überschreibt 1 seinen Inhalt und erstellt ihn, wenn er nicht existiert.

    • foo >> bar: Führt das Programm aus foound speichert sie auf dem seine Ausgangsdatei bar , anhängt , um den Inhalt und die Schaffung , wenn es nicht existiert.

    • foo < bar: wird ausgeführt und fooweist es an, Eingaben aus der Datei zu lesen bar.

    • Dies <<ist ein Sonderfall, da es keinen Sinn macht, Eingaben an einen Befehl <<anzuhängen. Dies wird hauptsächlich (ausschließlich AFAIK) für Here Documents verwendet :

      $ cat << EOF > file.txt
      > Hello World!
      > EOF

      Das Konstrukt << SomeStringHere > Out.fileleitet den gesamten geschriebenen Text um, bis es auf die Endzeichenfolge ( EOFim obigen Beispiel) trifft, in die Zieldatei. In den Dokumenten können Sie auf einfache Weise mehrzeilige Zeichenfolgen formatieren und Variablen und Sonderzeichen einfügen.

  3. Der <<<Operator, der Here-String , ähnelt einem Here-Dokument, erweitert jedoch Variablen. Also zum Beispiel:

    grep foo <<< "$bar"

    Der obige Befehl entspricht echo "$bar" | grep foo.

  4. Was Sie tatsächlich suchen, wird als Prozessersetzung bezeichnet und ist eine weitere Möglichkeit, die Ausgabe eines Befehls an einen anderen zu übergeben. Es besteht aus <(command).

    foo <(bar) 

    Für Ihr atBeispiel könnten Sie es also tun

    at now < <(echo "notify-send HELLO")

    Das Obige funktioniert, weil durch die Prozessersetzung tatsächlich eine Datei erstellt wird (lesen Sie den obigen Link für weitere Details) und es sich um den Dateideskriptor dieser Datei handelt, an <den übergeben wird at now.


1 Das Standardverhalten ist das Überschreiben. Dies kann geändert werden, indem die noclobberOption auf Bash gesetzt wird. Wenn festgelegt, echo foo > barschlägt dies fehl, falls barvorhanden. In diesem Fall kann stattdessen die Verwendung erzwungen werden echo foo |> bar. Siehe Abschnitt 3.6.2 hier .

Terdon
quelle
1
Gute Antwort! sehr gründlich (insbesondere einschließlich der Unterschiede zwischen den Datei-Redirectors)
Steeldriver
@steeldriver aww, shucks, danke :) Und so war dies unter geschätzten Juwel. Ich wünschte, ich hätte Ihnen eine +1 für jede der verschiedenen Fallstricke geben können, die Ihre Lösung stillschweigend vermeidet.
Terdon
Könnten Sie bitte auch erweitern, um einige Informationen über <<und <<<(die @steeldriver in seiner Antwort erwähnt hat) aufzunehmen. Darüber hinaus gibt es mehr - so etwas wie >>>>>>oder <<<<<<<<<<?
Aditya
@ Aditya fertig. Und keine Sorge, es hört auf <<<:)
Terdon
12

In diesem Fall echo "notify-send HELLO"handelt es sich bei einem Prozess nicht um eine Datei. Sie benötigen daher eher eine Prozessersetzung als eine Dateiumleitung

at now < <(echo "notify-send HELLO")

Sie hätten auch eine Here-Zeichenfolge verwenden können , um den echoBefehl vollständig zu vermeiden

at now <<< "notify-send HELLO"
Steeldriver
quelle
5
Nachdem Sie die Art von Fragen gesehen haben, die Sie gerne mögen (die gleichen, die ich tue), sollten Sie mehr Zeit mit Unix und Linux verbringen . Wir leben und sterben für coole Shell-Tricks dort ..
Terdon
@terdon: das gleiche für perl golfspieler?
Sylvain Pineau
1
@ SylvainPineau oooh ja. Besonders gern :). Im Ernst, die Art von Frage, die Sie, Stahlfahrer und ich genießen, ist dort viel häufiger. Der Ort ist voll von Kommandozeilen - Freaks einige von denen absurden auskennen.
Terdon