Ho una funzione bash che produce un output:
function scan {
echo "output"
}
Come posso assegnare questo output a una variabile?
cioè. VAR = scan (ovviamente questo non funziona - rende VAR uguale alla stringa "scan")
Risposte:
VAR=$(scan)
Esattamente allo stesso modo dei programmi.
Puoi usare le funzioni bash nei comandi / pipeline come faresti altrimenti con programmi regolari. Le funzioni sono disponibili anche per subshell e transitivamente, Command Substitution:
VAR=$(scan)
È il modo più diretto per ottenere il risultato desiderato nella maggior parte dei casi. Descriverò casi speciali di seguito.
Preservare le nuove righe finali:
Uno degli effetti collaterali (solitamente utili) della sostituzione del comando è che eliminerà qualsiasi numero di nuove righe finali. Se si desidera conservare le nuove righe finali, è possibile aggiungere un carattere fittizio all'output della subshell e successivamente rimuoverlo con l'espansione dei parametri.
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}---"
stampe (3 newline mantenute):
output
---
Usa un parametro di output: evitare la subshell (e preservare le nuove righe)
Se ciò che la funzione cerca di ottenere è "restituire" una stringa in una variabile, con bash v4.3 e versioni successive, si può usare ciò che viene chiamato a nameref
. Namerefs consente a una funzione di prendere il nome di uno o più parametri di output delle variabili. Puoi assegnare cose a una variabile nameref, ed è come se avessi cambiato la variabile che "punta a / fa riferimento".
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}==="
stampe:
output
===
Questa forma presenta alcuni vantaggi. Vale a dire, consente alla funzione di modificare l'ambiente del chiamante senza utilizzare variabili globali ovunque.
Nota: l'uso di namerefs può migliorare notevolmente le prestazioni del tuo programma se le tue funzioni fanno molto affidamento sui builtin bash, perché evita la creazione di una subshell che viene gettata via subito dopo. Questo generalmente ha più senso per piccole funzioni riutilizzate spesso, ad esempio funzioni che terminano conecho "$returnstring"
Questo è rilevante. https://stackoverflow.com/a/38997681/5556676
Penso che init_js dovrebbe usare declare invece di 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
builtin accetterà tutte le opzioni che il declare
builtin accetterà. da un rapido test, sembra anche che declare -n
in uno scope di funzione fornisca anche l'ambito locale della variabile. sembra che siano intercambiabili qui.