Crie uma abreviação para “2 / dev / null &”

0

Estou tentando compor um script bash com a intenção de ser usado comumente em um terminal. Ele deve iniciar um aplicativo como um processo em segundo plano e descartar sua saída stderr. Aqui está o que eu tenho:

 for app in $@; do 
    $app 2>/dev/null
 done

Pareceu funcionar muito bem com aplicativos simples iniciados sem parâmetros, como script.sh firefox gedit , mas não conseguiu fazer o seguinte:

script.sh "vlc video.mp4"

Minha pergunta é: Como posso melhorar esse script básico para lidar com aplicativos que usam parâmetros / arquivos como entrada? Talvez já exista uma ferramenta que eu possa usar?

    
por 610 03.05.2018 / 15:02

2 respostas

5

Existem dois problemas:

  1. O uso de $@ sem aspas.

    Isso faria com que o loop fosse iterado sobre vlc e video.mp4 como dois itens separados, mesmo que estivessem dentro da mesma string citada na invocação do script.

  2. Usando um comando em uma variável.

    Se o comando for algo mais complicado que um simples comando simples, isso não funcionará. Você teria que eval da string dada.

Levando isso em conta, seu script pode se parecer com

#!/bin/sh

for cmd do  # or:  for cmd in "$@"; do
    eval "$cmd" 2>/dev/null
done

Chamando isso como

./script 'echo "hello world"' 'vim "$HOME/.profile"' 'tr a-z A-Z <"$HOME/.profile" | grep -c EXPORT'

primeiro executaria echo "hello world" e, quando isso terminasse, abriria vim para editar o arquivo nomeado naquele segundo comando. O último comando é mais complexo, mas manipulado pelo fato de usarmos eval (ele apenas altera todos os caracteres alfabéticos para maiúsculos e conta o número de vezes que a string EXPORT ocorre em um arquivo). É executado assim que sai a sessão vim .

Com isso, você pode até fazer

./script 'd=$HOME' 'ls "$d"'

, por exemplo, defina variáveis que são usadas em comandos posteriores. Isso funciona porque os comandos chamados por eval são executados no mesmo ambiente que o script. Isso não funcionaria se você iniciar os comandos como tarefas em segundo plano, como sugere o título da sua pergunta.

    
por 03.05.2018 / 15:08
1

Você está atualmente dizendo ao seu script para manipular cada parâmetro como um aplicativo separado. Então você está correndo:

$ vlc

Então:

$ video.mp4

Você deve tornar seu script mais parecido com isto:

#!/bin/bash
$@ 2>/dev/null

Qual, na minha opinião, seria mais adequado como uma função:

func_name() {
$@ 2>/dev/null
}

Observação: isso só permitirá que você execute um comando por vez. Não tenho certeza se sua intenção original era passar vários comandos de uma só vez para o seu script, se assim for, vou excluir.

    
por 03.05.2018 / 15:08