Inilah produk akhir yang bekerja pada xterm layar terbagi dari dasarnya shell untuk bekerja hanya dalam beberapa perintah:

Cara yang lebih kasar untuk melakukan ini daripada yang ditunjukkan dalam tangkapan layar mungkin terlihat seperti ini:
PS1='$( { date ; fc -l -0 ; } >${TGT_PTY} )'$PS1
Di mana ${TGT_PTY}akan menjadi apa pun yang Anda dapatkan dari ttyperintah ketika benar-benar menjalankan shell interaktif di layar di mana Anda ingin output Anda. Atau, sungguh, Anda bisa menggunakan file yang dapat ditulis sama sekali karena pada dasarnya hanya target untuk pengalihan file.
Saya menggunakan sintaks pty untuk pseudo-terminal karena saya menganggap itu adalah xterm dari beberapa jenis, tetapi Anda mungkin dengan mudah mendedikasikan vt - dan sejarah streaming Anda selalu hanya merupakan CTRL-ALT-Fnkombo kunci. Jika itu aku, aku mungkin menggabungkan dua gagasan dan membuatnya menjadi screenatau tmuxsesi pada vt khusus ... Tapi aku ngelantur.
Pada mesin yang baru saja boot saya disambut dengan /bin/loginprompt khas pada gettykonsol Linux yang khas . Saya menekan CTRL-ALT-F2untuk mengakses kmsconkonsol yang kurang umum yang berperilaku lebih seperti xterma tty. Saya memasukkan perintah ttydan menerima sebagai tanggapan /dev/pts/0.
Umumnya xterms multipleks perangkat terminal tunggal menjadi banyak menggunakan pseudo-terminal - jadi jika Anda melakukan hal serupa di X11 dengan beralih di antara tab terminal atau windows Anda kemungkinan akan menerima output /dev/pts/[0-9]*juga. Tetapi konsol terminal virtual yang diakses dengan CTRL-ALT-Fnkombinasi kunci adalah perangkat terminal yang benar (er) dan karenanya menerima /dev/tty[0-9]*peruntukannya sendiri .
Inilah sebabnya mengapa setelah masuk ke konsol 2 ketika saya mengetik ttydi prompt jawabannya adalah /dev/pts/0tetapi ketika saya melakukan hal yang sama pada konsol 1 hasilnya /dev/tty1. Bagaimanapun, kembali pada konsol 2 saya kemudian lakukan:
bash
PS1='$( { date ; fc -l -0 ; } >/dev/tty1 )'$PS1
Tidak ada efek yang terlihat. Saya terus mengetik beberapa perintah lagi dan kemudian saya beralih ke konsol 1 dengan menekan CTRL-ALT-F1lagi. Dan di sana saya menemukan entri berulang yang terlihat seperti <date_time>\n<hist#>\t<hist_cmd_string>untuk setiap perintah yang saya ketikkan pada konsol 2.
Pembatasan langsung menulis ke perangkat terminal, opsi lain dapat terlihat seperti:
TGT_PTY=
mkfifo ${TGT_PTY:=/tmp/shell.history.pipe}
{ echo 'OPENED ON:'
date
} >${TGT_PTY}
Dan mungkin ...
less +F ${TGT_PTY}
Perintah prompt kasar tidak memenuhi spesifikasi Anda - tidak ada string format untuk datedan tidak ada opsi format fcbaik - tetapi mekanismenya tidak memerlukan banyak: setiap kali prompt Anda membuat perintah riwayat terakhir dan tanggal dan waktu saat ini ditulis untuk yang ${TGT_PTY}file yang Anda tentukan. Sesederhana itu.
Menonton dan mencetak riwayat shell adalah fctujuan utama. Ini adalah built-in shell, meskipun datetidak. Di zsh fcdapat memberikan semua jenis opsi pemformatan mewah, beberapa di antaranya berlaku untuk cap waktu. Dan tentu saja, seperti yang Anda perhatikan di atas, bash's historydapat melakukan hal yang sama.
Untuk kepentingan output yang lebih bersih, Anda dapat menggunakan teknik yang saya jelaskan lebih baik di sini untuk mengatur variabel pelacakan persisten di shell saat ini meskipun harus melacak dan memprosesnya dalam subkulit dalam urutan cepat.
Berikut cara portabel memformat dengan spesifikasi Anda:
_HIST() { [ -z ${_LH#$1} ] ||
{ date "+${1}%t[%F %T]"
fc -nl -0
} >${TGT_PTY}
printf "(_LH=$1)-$1"
}
: "${_LH=0}"
PS1='${_LH##*[$(($(_HIST \!)))-9]}'$PS1
Saya menerapkan penghitung last_history$_LH yang hanya melacak pembaruan terbaru sehingga Anda tidak menulis perintah sejarah yang sama dua kali - misalnya hanya untuk menekan enter. Ada sedikit perselisihan yang diperlukan untuk mendapatkan variabel yang bertambah dalam shell saat ini sehingga tetap mempertahankan nilainya meskipun fungsinya disebut dalam subkulit - yang, sekali lagi, lebih baik dijelaskan dalam tautan .
Outputnya seperti <hist#>\t[%F %T]\t<hist_cmd>\n
Tapi itu hanya versi yang sepenuhnya portabel. Dengan bashitu dapat dilakukan dengan lebih sedikit dan dengan menerapkan shell builtins saja - yang mungkin diinginkan ketika Anda menganggap bahwa ini adalah perintah yang akan berjalan setiap kali Anda menekan [ENTER]. Berikut ini dua cara:
_HIST() { [ -z ${_LH#$1} ] || {
printf "${1}\t[%(%F %T)T]"
fc -nl -0
} >${TGT_PTY}
printf "(_LH=$1)-$1"
}
PROMPT_COMMAND=': ${_LH=0};'$PROMPT_COMMAND
PS1='${_LH##*[$(($(_HIST \!)))-9]}'$PS1
Atau, menggunakan bash's historyperintah, Anda dapat menentukan _HISTfungsi dengan cara ini:
_HIST() { [ -z ${_LH#$1} ] ||
HISTTIMEFORMAT="[%F %T]<tab>" \
history 1 >${TGT_PTY}
printf "(_LH=$1)-$1"
}
Output untuk kedua metode juga terlihat seperti: <hist#>\t[%F %T]\t<hist_cmd>\nmeskipun historymetode ini menyertakan beberapa spasi putih terkemuka. Namun, saya percaya historycap waktu metode akan lebih akurat karena saya pikir mereka tidak perlu menunggu perintah yang dirujuk untuk menyelesaikan sebelum mendapatkan cap mereka.
Anda dapat menghindari pelacakan keadaan apa pun dalam kedua kasus jika hanya Anda yang entah bagaimana menyaring aliran uniq- seperti yang mungkin Anda lakukan dengan yang mkfifosaya sebutkan sebelumnya.
Tetapi melakukannya di prompt seperti ini berarti selalu diperbarui hanya jika perlu hanya dengan tindakan memperbarui prompt. Itu mudah.
Anda mungkin juga melakukan sesuatu yang mirip dengan apa yang Anda lakukan tailtetapi lebih pada pengaturan
HISTFILE=${TGT_PTY}
fn+1membandingkan! Terima kasih!