Como canalizar a saída para o script sh e canalizar isso para um comando?

3

Eu estive pesquisando por isso e pesquisei Stack, mas não encontrei a coisa exata que queria fazer. Eu realmente não consigo entender isso ainda.

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

Exemplo de linha de comando:

mysqldump somedb | myscript > somefile.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 com este exemplo. Por favor ajude? :)

Solução (para outras pessoas que o procuram)

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

Então, neste caso:

cat file | gzip

fará exatamente o mesmo que:

myscript:

#!/usr/bin/env sh
gzip

cat file | ./myscript

Por isso, gostaria de salientar que, no meu caso, havia outro problema também: 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.

    
por vrijdenker 18.05.2017 / 18:41

3 respostas

3
#!/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 atendidos pelo shell de chamada.

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

#!/bin/sh

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

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

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

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

    
por 18.05.2017 / 20:06
2

Não sei ao certo qual parte do seu script é um mal-entendido simples e qual é a complexidade porque você está tentando ilustrar uma situação complexa em um exemplo mais simples.

Tendo dito isso, isso fará o que sua pergunta perguntar:

#!/bin/sh
gzip "$@"
    
por 18.05.2017 / 19:11
1

Para usar read , para ler algumas das entradas para verificar se está vazio ou não, você teria que usar um shell como zsh 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
    
por 19.05.2017 / 10:55

Tags