Tenho uma função bash que produz alguma saída:
function scan {
echo "output"
}
Como posso atribuir essa saída a uma variável?
ie. VAR = scan (claro que isso não funciona - torna VAR igual à string "scan")
Respostas:
VAR=$(scan)
Exatamente da mesma forma que nos programas.
Você pode usar funções bash em comandos / pipelines da mesma forma que usaria programas normais. As funções também estão disponíveis para subshells e transitivamente, Substituição de Comando:
VAR=$(scan)
É a maneira direta de obter o resultado desejado na maioria dos casos. Vou delinear casos especiais abaixo.
Preservando Newlines à direita:
Um dos efeitos colaterais (geralmente úteis) da Substituição de Comando é que ela removerá qualquer número de novas linhas finais. Se alguém deseja preservar as novas linhas finais, pode anexar um caractere fictício à saída do subshell e, subsequentemente, removê-lo com a expansão do parâmetro.
function scan2 () {
local nl=$'\x0a'; # that's just \n
echo "output${nl}${nl}" # 2 in the string + 1 by echo
}
# append a character to the total output.
# and strip it with %% parameter expansion.
VAR=$(scan2; echo "x"); VAR="${VAR%%x}"
echo "${VAR}---"
impressões (3 novas linhas mantidas):
output
---
Use um parâmetro de saída: evitando o subshell (e preservando novas linhas)
Se o que a função tenta alcançar é "retornar" uma string em uma variável, com bash v4.3 e superior, pode-se usar o que é chamado de a nameref
. Namerefs permite que uma função receba o nome de um ou mais parâmetros de saída de variáveis. Você pode atribuir coisas a uma variável nameref, e é como se você alterasse a variável para a qual ela 'aponta / referencia'.
function scan3() {
local -n outvar=$1 # -n makes it a nameref.
local nl=$'\x0a'
outvar="output${nl}${nl}" # two total. quotes preserve newlines
}
VAR="some prior value which will get overwritten"
# you pass the name of the variable. VAR will be modified.
scan3 VAR
# newlines are also preserved.
echo "${VAR}==="
estampas:
output
===
Este formulário tem algumas vantagens. Ou seja, ele permite que sua função modifique o ambiente do chamador sem usar variáveis globais em todos os lugares.
Nota: o uso de namerefs pode melhorar muito o desempenho de seu programa se suas funções dependerem muito de bash builtins, porque evita a criação de um subshell que é descartado logo depois. Isso geralmente faz mais sentido para pequenas funções reutilizadas com frequência, por exemplo, funções que terminam emecho "$returnstring"
Isso é relevante. https://stackoverflow.com/a/38997681/5556676
Acho que init_js deve usar declare em vez de local!
function scan3() {
declare -n outvar=$1 # -n makes it a nameref.
local nl=$'\x0a'
outvar="output${nl}${nl}" # two total. quotes preserve newlines
}
local
integrado aceitará todas as opções que o declare
integrado aceitar. a partir de um teste rápido, também parece que declare -n
em um escopo de função também dá o escopo local variável. parece que eles são intercambiáveis aqui.