Skrypty Bash odbijają się echem lokalnie w funkcji

13

W skryptach bash staram się, aby moje zmienne były lokalne dla funkcji, gdzie tylko mogę, a następnie przekazać to, czego potrzebuję, z funkcji takich jak poniżej

#!/bin/bash

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"   # return this variable
}

GLOBAL=$(FUNCTION)

echo "$GLOBAL"

Ale czy można to zrobić, uwzględniając własne echa funkcji, więc jeśli funkcja ma własne komunikaty do wysłania, nie muszę ich chwytać w zmiennej

#!/bin/bash

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"                      # return this variable
    echo "This function is done now"   # do not return this variable
}

GLOBAL=$(FUNCTION)

echo "$GLOBAL"                         # should only echo 'value'
TheLovelySausage
źródło
1
Hej, dlaczego wszyscy używacie starej, nie POSIX-owej function foo()składni? Możesz uzyskać lepszą zgodność z POSIX dzięki 9 mniejszym klawiszom.
Arthur2e5
2
Ta składnia jest mi bardziej znana
TheLovelySausage
1
@ Arthur2e5 przede wszystkim dlatego, że łatwiej jest wpisać „funkcja” niż „[a-zA-Z0-9] + \ (\) \ {” podczas przeszukiwania kodu
Alex Jansen

Odpowiedzi:

17

Wszystko, co wydrukuje funkcja, może zostać przechwycone, jeśli przechwycisz właściwy strumień wyjściowy. Tak więc najłatwiejszym sposobem wydrukowania czegoś i zapisania innego wyjścia jest przekierowanie zbędnego wyjścia na standardowy błąd:

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"
    echo "This function is done now" >&2
}

Inną możliwością jest zalogowanie się do pliku zamiast bezpośredniego drukowania komunikatów dziennika, na przykład przy użyciu czegoś takiego:

log() {
    printf '%s\n' "$@" > my.log
}

To powiedziawszy, funkcje Bash nie mogą zwracać zmiennych . Jedyną faktyczną wartością „return” jest kod wyjścia. Z tego powodu ( i wielu innych ), jeśli chcesz niezawodnego rejestrowania, zwracania wartości, obsługi wyjątków i innych, będziesz chciał użyć innego języka, takiego jak Python, Ruby lub Java.

l0b0
źródło
6

Możesz wyświetlać komunikaty informacyjne o standardowym błędzie:

function FUNCTION() {
    local LOCAL="value"
    echo "$LOCAL"                      # return this variable
    echo "This function is done now" > /dev/stderr  # goes to the screen
}

Kilka innych sugestii znajduje się w tym artykule w Linux Journal : użyj zmiennych globalnych (o których wspomniałeś, że nie wolisz) lub przekaż nazwę zmiennej, aby zwrócić wynik.

cxw
źródło
/dev/stderrwskazuje na fd 2 i nadal można go przekierować za pomocą &>blahlub 2>blah. /dev/ttymoże lepiej.
Arthur2e5