2012-09-11 12 views
17

Nie mogę tego obejść. Dlaczego /dev/null byłby używany jako dane wejściowe do instrukcji if? Jaki jest pożytek z następujących czynności: < /dev/null?if()</ dev/null

if ($PROG --version) </dev/null> /dev/null 2>&1; then 
     $PROG 
else 
     echo "failed" 
     exit 1 
fi 

I (chyba) Rozumiem, że > /dev/null 2>&1 jest właśnie używany do tłumienia żadnego wyjścia z obu stdout i stderr.

Odpowiedz

15

Jeśli $PROG to program, który przewiduje wejście od stdin, skrypt może opóźnić zawsze czeka, aby wpisać coś. Zastosowanie < /dev/null jest dostarczenie pustej wejście do takiego programu. Masz rację co do > i 2>&1.

Ten fragment skryptu sprawdza, czy $PROG --version kończy działanie ze statusem 0 (powodzenie), a następnie uruchamia ten program bez żadnych flag. Jeśli nie powiedzie się $PROG --version, skrypt wyświetli "błąd" i zakończy działanie.

+0

Dzięki. Nadal nie jestem pewien, na ile jest to przydatne, jeśli wiem, czym jest '$ PROG' i wiem, że' PROG --version' nie czeka na dane wejściowe. Na przykład 'PROG = autoconf' to taki, w którym to zobaczyłem.I wiem, że 'autoconf --version' nie czeka na dane wejściowe. Czy nadal jest przydatna w tym przypadku? –

+0

@Carl Norum, czy można użyć 'if ('$ PROG --version')' (z nawiasami ostrymi), aby wykonać polecenie, a zatem nie ma potrzeby używania ' fduff

+0

Uchwyty kątowe? –

13

Myślę, że zastanawiasz się, dlaczego przekierowanie jest poza nawiasami.

W tej linii:

if ($PROG --version) </dev/null> /dev/null 2>&1; then 

nawiasy nie są częścią składni rachunku if; po prostu określają grupy poleceń. (Zajęło mi chwilę, aby pamiętać, że sam; w csh/tcsh nawiasach częścią składni instrukcji if.)

Na przykład ten:

(echo one ; echo two) | tr a-z A-Z 

przyniesie to wyjście :

ONE 
TWO 

W tym przypadku, ponieważ $PROG --version jest jedno polecenie, nawiasy są konieczne (chyba $PROG rozszerza się do więcej niż jednego polecenia, ale to mało prawdopodobne).

Tak więc przekierowanie nie ma zastosowania do instrukcji if; dotyczy to $PROG --version. Celem jest zapewnienie braku danych wejściowych (tak jak czytanie z pustego pliku) do $PROG i odrzucić wszystko, co napisze do stdout lub stderr. Jeśli $PROG jest poleceniem odczytującym ze standardowego wejścia, nawet po wywołaniu z --version, to bez przekierowania wejścia może zawiesić oczekiwanie na wejście klawiatury.

Skrypt zakłada, że ​​można bezpiecznie wywołać $PROG (cokolwiek może być) tylko wtedy, gdy $PROG --version nie spowoduje błędu.

pamiętać, że może zastosować przekierowanie do if:

if test_command ; then 
    something 
else 
    something_else 
fi </dev/null> /dev/null 2>&1 

ten przekierowuje wejście i wyjście dla test_command, something, isomething_else.

+0

Dziękuję za wspaniałą odpowiedź! Byłem rzeczywiście zdezorientowany w odniesieniu do nawiasów. Dziękuję za podzielenie się mną i za podanie przykładów. Świetne wyjaśnienie. –