Como canalizar a saída para o script sh e canalizá-la para um comando?

Como canalizar a saída para o script sh e canalizá-la para um comando?

Estive pesquisando isso no Google e procurei no Stack, mas não encontrei exatamente o que quero fazer. Eu realmente não consigo entender isso ainda.

Então, digamos que eu tenha um script sh que é apenas um wrapper do gzip (apenas como exemplo). Na linha de comando, quero canalizar a saída de algo (digamos mysqldump) para o meu script. Esse script deve então pegar a entrada e canalizá-la para o gzip.

Exemplo de linha de comando:

mysqldump algumdb | meuscript > algum arquivo.dmp.gz

Exemplo de myscript (algo que tentei):

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

Provavelmente muitas coisas estão erradas neste exemplo. Por favor ajude? :)

Solução (para outros que procuram)

Graças às explicações abaixo, agora entendo que executar um comando em um script SH simplesmente levará a entrada canalizada para o script tão bem quanto quando o comando estava sendo executado diretamente.

Então, neste caso:

arquivo gato | gzip

fará exatamente o mesmo que:

meuscript:

#!/usr/bin/env sh
gzip

arquivo gato | ./meuscript

Portanto, gostaria de salientar que, no meu caso, também havia outro problema: no meu script do mundo real, tentei verificar se havia um fluxo de entrada lendo-o assim:

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

Acontece que depois do read inp, o canal de entrada está vazio.

Responder1

#!/bin/sh
gzip -c

Isso seria suficiente.

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

gzip -clerá dados não compactados em sua entrada padrão e gravará dados compactados em sua saída padrão.

A entrada padrão é fornecida pelo pipe e a saída padrão é redirecionada para um arquivo. A tubulação e o redirecionamento são feitos pelo shell de chamada.

Um exemplo um pouco mais complexo que pegará uma sedexpressão na linha de comando e transformará a entrada de acordo com ela, ou apenas encaminhará os dados se nenhuma expressão for usada:

#!/bin/sh

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

(aqui, using sed -e ""teria o mesmo efeito que cat, mas eu queria um exemplo mais complexo)

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

... excluiria as primeiras cinco linhas de saída de utility.

Responder2

Não tenho certeza de qual parte do seu script é um simples mal-entendido e qual é complexa, porque você está tentando ilustrar uma situação complexa em um exemplo mais simples.

Dito isto, isso fará o que sua pergunta pede:

#!/bin/sh
gzip "$@"

Responder3

Para usar read, para ler parte da entrada e verificar se está vazia ou não, você teria que usar um shell como zshaquele que pode armazenar qualquer valor de byte em suas variáveis, 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

Ou use alguma forma de codificação:

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

informação relacionada