Je to možné v interaktivní bash shell pro zadání příkazu, který vypíše nějaký text, takže se objeví na dalším příkazovém řádku, jako by uživatel zadal tento text na tomto řádku ?
Chci umět source skript, který vygeneruje příkazový řádek a vydá jej tak, aby se zobrazil, když se výzva vrátí po skončení skriptu, takže jej uživatel může volitelně upravit před stisknutím enter k provedení.
Toho lze dosáhnout pomocí xdotool ale to funguje pouze tehdy, když je terminál v okně X a pouze pokud je nainstalován.
[[email protected]] 100 $ xdotool type "ls -l"
[[email protected]] 101 $ ls -l <--- cursor appears here!
Lze to provést pouze pomocí bash?
Přijatá odpověď:
Pomocí zsh , můžete použít print -z k umístění nějakého textu do vyrovnávací paměti řádkového editoru pro další výzvu:
print -z echo test
by naplnil editor řádků pomocí echo test kterou můžete upravit na další výzvu.
Nemyslím si, že bash má podobnou funkci, ale na mnoha systémech můžete naplnit vstupní vyrovnávací paměť koncového zařízení pomocí TIOCSTI ioctl() :
perl -e 'require "sys/ioctl.ph"; ioctl(STDIN, &TIOCSTI, $_)
for split "", join " ", @ARGV' echo test
Vloží echo test do vstupní vyrovnávací paměti koncového zařízení, jako by byla přijata z terminálu.
Přenosnější varianta Terminology @mike přístup, který neobětuje zabezpečení, by bylo poslat emulátoru terminálu poměrně standardní query status report escape sekvence:<ESC>[5n které terminály vždy odpovídají (tedy jako vstup) jako <ESC>[0n a připojte jej k řetězci, který chcete vložit:
bind '"e[0n": "echo test"'; printf 'e[5n'
Pokud je na screen GNU , můžete také:
screen -X stuff 'echo test'
Nyní, s výjimkou přístupu TIOCSTI ioctl, žádáme emulátor terminálu, aby nám poslal nějaký řetězec jako napsaný. Pokud se tento řetězec nachází před readline (bash 's line editor) zakázal místní odezvu terminálu, pak se tento řetězec zobrazí ne při výzvě shellu, což mírně naruší displej.
Chcete-li to obejít, můžete odeslání požadavku na terminál mírně zpozdit, abyste se ujistili, že odpověď dorazí, když bude odezva zakázána pomocí readline.
bind '"e[0n": "echo test"'; ((sleep 0.05; printf 'e[5n') &)
(zde za předpokladu, že máte sleep podporuje subsekundové rozlišení).
V ideálním případě byste chtěli udělat něco jako:
bind '"e[0n": "echo test"'
stty -echo
printf 'e[5n'
wait-until-the-response-arrives
stty echo
Nicméně bash (na rozdíl od zsh ) nemá podporu pro takové wait-until-the-response-arrives který nečte odpověď.
Má však has-the-response-arrived-yet funkce s read -t0 :
bind '"e[0n": "echo test"'
saved_settings=$(stty -g)
stty -echo -icanon min 1 time 0
printf 'e[5n'
until read -t0; do
sleep 0.02
done
stty "$saved_settings"
Další čtení
Podívejte se na odpověď @starfry, která rozšiřuje dvě řešení poskytnutá @mikeserv a mnou s několika podrobnějšími informacemi.