通過將字元串放入 tty 來構造命令
我設法做到了
echo -n "*命令*" > /dev/tty1
字母出現,游標移動,但它們是“幽靈”——如果你點擊
Enter
,什麼都不會發生(它們不在標準輸入中)。編輯:
在下面的螢幕截圖中間,你會明白為什麼我會看到它的用途。(帶有紅色標題的行,就在帶有黃色標題的行下方。)現在,您並沒有真正“編輯”註釋文本。你只是被要求寫一個新的文本,它將替換你正在(不是真的)編輯的筆記的文本。因此,我認為可以通過簡單地將舊文本粘貼到 tty 中來補救:如果使用者按 Enter,則不會進行任何修改。(這個程序在 Perl/MySQL 中,但我認為尋求通用解決方案比“我如何在 Perl 中做到這一點”更有趣。)
編輯2:
這是 Perl 程式碼,它使用下面的 C 程式碼(完全按照預期工作),以及一個新的螢幕截圖 - 希望這將澄清毫無疑問的事情 :) 再次查看螢幕截圖的中間,進行編輯到註釋文本 - 這一次,舊文本在那裡,例如,如果您只是想修正一個錯字,您不必重新輸入整個註釋文本。
my $edit_note_text = $edit_note_data[2]; print BOLD, RED, " new text: ", RESET; system("writevt /dev/tty \"$edit_note_text\""); my $new_text = <$in>; $new_text = fix_input($new_text); my $set_text = "UPDATE notes SET note = \"$new_text\" WHERE id = $edit_note_id"; $db->do($set_text);
終端兼作兩件事:輸入設備(如鍵盤)和顯示設備(如監視器)。當您從終端讀取時,您會得到來自輸入設備的內容。當您寫入終端時,數據會進入顯示設備。
沒有強制輸入到終端的一般方法。很少有必要這樣做。如果您需要與需要終端的程序互動,請使用專用終端仿真器,例如Expect或Empty,或可程式終端包裝器,例如Screen或Tmux。您可以使用 ioctl強制輸入到 Linux 控制台。您可以使用xdotool或xmacro等工具強制輸入 X11 終端仿真器。
至少 Linux 和 BSD 有 TIOCSTI ioctl 將字元推回終端輸入緩衝區(最多限制
$$ 4096 characters on Linux $$):
#include <sys/ioctl.h> #include <termios.h> #include <stdio.h> #include <stdlib.h> void stackchar(char c) { if (ioctl(0, TIOCSTI, &c) < 0) { perror("ioctl"); exit(1); } } int main(int argc, char *argv[]) { int i, j; char c; for (i = 1; i < argc; i++) { if (i > 1) stackchar(' '); for (j=0; (c = argv[i][j]); j++) { stackchar(c); } } exit(0); }
編譯它,並將其稱為:
cmd foo bar < "$some_tty"
將字元推回某些 tty。
在 perl 中:
require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_) for split "", join " ", @ARGV;
編輯:我現在意識到它與writevt解決方案中的 ioctl 相同。該命令的註釋和名稱具有誤導性,因為 TIOCSTI 適用於任何終端,而不僅僅是 VT。