Bagaimana cara menentukan warna keluaran konsol saat ini?

14

Saya tahu bahwa, jika terminal berwarna tersedia, orang dapat mewarnai outputnya menggunakan karakter escape .

Tetapi apakah ada kemungkinan untuk mencari tahu, warna apa yang saat ini ditampilkan sebagai output? Atau lebih baik, apa warna teksnya, jika saya akan menampilkannya sekarang?

Saya meminta untuk tidak merusak pengaturan warna sebelumnya, saat menggunakan karakter pelarian ini. Karakter escape 'default foreground color' adalah mendapatkan informasi dari skema warna, daripada warna teks sebelum saya mengubahnya.

Minix
sumber
Melihat variabel termcap dan terminfo tampaknya itu tidak mungkin. Misalnya, Anda dapat mendapatkan jumlah warna yang mendukung terminal Anda dengan echotc Coatau echoti colors, tetapi tidak ada cukup variabel yang menyimpan kode warna saat ini definisi.
jimmij
@jimmij saya pikir begitu dan berharap, bahwa saya melewatkan sesuatu. Jika Anda cukup yakin tentang hal itu tidak mungkin, maka buatlah jawaban dan saya akhirnya akan menerimanya, jika tidak ada yang mengikuti. Terima kasih atas waktunya.
Minix

Jawaban:

10

Secara umum, mendapatkan warna saat ini tidak mungkin. Pemrosesan urutan kontrol terminal terjadi "di dalam" terminal, di mana pun itu terjadi. Dengan emulator terminal seperti xtermatau yang dibangun ke dalam kernel sistem operasi yang menyediakan terminal virtual kernel, keadaan internal emulator, termasuk gagasan tentang "rendition grafis" saat ini (yaitu warna dan atribut), ada di mesin itu sendiri dan secara teori dapat diakses. Tetapi untuk terminal nyata, informasi ini ada di beberapa lokasi RAM pada mesin yang secara fisik terpisah terhubung melalui tautan serial.

Yang mengatakan, beberapa terminal menyertakan mekanisme untuk membaca informasi seperti sebagai bagian dari protokol terminal mereka, yang dikirim melalui tautan serial itu. Mereka memberikan urutan kontrol yang dapat dikirim oleh sebuah program ke terminal, yang menyebabkannya mengirim kembali informasi tentang keadaan internalnya, sebagai input terminal. mikeservtelah menunjukkan kepada Anda urutan kontrol yang xtermmerespons emulator terminal. Tetapi ini khusus untuk xterm. Emulator terminal bawaan di kernel Linux dan berbagai kernel BSD adalah tipe terminal yang berbeda, misalnya, dan tidak menerapkan urutan kontrol seperti itu sama sekali. Hal yang sama berlaku untuk seluruh keluarga terminal nyata.

Terminal DEC VT525 menerapkan mekanisme pembacaan, tetapi memiliki serangkaian rangkaian kontrol yang tidak memiliki hubungan dengan yang digunakan oleh xterm. Seseorang mengirim urutan DECRQSS (Permintaan Pemilihan atau Pengaturan) untuk meminta rendisi grafik saat ini, dan terminal merespons dengan mengirimkan DECRPSS (Pemilihan atau Pengaturan Laporan). Secara khusus:

  1. Host mengirim: DCS $ q mST (DECRQSS dengan bagian fungsi kontrol SGR sebagai pengaturan)
  2. Terminal merespon: DCS 0 $ r 0 ; 3 3 ; 4 4 mST (DECRPSS dengan bagian parameter dan fungsi kontrol dari rangkaian kontrol SGR yang mengatur warna foreground dan background saat ini)

Tentu saja, pembacaan yang cermat atas pertanyaan Anda mengungkapkan bahwa Anda mengayunkan pisang yang dilapisi cokelat di sistem mata uang Eropa itu lagi. Apa yang sebenarnya Anda coba lakukan, yang telah Anda pilih solusi dan kemudian bertanya bagaimana melakukan bagian dari solusi itu, adalah mempertahankan keadaan sebelumnya sementara Anda menulis beberapa output berwarna. Tidak hanya ada urutan kontrol DEC VT untuk melakukan hal ini, ada urutan terminal konsol SCO untuknya yang dikenali oleh xtermdan berbagai emulator terminal bawaan kernel, dan entri termcap / terminfo yang memberi tahu Anda apa artinya untuk terminal Anda.

Entri termcap adalah scdan rc. Entri terminfo adalah save_cursordan restore_cursor. Nama-nama tersebut agak menyesatkan sebagai efek (meskipun mereka bertindak sebagai peringatan bahwa Anda mengandalkan sesuatu yang secara de facto daripada de jure ). Urutan kontrol DECSC, DECRC, SCOSC, dan SCORC yang sebenarnya juga menyimpan dan mengembalikan rendisi grafik saat ini.

Mengingat bahwa artikel yang Anda tunjuk adalah tentang menghasilkan urutan kontrol dari skrip shell, perintah yang Anda cari sekarang adalah tput.

Bacaan lebih lanjut

