É compatível com POSIX para usar uma função shell em um pipeline?

1

É possível usar uma função shell em um pipeline?

Digamos que eu tenha uma função que agia como grep , chamada mygrep . Existe alguma maneira, usando apenas recursos de shell POSIX, para poder invocar mygrep assim:

if ps | mygrep foo ; then
   echo "process foo is running"
fi

Ou a tubulação está limitada apenas a comandos externos?

    
por Tim Bird 19.09.2018 / 06:56

2 respostas

4

Sim. Consulte este documento .

1. Introdução

The Shell and Utilities volume of POSIX.1-2017 describes the commands and utilities offered to application programs by POSIX-conformant systems.

De 2.9.2 Oleodutos :

A pipeline is a sequence of one or more commands separated by the control operator '|'.

De 2.9.5 Comando de definição de função :

A function is a user-defined name that is used as a simple command [...]

The format of a function definition command is as follows:

fname ( ) compound-command [io-redirect ...]

De 2.9 Comandos da Shell :

A command is one of the following:

  • Simple command [...]
  • [...]

Então | separa os comandos; um comando pode ser um comando simples; nome da função é usado como um comando simples. A resposta para sua pergunta é: sim, esta sintaxe

some_command | some_function

é definido por POSIX.

É muito fácil tentar (testado com sh fornecido por dash no Debian 9):

mygrep() { grep "$@"; }

if ps | mygrep foo ; then
   echo "process foo is running"
fi

if ps | mygrep ps ; then
   echo "process ps is running"
fi

( ps | mygrep foo também detectará um processo foobar , se houver. Entendo que esse problema está fora do escopo da sua pergunta e podemos ignorá-lo).

Neste exemplo, mygrep é trivial. Ele retorna o status de saída de seu último (e único) comando. Ao criar funções com lógica mais complexa, você pode precisar de um% especialreturn incorporado para retornar o status de saída desejado.

Observe também que a saída de grep não é suprimida. Não apenas uma função de shell pode ser usada em pipes, sua saída também pode ser redirecionada. Exemplo:

if ps | mygrep ps >/dev/null ; then
   echo "process ps is running"
fi
    
por 19.09.2018 / 08:12
-2

Você precisa usar o formulário oneliner ou compactar sua expressão para $ {}. Nesse formulário você escreveu como script bash não é possível.

    
por 19.09.2018 / 07:36

Tags