Configurando o ambiente vars contendo espaço com env

2

Estou tentando usar env para definir variáveis de ambiente (lidas de outra fonte, por exemplo, um arquivo) para um subprocesso. Essencialmente, estou tentando o seguinte:

env VALUE=thisisatest ./somescript.sh

Se, por exemplo, somescript.sh foi:

echo $VALUE

Em seguida, isso imprimirá thisisatest conforme o esperado. Mas eu gostaria de carregar as variáveis de um arquivo. Eu cheguei a este ponto:

env $(cat .vars | xargs -d '\n') ./somescript.sh

Mas, , tenho problemas quando qualquer uma das variáveis contém espaços (e as cotações não funcionam como esperado) . Então, por exemplo:

env $(echo 'VALUE="this is a test"' | xargs -d '\n') ./somescript.sh

O erro ocorrerá com

env: is: No such file or directory

E tentando:

env $(echo 'VALUE="thisisatest"' | xargs -d '\n') ./somescript.sh

Vai me dar o inesperado:

"thisisatest"

Presumi que isso funcionaria corretamente, pois a execução de env VALUE="thisisatest" ./somescript.sh imprime sem as aspas.

A partir do erro, eu compreendo que, por algum motivo, env não está entendendo que as aspas significam que o valor que segue deve ser uma string. No entanto, não tenho certeza de como interpolar essas vars de forma que as aspas sejam interpretadas corretamente.

Alguém pode dar dicas de como eu poderia fazer isso?

Obrigado!

    
por Bailey Parker 17.04.2015 / 08:43

3 respostas

3

Você precisa de aspas duplas na substituição do comando, caso contrário, o shell executará a divisão de campo com o resultado da substituição do comando:

$ env "$(echo 'VALUE="this is a test"')" ./somescript.sh
"this is a test"

Para a leitura de env do arquivo, você deve permitir que o shell execute a divisão de campo, mas defina IFS apenas para nova linha, para que seu comando não seja interrompido com espaço:

$ IFS='
'
$ env $(cat .vars) ./somescript.sh

Se você quiser ler a partir do arquivo, é melhor que você faça a fonte (também conhecido como ponto ) o arquivo em somescript.sh :

#!/bin/bash

. .vars
: The rest of script go here
    
por 17.04.2015 / 08:53
2

Isso funciona: env -S "'cat .vars'" command

Primeiro, no seu arquivo, você precisa citar o valor da variável.

VALUE="This has spaces"

Em seguida, use o sinalizador -S para analisar os vars (que retira as aspas).

env -S "'cat .vars'" command-refers-to-env-vars

Você não pode se referir a $VALUE no comando, é claro, porque o comando é avaliado pelo shell anterior à ação de env . Para fazer isso, você precisa usar o seguinte:

( . .vars ; echo $VALUE )

Os parênteses abrem um subshell para que você não polua seu shell com todas as definições em .vars. No entanto, as variáveis estão disponíveis apenas para o shell. Na verdade, eles não estão no env , portanto, os processos não poderiam acessá-los com process.ENV.VALUE ou getenv("VALUE") com a invocação env -S .

Você pode combinar os dois com

( . .vars ; env -S "'cat .vars'" command-refers-to-envs $VALUE )

    
por 14.06.2017 / 06:17
0

Eu acho que você está complicando demais as coisas.

$ env FOO='this is a test' printenv | egrep -i foo
FOO=this is a test

A propósito, as citações não fazem parte do problema this . Use aspas duplas se você quiser, por exemplo, substituição de variável em seu valor; use aspas simples se quiser evitar a substituição de variáveis, etc.

Heck, use a substituição de comandos se ela atender às suas necessidades. Use cadeias de caracteres formatadas. Use os dois.

$ env FOO=$'this\tis a test' printenv | egrep -i foo | cat -t
FOO=this^Iis a test
$ env FOO="$(echo $'this\tis a test')" printenv | egrep -i foo | cat -t
FOO=this^Iis a test

Opa, esse pode ser um exemplo melhor de usar a substituição de comandos. A idéia é colocar a saída de algum comando requerido na variável, não apenas usar gratuitamente a substituição de comando onde nenhuma é necessária.

$ env FOO="$(man man)" printenv | egrep -iA5 foo=
FOO=man(1)                                    man(1)



NAME
   man - format and display the on-line manual pages
    
por 06.09.2017 / 23:20