Como usar xargs com um comando que requer entrada do usuário?

2

Eu configurei um canal retornando o nome de um pacote que gostaria de instalar usando apt-get :

... | xargs -I _ sudo apt install _

No entanto, apt-get não pode ler stdin neste caso e sai com:

Do you want to continue? [Y/n] Abort.

Eu sei sobre o sinal -y para instalar o pacote sem a confirmação do usuário, mas gostaria de ver a confirmação.

Existe uma maneira de encaminhar o nome do pacote para apt-get enquanto ainda permite que ele leia stdin?

Colocar apt-get no lado esquerdo de todo o comando não é uma opção, pois não quero que apt-get seja executado se um comando ealier no canal for abortado, usando a opção set -o pipefail .

    
por danijar 08.02.2018 / 15:38

2 respostas

2

pipefail não impede que o lado direito do pipeline seja executado, todo o tubo é executado simultaneamente, como de costume. Experimente, por exemplo

$ set -o pipefail
$ false | echo foo
foo

É o uso de xargs que pode ou não impedir a execução de apt aqui, se não receber entrada. Sem -r ou -I , ele ainda executaria o comando pelo menos uma vez.

Mas você poderia contornar isso capturando a saída com uma substituição de comando e executando apt ou não, com base no resultado:

if packages=$(somecmd...) && [ "$packages" ] ; then
    set -f
    sudo apt install $packages
fi

Nomes de pacotes não devem ter espaços em branco, portanto, usar $packages não-citado deve funcionar (assumindo o valor padrão $IFS ; eles provavelmente não podem conter caracteres glob, portanto set -f pode ser desnecessário).

    
por 08.02.2018 / 16:31
1

Com a implementação GNU de xargs (aquela normalmente encontrada em sistemas que também possuem um comando apt ) e um shell como o ksh93 / zsh / bash com suporte para substituição de processos, você pode fazer:

sudo xargs -I _ -ra <(cmd) apt install _

em vez de:

cmd | xargs -I _ sudo apt install _

Note que provavelmente faria mais sentido passar todos os pacotes de uma só vez para apt em vez de chamar um apt por pacote.

sudo xargs -d '\n' -ra <(cmd) apt install

( -d é outra extensão do GNU)

Em qualquer caso, como na versão de pipeline, com ou sem pipefail , que executará sudo , independentemente de cmd ter êxito ou não, pois sudo e cmd são iniciados ao mesmo tempo e executados ao mesmo tempo.

    
por 08.02.2018 / 16:31