Wie leite ich die Ausgabe an ein SH-Skript weiter und wie leite ich diese an einen Befehl weiter?

Wie leite ich die Ausgabe an ein SH-Skript weiter und wie leite ich diese an einen Befehl weiter?

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 -cliest 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 sedAusdruck 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 readeinen Teil der Eingabe zu lesen und zu prüfen, ob sie leer ist oder nicht, müssen Sie eine Shell wie zshdiese 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

verwandte Informationen