JdeBP
sumber
Jawaban yang bagus Senang saya kembali untuk itu. Terima kasih banyak.
Minix
@ Minx - selain scdan rc, Anda mungkin juga ingin melihat ke buffer alternatif jika terminal Anda mendukungnya. Dan ya, ini adalah jawaban yang bagus. Minix, mungkin juga lihat ini: cara menggunakan / dev / fb0 sebagai konsol dari userspace . The noshSuite dia merekomendasikan ada sendiri.
mikeserv
@ mikeserv saya akan memeriksanya, terima kasih untuk tautannya :)
Minix
2
Melihat ini "tidak memiliki hubungan dengan yang digunakan oleh xterm" - namun, xterm mendukung DECRQSS untuk sementara waktu. Bagian dengan respons SGR termasuk tanggal warna hingga 1996.
Thomas Dickey
2
Lihat Bacaan Lebih Lanjut , dalam dokumentasi sekuens kontrol xterm, yang menunjukkan bahwa dokumentasi VT520 / etc tidak tersedia ketika xterm mulai memberikan warna DECRQSS(sekitar 7 tahun menunda ...).
Thomas Dickey
10

Dalam xtermAnda bisa mendapatkan kode warna RGB warna saat ini dilaporkan dengan mengubah melarikan diri perubahan warna ke permintaan. Gunakan ESC ] Ps m- tetapi tambahkan ?tanda tanya. Dari dokumen :

  • Jika a "?"diberikan alih-alih nama atau spesifikasi RGB, xtermbalas dengan urutan kontrol dengan bentuk yang sama yang dapat digunakan untuk mengatur warna dinamis yang sesuai. Karena lebih dari satu pasang nomor warna dan spesifikasi dapat diberikan dalam satu urutan kontrol, xtermdapat membuat lebih dari satu balasan.
    • P s = 1 0 → Ubah warna foreground teks VT100 menjadi P. t.
    • P s = 1 1 → Ubah warna latar belakang teks VT100 ke P. t.
    • P s = 1 2 → Ubah warna kursor teks ke P. t.
    • P s = 1 3 → Ubah warna foreground mouse ke P. t.
    • P s = 1 4 → Ubah warna latar belakang mouse ke P. t.
    • Ps = 1 5 → Ubah warna latar depan Tektronix ke Pt.
    • Ps = 1 6 → Ubah warna latar belakang Tektronix ke Pt.
    • Ps = 1 7 → Ubah warna latar belakang sorot ke P. t.
    • Ps = 1 8 → Ubah warna kursor Tektronix ke Pt.
    • Ps = 1 9 → Ubah warna foreground highlight menjadi Pt.

Saya memiliki keraguan serius apakah ini mungkin bekerja di terminal emulator lain, tetapi xtermjika Anda menjalankan ...

printf '\033]11;?\007'

... xtermakan mendorong kembali ke buffer input terminal Anda urutan seperti berikut ...

11;rgb:ffff/ffff/ffff

... untuk latar belakang atau latar depan:

printf '\033]10;?\007'

10;rgb:0000/0000/0000
mikeserv
sumber
Jadi ketika saya menjalankan printf '\033]10;rgb:8f8f/8f8f/8f8f8f\007, semua teks di terminal yang sebelumnya "normal" berubah menjadi biru muda. Selanjutnya, menjalankan printf '\033]10;rgb:bfbfbf/bfbfbf/bfbfbf\007'mengubah semua teks biru muda kembali ke "normal". Bagaimana cara menggunakan nilai ini untuk hanya mengubah warna teks yang bergerak maju?
fourpastmidnight
@fourpastmidnight: mungkin cleardulu?
mikeserv
Saya pikir saya tidak mengerti dokumentasinya. Itu jelas mengatakan "P s = 1 0 -> ubah warna latar depan VT100", dan itulah yang tampaknya dilakukan. ;) Tapi bukan itu yang saya harapkan. Saya mungkin perlu menggunakan nilai RGB yang diambil dari "P s = 1 0; Pt =?" dengan perintah melarikan diri lain untuk mencapai apa yang saya inginkan.
fourpastmidnight
Ok, jadi printf '\033]10;?\007'tanyakan xterm untuk warna foreground terminal saat ini. Jika terminal Anda dimulai dengan "normal" (mis. 7 sebagai warna latar depan), tetapi Anda menjalankan tput setaf 3sebelum menjalankan printfperintah, printfperintah di atas masih mengembalikan "normal" - dan itu benar, karena itulah warna latar depan terminal Anda saat ini. Apa yang saya harapkan adalah cara untuk mengambil warna saat ini dari posisi kursor saat ini sehingga saya bisa menyimpannya untuk "mengembalikan" nanti - sesuai OP.
fourpastmidnight
1
@fourpastmidnight - apakah Anda mengikuti tautan dalam jawaban di sini? juga, Thomas Dickey - (dia mengomentari jawaban lain untuk pertanyaan ini) adalah xtermpemelihara dan anggota aktif di sini. (tautannya ke situs webnya - xtermdokumen pelariannya luas - dan pada dasarnya referensi standar untuk setiap programmer lain yang ingin menulis terminal)
mikeserv