Я смотрю на результаты работы запущенного процесса bash, подключенного к терминалу, в образовательных целях.
Мой процесс bash имеет PID 2883.
Я печатаю
[OP@localhost ~]$ strace -e trace=openat,read,write,fork,vfork,clone,execve -p 2883 2> bash.strace
В терминал. Затем я вхожу в процесс bash и получаю следующее взаимодействие:
[OP@localhost ~]$ ls
Глядя на вывод, я вижу
strace: Process 2883 attached
read(0, "l", 1) = 1
write(2, "l", 1) = 1
read(0, "s", 1) = 1
write(2, "s", 1) = 1
read(0, "\r", 1) = 1
write(2, "\n", 1) = 1
clone(child_stack=NULL, flags=CLONE_CHILD_CLEARTID|CLONE_CHILD_SETTID|SIGCHLD, child_tidptr=0x7fec6b1d8e50) = 3917
--- SIGCHLD {si_signo=SIGCHLD, si_code=CLD_EXITED, si_pid=3917, si_uid=1000, si_status=0, si_utime=0, si_stime=0} ---
write(1, "\33]0;OP@localhost:~\7", 23) = 23
write(2, "[OP@localhost ~]$ ", 22) = 22
...
Я запутался в последних двух строках. Похоже, что bash пытается написать две подсказки оболочки? Что тут происходит?
cat
, есть два различия: он читает входные данные построчно, и хотя он выводит свой ввод обратно на стандартный вывод, я вижу ввод дважды (один раз, когда я печатаю, и один раз, когда кошка повторяет его).^A
нажатии клавиши TAB или (Ctrl-A) или различных специальных символов. Кроме того, он отключает эхо-сигнал терминала, так что он может решить, что выводить для каждого конкретного входного символа (опять же, TAB обычно не выводит TAB.) Неcat
делает ничего из этого. Если это так, попробуйте запуститьdash
, что не делает никакой обработки командной строки.read()
чтение только одного байта за раз, заключается в том, что он не может читать после новой строки. Новая строка может привести к запуску внешней программы, которая также может читать из того же ввода. (И эта программа должна быть способна читать любые символы после новой строки.) Если ей не нужно об этом заботиться, она может вызыватьread()
с большим лимитом, а с терминалом в режиме raw, она все равно обычно получает ввод по одному персонажу за раз. (Это будет зависеть от того, как быстро будут поступать вводимые символы и как планировался процесс.)read()
буфер с большим объемом может по-прежнему возвращать обе строки в тот же звонок. Я не думаю, что есть гарантия,read()
которая всегда вернула бы только одну строку в готовом режиме.