Jak mogę przypisać dane wyjściowe funkcji do zmiennej za pomocą bash?


Odpowiedzi:


150
VAR=$(scan)

Dokładnie tak samo jak w przypadku programów.


3
Odkryłem, że nowe wiersze są usuwane, gdy wykonałem polecenie „echo $ VAR”. Gdybym zamiast tego zacytował $ VAR, zachował nowe linie.
Brent

2
To nie w 100%. Podstawianie poleceń zawsze usuwa końcowe znaki nowej linii.
TheBonsai

8
To tworzy podpowłokę; czy istnieje sposób, aby to zrobić w tej samej powłoce?
lmat - Przywróć Monikę

24

Możesz używać funkcji bash w poleceniach / potokach, tak jak w normalnych programach. Funkcje są również dostępne dla podpowłok i przejściowo, Zastępowanie poleceń:

VAR=$(scan)

W większości przypadków jest prostym sposobem osiągnięcia pożądanego rezultatu. Poniżej opiszę przypadki szczególne.

Zachowywanie końcowych znaków nowej linii:

Jednym z (zwykle pomocnych) efektów ubocznych zastępowania poleceń jest to, że usuwa dowolną liczbę końcowych znaków nowej linii. Jeśli ktoś chce zachować końcowe znaki nowej linii, może dołączyć fikcyjny znak do wyjścia podpowłoki, a następnie usunąć go za pomocą rozwinięcia parametrów.

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}---"

wydruki (zachowane 3 nowe linie):

output


---

Użyj parametru wyjściowego: unikanie podpowłoki (i zachowanie nowych linii)

Jeśli funkcja stara się „zwrócić” ciąg do zmiennej, przy bash v4.3 i nowszych, można użyć tak zwanego a nameref. Namerefs pozwala funkcji na przyjęcie nazwy jednego lub więcej parametrów wyjściowych zmiennych. Możesz przypisać rzeczy do zmiennej nazwy odniesienia i to tak, jakbyś zmienił zmienną, na którą „wskazuje / odwołuje się”.

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}==="

wydruki:

output

===

Ta forma ma kilka zalet. Mianowicie, pozwala twojej funkcji modyfikować środowisko wywołującego bez używania wszędzie zmiennych globalnych.

Uwaga: użycie nazw odwołań może znacznie poprawić wydajność programu, jeśli funkcje w dużym stopniu opierają się na wbudowanych funkcjach bash, ponieważ unika się tworzenia podpowłoki, która jest wyrzucana zaraz potem. Zwykle ma to większy sens w przypadku małych funkcji często używanych ponownie, np. Funkcji kończących się naecho "$returnstring"

To jest istotne. https://stackoverflow.com/a/38997681/5556676


0

Myślę, że init_js powinien używać deklaracji zamiast lokalnego!

function scan3() {
    declare -n outvar=$1    # -n makes it a nameref.
    local nl=$'\x0a'
    outvar="output${nl}${nl}"  # two total. quotes preserve newlines
}

localwbudowane zaakceptuje żadnych opcji, że declarewbudowane zaakceptuje. z szybkiego testu wygląda również, że declare -nw zakresie funkcji podaje również zmienny lokalny zasięg. wydaje się, że są tutaj wymienne.
init_js
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.