Udało mi się to zrobić
echo -n " polecenie "> / dev / tty1
Pojawiają się litery i kursor się porusza, ale są one „duchami” - jeśli trafisz Enter, nic się nie wydarzy (nie są ustawione na standardowe).
Edytować:
Pośrodku poniższego zrzutu ekranu widać, dlaczego widzę zastosowanie tego. (Linia z czerwonym podpisem, tuż pod linią z żółtym podpisem.) W tej chwili tak naprawdę nie „edytujesz” tekstu notatki; zostałeś poproszony o napisanie nowego tekstu, który zastąpi tekst notatki, którą (tak naprawdę) nie edytujesz. Pomyślałem więc, że można temu zaradzić, po prostu wklejając stary tekst do tty: jeśli użytkownik naciśnie klawisz Enter, nie zostaną wprowadzone żadne zmiany. (Ten program jest w Perlu / MySQL, ale pomyślałem, że bardziej interesujące byłoby poprosić o ogólne rozwiązanie niż „jak to zrobić w Perlu”).
Edycja 2:
Oto kod Perla, który używa poniższego kodu C (działa dokładnie zgodnie z przeznaczeniem), a także nowy zrzut ekranu - mam nadzieję, że wyjaśni to ponad wszelką wątpliwość :) Ponownie spójrz na środek zrzutu ekranu, w którym dokonano edycji do tekstu notatki - tym razem znajduje się stary tekst, na przykład jeśli chcesz tylko poprawić literówkę, nie będziesz musiał ponownie wpisywać całego tekstu notatki.
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);
Odpowiedzi:
Właśnie znalazłem mały program o nazwie C,
writevt
który działa. Pobierz kod źródłowy tutaj . Aby go skompilować,gcc
najpierw usuń następujące linie:Aktualizacja . Polecenie jest teraz częścią narzędzi konsolowych , a zatem dostępnych w nowszych systemach, chyba że twoja dystrybucja używa kbd zamiast narzędzi konsolowych , w którym to przypadku możesz skompilować go ze źródła (znacznie nowsza wersja, nie jest wymagana modyfikacja).
Stosowanie:
Pamiętaj, że z jakiegoś powodu musisz użyć
'\r'
(lub'\x0D'
) zamiast'\n'
(lub'\x0A'
), aby wysłać zwrot.źródło
progname
a_
i skomentować kilka wywołań funkcjimain()
_()
Funkcja jest zwykle oznaką użycia gettext . Wydaje się to trochę przesadne jak na tak prosty fragment kodu demonstracyjnego, ale chyba nie zaszkodzi.writevt.c
tutaj (na github.com/ grawity ) ; wydaje się, że jest to zasadniczo ten sam program.Terminal podwaja się jako dwie rzeczy: urządzenie wejściowe (takie jak klawiatura) i urządzenie wyświetlające (takie jak monitor). Kiedy czytasz z terminala, dostajesz to, co pochodzi z urządzenia wejściowego. Gdy piszesz do terminala, dane trafiają na urządzenie wyświetlające.
Nie ma ogólnego sposobu na zmuszanie wejścia do terminala. Rzadko jest taka potrzeba. Jeśli potrzebujesz wejść w interakcję z programem, który wymaga terminala, użyj dedykowanego emulatora terminala, takiego jak Expect lub Empty , lub programowalnego otoki terminala, takiego jak Screen lub Tmux . Możesz wymusić wejście do konsoli Linux za pomocą ioctl . Możesz wymusić wejście do emulatora terminala X11 za pomocą narzędzi takich jak xdotool lub xmacro .
źródło
screen
lubtmux
i użyj ich poleceniastuff
(screen) lubsend-key
(tmux) lub funkcji bufora wklejania.screen
lubtmux
)?screen -X stuff 'note version one'
.Przynajmniej Linux i BSD mają ioctl TIOCSTI do wypychania znaków z powrotem do bufora wejściowego terminala (do limitu [4096 znaków w Linuksie]):
Skompiluj go i wywołaj jako:
aby zepchnąć postacie z powrotem na jakiś tty.
I w perlu:
Edycja : Zdaję sobie sprawę, że teraz jest to ten sam ioctl, co w rozwiązaniu zapisu . Komentarz i nazwa polecenia są mylące, ponieważ TIOCSTI działa na dowolnym terminalu, nie tylko VT.
źródło
Mam pełniejsze demo na Stack Overflow .
W pythonie możesz wykonać:
To zakłada prostą
"command"
wartośćls -la
i użycie ścieżki tty określonej przez OP.źródło