Existe alguma maneira de redirecionar stdout e stderr via variável como adicionar opções de comando no script?
Por exemplo, eu tenho um script:
#!/bin/bash -x
TEST=">/dev/null 2>&1"
OPT='-p -v'
mkdir $OPT 123/123/123 $TEST
Eu posso ver que o OPT é substituído por -p
sem problemas e o bash o interpreta como opção. Mas o redirecionamento interpreta como o nome dos diretórios.
$ ./test.sh
+ TEST='>/dev/null 2>&1'
+ OPT='-p -v'
+ mkdir -p -v 123/123/123 '>/dev/null' '2>&1'
mkdir: created directory `123/123'
mkdir: created directory `123/123/123'
mkdir: created directory `>/dev'
mkdir: created directory `>/dev/null'
mkdir: created directory `2>&1'
Existe alguma maneira de dizer bash, que $ VAR é redirecionamento, não um nome de diretório.
PS. Pode ser que eu esteja no caminho errado, mas quero fazer uma saída opcional ou detalhada do meu script. Mas eu preciso de alguma saída, mesmo no modo não detalhado, portanto, não posso apenas redirecionar todo o stdout e o stderr, apenas a partir de alguns comandos dentro do meu script.
fonte
O "como" foi bem explicado em outras respostas; Quero abordar o "por que" o código do OP não funciona.
A nota principal é que os redirecionamentos de saída são marcados antes da expansão da variável. Os redirecionamentos são realmente executados após a expansão da variável (por isso, é possível redirecionar a saída para um nome de arquivo armazenado em uma variável), mas o shell identifica os redirecionamentos para processamento posterior antes que as variáveis sejam expandidas.
Em outras palavras, uma vez que as variáveis são expandidas, é "muito tarde" para que um caractere de redirecionamento (
<
ou>
etc.) seja considerado, porque o shell já identificou quais partes da cadeia de comando ele irá tratar como redirecionamentos.Para leitura adicional, consulte as etapas 1 e 3 listadas em:
fonte
Ele não está sendo interpretado como um "nome de diretório",
>
está sendo citado e, portanto, está sendo tratado literalmente (mais especificamente, você está enviando a string>dev/null 2>&1
. Sua única maneira de contornar isso é usareval
ou gerar um novo shell.Quanto ao problema "detalhado" mencionado na sua pergunta, faça o seguinte:
fonte
Você tem muitos espaços em suas variáveis, que não serão avaliados adequadamente. Você vai querer usar
eval
para configurar isso.Isso permitirá que $ OPT seja dividido em dois argumentos (
-p
e-v
) em vez de um (-p -v
) e o mesmo com $ TEST. Também foi alterado para uso,/dev/null
pois é muito improvável que você tenha umdev
diretório no diretório atual.fonte
A resposta de enzotib usa alguma mágica descritor de arquivo bom, mas uma solução mais simples seria usar apenas
eval
a linha (que faz sobrecarga processo add, no entanto):fonte