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.

Alex B.
źródło
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.

Dennis Williamson
źródło
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
sorin
źródło
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
użytkownik4514
źródło
Ł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”.

Chris
źródło
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