¿Cómo canalizar la salida al script sh y canalizarla a un comando?

¿Cómo canalizar la salida al script sh y canalizarla a un comando?

Estuve buscando esto en Google y busqué en Stack, pero no encontré exactamente lo que quiero hacer. Realmente todavía no puedo entender esto.

Entonces, digamos que tengo el script sh que es solo un contenedor de gzip (solo como ejemplo). En la línea de comando quiero canalizar la salida de algo (digamos mysqldump) a mi script. Luego, ese script debe tomar la entrada y canalizarla a gzip.

Ejemplo de línea de comando:

mysqldump somedb | miscript > algún archivo.dmp.gz

Ejemplo de myscript (algo que probé):

#!/usr/bin/env sh
read inp
command="echo \"$inp\" | gzip"
eval $command

Probablemente muchas cosas estén mal en este ejemplo. ¿Por favor ayuda? :)

Solución (para otros que la buscan)

Gracias a las explicaciones a continuación, ahora entiendo que ejecutar un comando en un script SH simplemente tomará la entrada canalizada al script tan bien como cuando el comando se ejecuta directamente.

Entonces en este caso:

archivo de gato | zip

hará exactamente lo mismo que:

mi guión:

#!/usr/bin/env sh
gzip

archivo de gato | ./miscript

Así que me gustaría señalar que en mi caso también hubo otro problema: en mi script del mundo real intenté comprobar si había un flujo de entrada leyéndolo así:

read inp
if [ -z "$inp" ]; then
    echo "No input"
    exit;
fi

Resulta que después de read inp, la tubería de entrada está vacía.

Respuesta1

#!/bin/sh
gzip -c

Eso sería suficiente.

$ mysqldump ... | ./script >out.gz

gzip -cleerá datos sin comprimir en su entrada estándar y escribirá datos comprimidos en su salida estándar.

La entrada estándar la proporciona la tubería y la salida estándar se redirige a un archivo. El shell de llamada se encarga de la canalización y la redirección.

Un ejemplo un poco más complejo que tomará una sedexpresión en la línea de comando y transformará la entrada de acuerdo con ella, o simplemente reenviará los datos si no se usó ninguna expresión:

#!/bin/sh

if [ -n "$1" ]; then
    sed -e "$1"
else
    cat
fi

(aquí, usar sed -e ""habría tenido el mismo efecto que cat, pero quería un ejemplo más complejo)

$ utility | ./script "1,5d" >out

... eliminaría las primeras cinco líneas de salida de utility.

Respuesta2

No estoy seguro de qué parte de tu guión es un simple malentendido y cuál es complejidad porque estás tratando de ilustrar una situación compleja con un ejemplo más simple.

Dicho esto, esto hará lo que pide su pregunta:

#!/bin/sh
gzip "$@"

Respuesta3

Para usar read, leer parte de la entrada y verificar si está vacía o no, tendría que usar un shell como zshese que pueda almacenar cualquier valor de byte en sus variables como:

#! /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

O utilice alguna forma de codificación:

#! /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

información relacionada