
Ich habe danach gegoogelt und Stack durchsucht, aber nicht genau das gefunden, was ich tun möchte. Ich kann das noch nicht wirklich begreifen.
Nehmen wir also an, ich habe ein sh-Skript, das nur ein Wrapper von gzip ist (nur als Beispiel). Auf der Befehlszeile möchte ich die Ausgabe von etwas (sagen wir mysqldump
) an mein Skript weiterleiten. Dieses Skript muss dann die Eingabe übernehmen und an gzip weiterleiten.
Beispiel einer Befehlszeile:
mysqldump somedb | myscript > somefile.dmp.gz
Beispiel für Myscript (etwas, das ich ausprobiert habe):
#!/usr/bin/env sh
read inp
command="echo \"$inp\" | gzip"
eval $command
Wahrscheinlich stimmt vieles an diesem Beispiel nicht. Bitte helfen Sie mir. :)
Lösung (für andere, die danach suchen)
Dank der folgenden Erklärungen verstehe ich nun, dass beim Ausführen eines Befehls in einem SH-Skript die Eingabe genauso einfach an das Skript weitergeleitet wird, als wenn der Befehl direkt ausgeführt würde.
In diesem Fall gilt also:
cat-Datei | gzip
bewirkt genau das Gleiche wie:
meinSkript:
#!/usr/bin/env sh
gzip
cat-Datei | ./myscript
Ich möchte daher darauf hinweisen, dass es in meinem Fall noch ein weiteres Problem gab: In meinem realen Skript habe ich versucht zu prüfen, ob ein Eingabestream vorhanden war, indem ich ihn folgendermaßen gelesen habe:
read inp
if [ -z "$inp" ]; then
echo "No input"
exit;
fi
Es stellt sich heraus read inp
, dass die Eingabeleitung nach dem leer ist.
Antwort1
#!/bin/sh
gzip -c
Das würde reichen.
$ mysqldump ... | ./script >out.gz
gzip -c
liest unkomprimierte Daten auf seiner Standardeingabe und schreibt komprimierte Daten auf seine Standardausgabe.
Die Standardeingabe wird von der Pipe bereitgestellt und die Standardausgabe wird in eine Datei umgeleitet. Die Pipe und Umleitung übernimmt die aufrufende Shell.
Ein etwas komplexeres Beispiel, das einen sed
Ausdruck in der Befehlszeile verwendet und die Eingabe entsprechend transformiert oder die Daten einfach weiterleitet, wenn kein Ausdruck verwendet wurde:
#!/bin/sh
if [ -n "$1" ]; then
sed -e "$1"
else
cat
fi
(hier sed -e ""
hätte die Verwendung den gleichen Effekt wie gehabt cat
, aber ich wollte ein komplexeres Beispiel)
$ utility | ./script "1,5d" >out
... würde die ersten fünf Ausgabezeilen von löschen utility
.
Antwort2
Ich bin nicht sicher, welcher Teil Ihres Skripts auf einem einfachen Missverständnis und welcher auf Komplexität beruht, da Sie versuchen, eine komplexe Situation anhand eines einfacheren Beispiels zu veranschaulichen.
Allerdings wird dies das bewirken, was Ihre Frage verlangt:
#!/bin/sh
gzip "$@"
Antwort3
Um read
einen Teil der Eingabe zu lesen und zu prüfen, ob sie leer ist oder nicht, müssen Sie eine Shell wie zsh
diese verwenden, die beliebige Bytewerte in ihren Variablen speichern kann, wie:
#! /bin/zsh -
if LC_ALL=C read -ru0 -k1 byte; then
# one byte was read, the input is not empty
(printf %s "$byte"; cat) | gzip
else
echo >&2 No input
fi
Oder verwenden Sie eine Form der Kodierung:
#! /bin/sh -
# get the value of the first byte as octal:
byte=$(od -An -N1 -vto1 | tr -cd 0-7)
if [ -n "$byte" ]; then
(printf "\\$byte"; cat) | gzip
else
echo >&2 No input
fi