Bagaimana saya bisa memeriksa di bash jika shell berjalan dalam mode interaktif?

46

Bagaimana saya bisa tahu (dalam ~/.bashrc) jika saya menjalankan dalam mode interaktif, atau, katakanlah, mengeksekusi perintah melalui ssh. Saya ingin menghindari pencetakan urutan pelarian ANSI .bashrcjika itu yang terakhir.

Alex B
sumber
Memilih apakah akan mencetak urutan pelepasan atau tidak lebih baik berdasarkan pada nilai $ TERM dan bukan pada interaktivitas dari shell. Variabel mengidentifikasi kemampuan terminal klien yang merupakan bagian yang menafsirkan urutan melarikan diri.
yrk

Jawaban:

53

Menurut man bash:

PS1 diatur dan $ - termasuk saya jika bash bersifat interaktif, memungkinkan skrip shell atau file startup untuk menguji keadaan ini.

Jadi Anda bisa menggunakan:

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

Juga:

Ketika shell interaktif yang bukan shell login dimulai, bash membaca dan mengeksekusi perintah dari /etc/bash.bashrc dan ~ / .bashrc, jika file-file ini ada.

Jadi ~/.bashrchanya bersumber untuk kerang interaktif. Terkadang, orang sumbernya dari ~/.bash_profileatau ~/.profileyang tidak benar karena mengganggu perilaku yang diharapkan. Jika Anda ingin menyederhanakan pemeliharaan kode yang umum, Anda harus menggunakan file terpisah untuk berisi kode umum dan sumbernya secara independen dari kedua file rc.

Lebih baik jika tidak ada output untuk stdout dari rcfile login seperti ~/.bash_profileatau ~/.profilekarena dapat mengganggu operasi yang tepat rsyncmisalnya.

Bagaimanapun, itu masih ide yang baik untuk menguji interaktivitas karena konfigurasi yang salah mungkin ada.

Dennis Williamson
sumber
7
Perhatikan bahwa $ - mungkin mengandung i, belum tentu sama dengan itu. Saya menggunakan[[ $- =~ i ]] && echo interactive
Alex Howansky
1
@AlexHowansky: tanda bintang dalam tes kesetaraan menjadikannya ujian untuk mengandungi
Dennis Williamson
Oh wow bahkan tidak memperhatikan itu, mereka terlihat seperti tanda kutip ganda pada monitor saya. Mungkin sudah waktunya untuk menaikkan ukuran font. <semakin tua>
Alex Howansky
Kadang-kadang, orang-orang mengambilnya dari ~/.bash_profileatau ~/.profileyang tidak benar karena itu mengganggu perilaku yang diharapkan . Apa yang Anda pikirkan sumber ~/.bashrcdari ~/.bash_login? Karena shell login tidak perlu bersifat interaktif, saya kira itu juga tidak benar.
Piotr Dobrogost
1
@PiotrDobrogost: Ini adalah diskusi yang sangat baik tentang file startup shell.
Dennis Williamson
12

Menggunakan:

if tty -s; then echo interactive; fi
Sorin
sumber
Tampaknya tidak berhasil
Steven Shaw
ini sepertinya tidak bekerja untuk saya juga, saya pikir ini adalah jawaban yang benar: stackoverflow.com/a/49064632/1223975
Alexander Mills
ini memeriksa keberadaan TTY pada input standar; walaupun bisa dihubungkan tetapi tidak sama dengan mode interaktif shell, yang ditandai dengan flag "-i" shell.
yrk
tidak bekerja mengapa orang dibesarkan?
Setop
11

yang testalat dapat memeriksa ini (dari halaman manual):

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

Jadi bisa Anda gunakan misalnya:

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

atau

if [ -t 1 ] ; then
    echo stdout is a terminal
 fi
pengguna4514
sumber
Bagus dan tampaknya portabel di antara cangkang. UJI itu bash <<< 'test -t 0 && echo Y || echo X'menulis Y, bash -c 'test -t 0 && echo Y || echo X'menulisX
kyb
1
ini juga memverifikasi bahwa input standar adalah TTY; walaupun ini dapat dihubungkan tetapi BUKAN sama dengan mode interaktif shell, yang diminta dan ditunjukkan oleh flag "-i" shell.
yrk
6

Saya biasanya melihat output dari tty program.

Jika Anda berada di tty, itu akan memberi tahu Anda tty mana Anda berada. Jika Anda tidak dalam mode interaktif, biasanya akan memberi tahu Anda sesuatu seperti "bukan tty".

chris
sumber
3
tty -s akan menetapkan nilai balik 0 jika Anda berada di terminal atau 1 sebaliknya tanpa memberikan Anda output. Anda dapat menggunakannya sebagai 'jika tty -s; kemudian _interaktif; fi '
BillThor
Terima kasih! Sudah lama sejak saya harus melakukan hal semacam ini dan saya kira saya lupa beberapa detail ...
chris