Colocando o descritor de arquivo substituído do processo na variável

4

Eu tenho muito comando aproximadamente isto:

$ command-outer "long command which references a file here: filename1, and another file reference here: filename2"

Os arquivos são a saída de outro comando. Então estou fazendo:

$ command-outer "long ... "<(command-inner "again long params")"...  "\
  <(command-inner "again long params")" ..."

Para facilitar a leitura, eu gostaria de extrair os pipes anônimos / anônimos internos (aqueles com <() ) da longa chamada de comando. No entanto, não consigo fazer isso; fazendo o seguinte:

RESULT_FILE_DESCRIPTOR1=<(command-inner ....)

leva ao descritor de arquivo já sendo fechado quando eu realmente uso RESULT_FILE_DESCRIPTOR1 na lista params de command-outer

E invocando command-outer na mesma linha, assim:

    RESULT_FILE_DESCRIPTOR1=<(command-inner ....) outer-command "long ... $RESULT_FILE_DESCRIPTOR1 ... "

devolve um resultado vazio RESULT_FILE_DESCRIPTOR1, o que não é uma grande surpresa, já que:

FOO=BAR echo $FOO

Também não funciona.

    
por hbogert 28.09.2015 / 11:46

2 respostas

9

Em vez de nomear os resultados, basta nomear o comando.

param_set_1(){
    input_command \
        -lots     \
        -of       \
        -params
}
param_set_2(){
    input_command \
        -lots     \
        -of       \
        -other    \
        -params
}

command_outer -params <(param_set_1) <(param_set_2)

Você também pode se referir a descritores de arquivos pelo nome.

param_set_1 | { param_set_2 | command_outer -params /dev/fd/3 -; } 3<&0

Se você realmente deseja os resultados em uma variável do shell atual e em um descritor de arquivo, deve evitar os canais. Você corre o risco de preencher o buffer de pipe com a saída do seu comando enquanto tenta atribuir esses resultados a uma variável pai-shell antes que o buffer de tubos possa ser drenado pelo processo de leitura e ... bem, não é bonito. Então, você deve levar tudo de uma só vez e usar aqui-documentos.

unset fd3 fd4
{   command_outer -params /dev/fd/[34]
}   3<<FD3 4<<FD4
${fd3=$(param_set_1)}
FD3
${fd4=$(param_set_2)}
FD4
    
por 28.09.2015 / 13:48
3

Você pode usar explicitamente pipes nomeados (o que, na minha opinião, a substituição de processos usa nos detalhes):

trap cleanup EXIT
cleanup() { rm -f "$inner1" "$inner2"; }

inner1=$(mktemp -u) && mkfifo "$inner1"
command-inner "again long params" > "$inner1" &

inner2=$(mktemp -u) && mkfifo "$inner2"
command-inner "again long params" > "$inner2" &

command-outer "long ... $inner1...  $inner2 ..."
    
por 28.09.2015 / 12:06