Há uma descrição de um source
comando:
source
é um comando interno do shell bash que executa o conteúdo do arquivo passado como argumento, no shell atual. Tem um sinônimo em .
(período).
Por exemplo, para um experimento, quero exportar uma variável de um shell diferente zsh
no meu caso (executando o comando em bash
):
$ zsh -c "export test=$(echo "hello world")"
$ echo $test
$
Não funciona porque o comando é executado em um zsh
subshell e não é executado diretamente no bash
.
Se eu criar e originar um script desta maneira:
#!/home/linuxbrew/.linuxbrew/bin/zsh
export test=$(echo "hello world")
$ chmod 777 test.zsh
$ source test.zsh
$ echo $test
hello world
Funciona bem.
A questão é como fazer source
um comando sem usar um script já que source
pode ser executado apenas com arquivos? Eu quero conseguir algo assim:
source zsh -c "export test=$(echo "hello world")"
Se não for possível, por favor, explique o porquê.
A resposta para a pergunta que você fez é: use
eval
.Tome cuidado para que o argumento
eval
seja executado como um pedaço de código shell. Geralmente é complicado acertar. Por exemplo, o código acima definetest
a string de 5 caractereshello
, não a string de 11 caractereshello world
. Isso imita seu exemplo original comzsh -c "export test=$(echo "hello world")"
, que também definetest
comohello
. A razão é que em ambos os casos, o shell externo executa o código e determina que está chamando um comando com o argumentoexport test=hello world
. Em um caso o comando é o programa externozsh
com um primeiro argumento-c
, e no outro caso o comando é o internoeval
.Se você quisesse definir
test
comohello world
, teria que providenciar para que a avaliação do shell interno obtivesse uma entrada comoexport test="hello world"
ouexport test='hello world'
ouexport test=hello\ world
. Observe que não há nenhum método direto que funcione para caracteres arbitrários no valor: cercar com aspas simples falhará se a string contiver aspas simples; cercar com aspas duplas falhará se a string contiver qualquer um`"\[
; adicionar barras invertidas requer adicioná-las antes de cada um dos vários caracteres e não funciona para novas linhas. Como contornar essa dificuldade depende do que você quer fazer. Muitas respostas podem ser encontradas entre as perguntas sobre citações neste site.No entanto, isso pode não ser o que você quer – não está claro o que você realmente quer fazer. Observe que o código é executado pelo mesmo shell. Esse é o objetivo de
source
oreval
: executar código dentro do mesmo programa. Você está mostrando um exemplosource
onde você lê um arquivo que começa com um shebang, mas essa linha shebang é ignorada, pois o arquivo não está sendo executado: apenas seu conteúdo está.Se você quiser construir o valor de uma variável usando um programa (por exemplo, zsh) enquanto usa outro shell (por exemplo, bash), esqueça tudo isso e faça o outro programa imprimir o valor. A maneira simples é:
Observe que a substituição de comando remove as novas linhas à direita. Portanto, o valor de
test
será a string de 11 caractereshello world
, sem uma nova linha no final. Se você deseja obter a saída completaecho
com a nova linha à direita, adicione outro caractere (e opcionalmente uma nova linha) no final e remova-o.Pode ser mais simples fazer com que seu comando escreva a definição da variável e, em seguida, obtenha isso usando a substituição do processo :