source
precisa de um nome de arquivo, você não pode redirecionar a entrada para ele.
No meu sistema, eu consegui usar a substituição do processo:
source <( grep = test.sh )
Substitua =
pela expressão regular apropriada.
Digamos que eu tenha um script bash que atua como um arquivo de configuração para outro script bash:
config.sh:
verbose=yes
echo "Malicious code!"
name=test
script.sh:
source config.sh
echo "After sourcing: verbose='$verbose', name='$name'"
O problema é que isso não é muito seguro, já que qualquer coisa colocada no config.sh é executado:
$ ./script.sh
Malicious code!
After sourcing: verbose='yes', name='test'
Para torná-lo mais seguro, pensei em distribuir as operações de atribuição e executá-las apenas. Eu realizaria passando source
um "documento aqui":
script.sh:
source <<EOF
$(grep -P '^\s*\w+=' test.sh)
EOF
echo "After sourcing: verbose='$verbose', name='$name'"
(Sim, sei que o regex não é tão strong; é apenas um marcador de posição.) Infelizmente, a fonte não parece funcionar bem aqui:
./script.sh: line 1: source: filename argument required
source: usage: source filename [arguments]
After sourcing: verbose='', name=''
Obviamente, eu poderia fazer várias coisas para obter dados de configuração de um arquivo, e é provável que seja mais seguro de qualquer maneira.
Mas ainda me resta essa coceira; Eu quero descobrir se o que eu tentei pode funcionar. Alguma sugestão?
source <(cat << EOF
A=42
EOF
)
echo $A
Saída:
42
Você pode diretamente eval
it:
eval "$(grep -P '^\s*\w+=' config.sh)"
#quotes needed if you want the full content of the file (including newlines etc.)
O sourcing é essencialmente o mesmo que:
eval "$(cat file)"
Observe, no entanto, que as pessoas poderiam estar executando todos os kinz de codez no lado direito do sinal de igual:
a=$(evil_code_here)
b='evil_code_here'
c="something" evil_code_here
#etc.
Você precisa de um filtro melhor.
Tags bash shell here-document