Jak mogę sprawdzić w bash, jeśli powłoka działa w trybie interaktywnym?


46

Jak mogę powiedzieć (in ~/.bashrc), czy działam w trybie interaktywnym lub, powiedzmy, wykonując polecenie przez ssh. Chcę uniknąć drukowania sekwencji ucieczki ANSI, .bashrcjeśli to ta ostatnia.


Wybór, czy drukować sekwencje specjalne, czy nie, lepiej oprzeć na wartości $ TERM, a nie na interaktywności powłoki. Zmienna identyfikuje możliwości terminala klienta, który jest częścią, która interpretuje sekwencje specjalne.
— yrk

Odpowiedzi:


53

Według man bash:

PS1 jest ustawione, a $ - obejmuje i, jeśli bash jest interaktywny, pozwalając skryptowi powłoki lub plikowi startowemu przetestować ten stan.

Możesz więc użyć:

if [[ $- == *i* ]]
then
    do_interactive_stuff
fi

Również:

Po uruchomieniu interaktywnej powłoki, która nie jest powłoką logowania, bash czyta i wykonuje polecenia z /etc/bash.bashrc i ~ / .bashrc, jeśli te pliki istnieją.

~/.bashrcJest więc pozyskiwany tylko dla interaktywnych powłok. Czasami ludzie ją pozyskują ~/.bash_profilelub ~/.profilejest ona niepoprawna, ponieważ przeszkadza w oczekiwanym zachowaniu. Jeśli chcesz uprościć obsługę wspólnego kodu, powinieneś użyć osobnego pliku, aby zawrzeć wspólny kod i uzyskać go niezależnie od obu plików rc.

Najlepiej, jeśli nie ma wyjścia do wyjścia z rcplików logowania , takich jak ~/.bash_profilelub, ~/.profileponieważ może to zakłócać rsyncna przykład prawidłowe działanie .

W każdym razie dobrym pomysłem jest przetestowanie interaktywności, ponieważ może istnieć niepoprawna konfiguracja.


7
Zauważ, że $ - może zawierać i, niekoniecznie równe. Używam[[ $- =~ i ]] && echo interactive
— Alex Howansky

1
@AlexHowansky: gwiazdki w teście równości sprawiają, że jest to test na przechowywaniei
— Dennis Williamson

Och, wow nawet ich nie zauważył, wyglądają jak podwójne cudzysłowy na moim monitorze. Może być czas na zwiększenie rozmiaru czcionki. <zestarzeć się>
— Alex Howansky

Czasami ludzie go pozyskują ~/.bash_profilelub ~/.profilejest on niepoprawny, ponieważ koliduje z oczekiwanym zachowaniem . Co sądzisz o zaopatrywaniu ~/.bashrcod ~/.bash_login? Ponieważ powłoka logowania nie musi być interaktywna, wydaje mi się, że jest również niepoprawna.
— Piotr Dobrogost

1
@PiotrDobrogost: To doskonała dyskusja na temat plików startowych powłoki.
— Dennis Williamson,

12

Posługiwać się:

if tty -s; then echo interactive; fi

Wygląda na to, że nie działa
— Steven Shaw,

Wydaje mi się, że to też nie działa, myślę, że to poprawna odpowiedź: stackoverflow.com/a/49064632/1223975
— Alexander Mills

sprawdza to obecność TTY na standardowym wejściu; chociaż może być powiązany, ale nie jest tym samym co tryb interaktywny powłoki, na co wskazuje flaga „-i” powłoki.
— yrk

nie działa. dlaczego ludzie głosowali?
— Setop

11

testnarzędzie może to sprawdzić (od strony man):

 -t FD          True if FD is opened on a terminal.

Możesz więc użyć na przykład:

 if [ -t 0 ] ; then
    echo stdin is a terminal
   .....
 fi

lub

if [ -t 1 ] ; then
    echo stdout is a terminal
 fi

Ładne i wydaje się być przenośne między pociskami. TEST bash <<< 'test -t 0 && echo Y || echo X'pisze Y, bash -c 'test -t 0 && echo Y || echo X'piszeX
— Kyb

1
sprawdza to również, czy standardowym wejściem jest TTY; chociaż można go powiązać, ale NIE jest on tym samym co tryb interaktywny powłoki, który jest wymagany i wskazywany przez flagę „-i” powłoki.
— yrk

6

Zwykle patrzę na wynik programu tty.

Jeśli jesteś na tty, powie ci, na którym ty jesteś. Jeśli nie jesteś w trybie interaktywnym, zwykle powie ci coś w stylu „nie tty”.


3
tty -s ustawi wartość zwracaną na 0, jeśli jesteś na terminalu lub 1 w przeciwnym wypadku, nie dając ci danych wyjściowych. Możesz użyć go jako „if tty -s; następnie _interactive; fi '
— BillThor

Dzięki! Minęło dużo czasu, odkąd musiałem robić takie rzeczy i chyba zapomniałem o niektórych szczegółach ...
— Chris
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.