2010-06-29 17 views
5

Przykład:Zwraca jedną wartość z funkcji skryptu powłoki

#!/bin/sh 

a() { 
R=f 
ls -1 a* 
[ "$?" == "1" ] && { R=t; } 
echo $R 
} 

r=`a` 
echo $r 

$r zawiera t lub f ale również wyjście polecenia do ls.

Mogę napisać ls -1 a* >/dev/null 2>/dev/null, ale jeśli jest bardziej złożony skrypt, który może prowadzić do błędów.

Czy istnieje sposób zwrócenia pojedynczej wartości z a()?

+0

'r = $ (a); echo $ r' może oczywiście zostać zastąpione właśnie' a'. –

Odpowiedz

4

Funkcja powłoki może zwrócić wartość liczbową. Rozważmy 0 i 1 zamiast „f” i „t”

#!/bin/sh 

a() { 
R=0 
ls -1 a* 
[ "$?" == "1" ] && { R=1; } 
return $R 
} 

a 
r=$? 
echo $r 

To będzie jeszcze napisać wyjście z ls -1 a* który prawdopodobnie nadal chce wyrzucać, ale wartość r będzie albo 0 albo 1 i wygrał nie obejmują wyjścia.

Inne przykłady przekierowania wyjścia z linii lub całego bloku są dobre i, jak sugerowali inni, powinniście poznać inne sposoby testowania warunków (ale zakładałem, że ls było swego rodzaju arbitralne przykład)

+0

Dlaczego nie ominąć całej funky z '$ R' i po prostu uruchomić' ls', a następnie 'return $?'? – Caleb

+0

@Caleb - ta odpowiedź jest modyfikacją oryginalnego skryptu PeterMmm, aby zademonstrować, w jaki sposób funkcja powłoki może zwrócić wartość. Jestem pewna, że ​​ta cała funkcja próbki może być pominięta, ale nie wiem, co mógł robić w swoim prawdziwym kodzie. –

0
a() { 
ls -1 a* > /dev/null 
[ "$?" == "0" ] && echo t || echo f 

} 

r=`a` 
echo $r 

Należy również rozważyć użycie [-f filename] i innych testów plików.

1

Nie trzeba używać ls, aby sprawdzić pliki rozpoczynające się od a. Wystarczy użyć powłoki

a() { 
    shopt -s nullglob 
    ret="f" 
    for file in a* 
    do 
    ret="t" 
    break 
    done 
    echo "$ret" 
} 
+0

To jest przykład, nie moje pytanie. Jak mogę uniknąć pisania wszędzie ">/dev/null 2>/dev/null", gdy chcę mieć pojedynczą wartość/ciąg znaków z funkcji skryptu. – PeterMmm

1

można umieścić przekierowanie na liście poleceń:

 
{ 
    command1 
    command2 
} >/dev/null 

Jeśli w pewnym momencie w skrypcie nie ma żadnego wyjścia z kolejnych poleceń, można przekierować wyjście przez powłokę z exec wbudowanego polecenia:

 
echo interesting 
exec >/dev/null 
echo boring 

Zauważ, że to trwa aż do końca scenariusza, a nie tylko do końca funkcji. Zajmuje się poleceniami po interesującym, ale nie wcześniej.

Istnieje sposób na odwrócenie efektu exec /dev/null, za pomocą manipulacji deskryptorem pliku. Niekoniecznie jednak to zalecam, ponieważ w praktyce może to być trudne. Chodzi o to, aby przenieść wszystko, co jest podłączone do standardowego wyjścia, do innego deskryptora, a następnie przekierować standardowe wyjście do innego pliku, a na koniec przenieść oryginalne standardowe wyjście z powrotem na standardowe wyjście.

 
{ 
    exec 3>&1   # duplicate fd 3 to fd 1 (standard output) 
    exec >/dev/null # connect standard output to /dev/null 
    echo boring 
    exec 1>&3   # connect standard output back to what was saved in fd 3 
    echo interesting 
    exec >/dev/null # connect standard output to /dev/null again 
    echo more boring 
} 3>/dev/null  # The braced list must have its fd 3 connected somewhere, 
        # even though nothing will actually be written to it. 
Powiązane problemy