Como usar uma função bash como um comando regular em uma cadeia de tubos?

3

Estou realizando vários comandos em arquivos grandes a partir de um script bash. Para monitorar o progresso eu uso o comando pv.

Um exemplo de comando poderia se parecer com isso

cat $IN_FILE | pv -w 20 -s $(du -sb $IN_FILE | awk '{print $1}') | grep ...

O script contém vários comandos de estrutura semelhante, em vez de ter que usar o mesmo prefixo em todos esses comandos repetidas vezes. Eu defini uma função para a parte de monitoramento de progresso como mão curta. ( Nota: as funções fSize e fSize Sum envolvem a parte do comando du do exemplo acima, onde fSizeSum retorna a soma do tamanho de dois arquivos fSize o tamanho de um arquivo ):

function prog()
{
    local __size
    if [[ $2 ]]
    then
        __size=$(fSizeSum $1 $2)
    else
        __size=$(fSize $1)
    fi

    echo "cat $1 | pv -w 20 -s ${__size}"
}

Na verdade, essa abordagem já encurta um pouco os comandos. Eu posso executar o exemplo acima agora assim:

eval "$(prog $IN_FILE) | grep ..."

O que ainda está me incomodando é que agora tenho que citar cada linha e usar eval. Eu prefiro usar a função "prog" como se fosse um comando shell regular, ou seja:

prog $IN_FILE | grep ...

Todas as minhas tentativas de modificar minha função para funcionar como um prefixo em uma cadeia de comandos canalizados falharam até agora.

Existe alguma maneira que eu possa fazer auto-definido bash-script função para agir como se fosse um comando bash regular e colocá-lo na frente de uma cadeia de tubos? Se não há como fazer isso usando funções, existe algum outro método para atingir esse objetivo - como definir um alias local dentro do script?

    
por norritt 13.05.2015 / 20:50

2 respostas

2

Na sua definição de função, sugiro substituir:

echo "cat $1 | pv -w 20 -s ${__size}"

com apenas:

cat $1 | pv -w 20 -s ${__size}

Dessa forma, a própria função executará esse código, sem precisar de uma chamada para eval no chamador.

    
por 13.05.2015 / 21:37
1

pv se comporta como cat se você passar arquivos como argumentos, e desta forma você nem precisa passar -s.

Então você pode fazer:

pv -w 20 $IN_FILE | grep ...

    
por 14.05.2015 / 06:49