Bagaimana saya memeriksa apakah shell saya berjalan di terminal?


22

Saya ingin melakukan beberapa tindakan hanya jika shell saya "terhubung" ke terminal, yaitu hanya jika input standar saya berasal dari input terminal dan output standar saya (dan kesalahan standar? Mungkin itu tidak masalah) akan dicetak / digema ke terminal.

Bagaimana saya bisa melakukan itu, tanpa mengandalkan spesifik GNU / Linux (seperti /proc/self) secara langsung?


Jawaban:


33

isattyadalah fungsi untuk memeriksa ini , dan -tflag testperintah membuatnya dapat diakses dari skrip shell:

-t file_descriptor

Benar jika nomor deskriptor file file_descriptor terbuka dan dikaitkan dengan terminal. Salah jika file_descriptor bukan nomor deskriptor file yang valid, atau jika nomor deskriptor file file_descriptor tidak terbuka, atau jika terbuka tetapi tidak terkait dengan terminal.

Anda dapat memeriksa apakah FD 0 (input standar) adalah TTY dengan:

test -t 0

Anda dapat melakukan hal yang sama untuk FD 1 dan 2 untuk memeriksa aliran output dan kesalahan, atau semuanya:

test -t 0 -a -t 1 -a -t 2

Perintah mengembalikan 0 (berhasil) jika deskriptor dihubungkan ke terminal, dan salah jika tidak.

testjuga tersedia sebagai [perintah untuk "uji kurung":

 if [ -t 0 ] ; then ...

adalah cara idiomatis untuk menulis persyaratan ini.


8

Saya membayangkan ini adalah duplikat, tetapi saya tidak dapat menemukannya. Menggunakan

[ -t 0 ]

dan

[ -t 1 ]

untuk menguji masing-masing apakah input dan output standar terhubung ke terminal. man testmemiliki detail.


7

Hanya catatan tambahan di atas jawaban baik yang telah diberikan. Catat itu[ -t 0 ] pengujian bahwa deskriptor file 0 adalah file terbuka yang merupakan file perangkat dengan disiplin garis tty (biasanya, itu dilakukan dengan memeriksa bahwa termo (s) ioctl () yang berhasil () berhasil).

Juga, itu tidak selalu berarti ada terminal atau terminal emulator (dengan pengguna nyata mengetik pada keyboard) di ujung yang lain (meskipun dalam sebagian besar kasus dan mungkin sebagian besar yang Anda pedulikan, itu cukup bagus dan perkiraan).

perangkat tty dan pty juga dapat digunakan untuk transfer data atau sebagai mekanisme komunikasi antarproses.

Misalnya, seseorang dapat melakukan:

(stty raw -echo; myscript) < /dev/ttyS0

Untuk memberi makan apa yang diterima melalui RS232 myscript.

echo test | ssh -tt host myscript

akan memiliki myscriptstdin menjadi perangkat pty (dengansshd di ujung lainnya, dan akhirnya (di koneksi ssh) bukan terminal, tetapi pipa yang diumpankan oleh echo)

Untuk memeriksa lebih lanjut bahwa ada terminal di ujung RS232 atau pty yang lain, Anda juga dapat memeriksa bahwa suatu $TERMvariabel disetel dan tidak kosong ( [ -n "$TERM" ]) dan mengirimkan urutan keluar Laporan Status Perangkat melalui fd itu dan memeriksa bahwa Anda menerima tanggapan (selain [ -t 0 ]dan [ -n "$TERM" ]).

printf >&0 '\e[5n'

Dijawab dengan a \e[0n oleh sebagian besar terminal.

Sekarang ada beberapa masalah dengan itu, jadi saya tidak akan merekomendasikan melakukan itu kecuali dalam kasus di mana Anda ingin memeriksa itu karena Anda ingin menjalankan aplikasi TUI visual (dalam hal ini, Anda akan lebih baik menggunakan perpustakaan seperti ncurses, dan alih-alih DSR, Anda lebih suka mengirim urutan pelarian identifikasi perangkat untuk menanyakan jenis terminal lebih tepatnya daripada melalui $TERM):

  • Untungnya, dalam kebanyakan kasus di mana stdin bukan terminal, itu akan terbuka dalam mode read-only yang akan menyebabkan itu printfgagal, tetapi dalam kasus stdin adalah perangkat tty yang terbuka dalam mode baca + tulis, yang akan memiliki efek samping mengirim urutan itu ke ujung yang lain. Sebagai contoh dalam contoh ssh kami di atas, itu sebenarnya akan mengirim urutan ke terminal (tetapi jawabannya tidak akan datang pada stdin)
  • Sulit untuk membaca jawabannya dengan andal dan mudah dibawa. Anda perlu mengubah disiplin tty line sementara dan membaca satu byte pada satu waktu. Anda juga harus memutuskan batas waktu di mana jika balasan tidak terlihat, Anda menyerah dan memutuskan tidak ada terminal. Jika Anda ingin mempertimbangkan orang-orang memutar melalui koneksi satelit, itu berarti waktu tunggu yang lama.
  • Membaca dari terminal ketika di latar belakang akan menangguhkan skrip Anda dengan sinyal SIGTTIN.
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.