Strichäquivalent zur Selbstumleitung der Skriptausgabe


9

In Bash können Sie alle zukünftigen Standardausgaben des aktuell ausgeführten Skripts umleiten . Zum Beispiel mit diesem Skript,

exec > >(logger -t my-awesome-script)
echo 1
echo 2
echo 3

Dies wird in Syslog enden:

Oct 26 01:03:16 mybox my-awesome-script[72754]: 1
Oct 26 01:03:16 mybox my-awesome-script[72754]: 2
Oct 26 01:03:16 mybox my-awesome-script[72754]: 3

Dies ist jedoch Bash-spezifisch und der nackte Manager mit Umleitung scheint in Dash nicht zu funktionieren.

Syntax error: redirection unexpected

Wie kann ich dafür sorgen, dass es in Dash oder möglicherweise in beiden Shells funktioniert?


Können Sie klarstellen, was Sie genau brauchen? Sie können mit >in Bindestrich umleiten . Mir ist klar, dass Sie anscheinend nach etwas anderem fragen, aber ich kann nicht genau sagen, was es ist.
Terdon

@terdon Ich habe die Erklärung erweitert.
Alex B

Antworten:


6

Sie können einfach tun:

{ commands
....
} | logger -t my_awesome_script

Sie können das mit jeder Shell tun.

Wenn Ihnen das Aussehen nicht gefällt, lassen Sie das Skript möglicherweise selbst in eine Funktion einschließen.

#!/bin/sh
run() if     [ "$run" != "$$" ] || return
      then   sh -c 'run=$$ exec "$0" "$@"' "$0" "$@" |
             logger -t my-awesome-script
      fi
#script-body
run "$@" || do stuff

Diese letzte Zeile sollte run ${1+"$@"} || do stuffso sein, dass die Argumente beibehalten werden.
Adam Katz

@AdamKatz - guter Punkt, execpt ${1+"$@"}macht nichts "$@" nicht. Es hatte sowieso andere Probleme.
Mikeserv

"$@"wird übergeben, ""wenn keine Argumente vorhanden sind, während ${1+"$@"}eine leere Zeichenfolge übergeben wird, wenn keine Argumente vorhanden sind. Dies ist für viele Programme von enormer Bedeutung, da sie ""als leeres Argument analysiert werden, während eine (nicht zitierte) leere Zeichenfolge überhaupt nicht als Argument interpretiert wird.
Adam Katz

@AdamKatz - eine sehr alte Bourne-Shell könnte (und ich würde nicht erwarten, dashauf einem solchen System zu finden ) , ist aber ansonsten "$@"insofern einzigartig, als ein Null-Argument-Fall kein Null-Argument für POSIX-Shells ersetzt.
Mikesserv

1
@AdamKatz - es war eigentlich ein Bug sogar im alten bsh und hätte nie so funktionieren sollen. Es wurde schließlich behoben, aber ich weiß nicht, ob es zum Beispiel in einem Solaris 10 noch notwendig sein sollte oder nicht. Sie haben Recht mit $ * - es weist nicht die gleichen ordentlichen Eigenschaften der Expabsion auf - seine Einzigartigkeit bezieht sich nur auf den variablen Inhalt seiner Expansion, obwohl es meiner Meinung nach immer etwas sein wird "${@+is especially cool $@}" . Aber praktisch nicht ganz anders als die alte ${1+”$@"}Problemumgehung. Wenn Sie ein ksh93 haben:"${1+quoted" not quoted "quoted again}"
mikeserv

5

Die Prozesssubstitution lässt sich leicht mit Named Pipes simulieren.

mkfifo logger_input
logger -t my_awesome_script < logger_input &
exec > logger_input
echo 1
echo 2
echo 3

In der Tat sind Named Pipes einer der Mechanismen (der andere ist /dev/fd), mit denen die Prozesssubstitution implementiert werden kann bash.


Das vielseitigste meiner Meinung nach: Ich könnte Tee verwenden, um nahtlos zu mehreren Streams umzuleiten. Nur eines: Vergessen Sie nicht, den erstellten logger_input am Ende eines Skripts zu löschen.
Lauhub

2

Ich denke nicht, dass dies in möglich ist dash. Soweit ich auf seiner manSeite sehen kann , wird die Prozessersetzung nicht unterstützt.

Um dieses Problem zu umgehen , können Sie versuchen, was mikserv vorgeschlagen hat , oder Sie können alles in eine Datei umleiten und dann nach Abschluss Ihres Skripts (vermutlich in einem Skript) den Inhalt dieser Datei zum Logger hinzufügen:

$ exec > ~/foo/foo.txt
$ ls
$ echo something
$ cat foo/foo.txt | sudo logger -t my-awesome-script

Tatsächlich ist die Prozessersetzung - oder was andere Shells Prozesssubstitution nennen - in dashanderen Shells einfacher . Die Prozessersetzung ist nur ein Argument, das auf eine /dev/fd/[num]Verknüpfung zu einer anonymen Pipe verweist . dashHier werden Dokumente mit anonymen Pipes erstellt, anstatt wie bei den meisten anderen Shells temporäre Dateien zu erstellen. Ist cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\nalso nicht nur funktional gleichwertig, Sie können den fd sogar selbst benennen. Trotzdem ist es gut gemacht, in die andere Richtung zu gehen - Sie müssen eine neue fd mit execeinem Prozess öffnen und einen Hintergrund erstellen, der sie liest.
Mikesserv

2
@mikeserv: Inwiefern ist cat /dev/fd/3 3<<HEREDOC\n$(get output)\nHEREDOC\n"einfacher" als cat <(get output)?
Ruakh

@mikeserv: Es gibt viele Regeln, an die man sich erinnern muss. Vielleicht haben Sie sich einfach so an sie gewöhnt, dass Sie es nicht bemerken.
Ruakh

@ruakh - na klar. < >Shell-Umleitungen. Wenn Sie nur zwei davon ausführen, können Sie im Grunde auch die folgenden Zeilen stapeln. Aber ja, Sie haben einen Punkt - ich mag hier Dokumente. Trotzdem, so viele Dinge, an die man sich erinnern muss, ist es einfacher, wenn sie universell funktionieren, denke ich. Andererseits haben viele Leute nicht viel Verwendung für andere Muscheln und so macht es für sie keinen Unterschied. Ich bin einfach nicht unter ihnen.
Mikesserv

1
@mikeserv: Nicht nur Heredocs, sondern auch /dev/fd/3(in dieser genauen Form) und die Details darüber, was mit Leerzeichen passiert. . . Die Tatsache, dass dieser gesamte Ansatz in Dash überhaupt funktioniert, wenn er in anderen Shells mit allen Komponenten nicht funktioniert, bedeutet, dass der Gesamtansatz eine besondere Regel ist, an die man sich erinnern sollte. (Dies erinnert mich an Versuche, ein vereinfachtes Englisch mit weniger Vokabeln zu erstellen; sie schneiden Wörter wie persist aus , ignorieren aber ebenso schwierige Redewendungen wie keep on .)
ruakh
Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.