
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 -c
lerá 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 sed
expressã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 zsh
aquele 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