我有这个makefile
:
all:
sudo watch "ls -l" > /dev/null &
@echo line 1
@echo line 2
@echo line 3
@echo line 4
跑步watch
(或以某种方式改变终端的任何其他进程)破坏了终端。这是输出。你可以看到这些大空间。另外,当我写下以下内容时,我看不到这些字符:
me@me:/tmp$ make
watch "ls -l" > /dev/null &
line 1
line 2
line 3
line 4
me@me:/tmp$
有没有办法阻止进程更改终端?
澄清:watch
只是一个可重现的例子。我正在使用另一个应作为守护进程运行的应用程序,但仍然会破坏终端。
编辑:我启动这个应用程序(在这个例子中,应用程序是watch
)sudo
解决方法是在没有 - 的情况下启动它sudo
,那么终端就不会被破坏。
这样做的缺点是,我不需要chown
这个过程root:root
。
答案1
Watch by design 更新了终端。它“监视”一个对象,并显示该对象的当前版本(或使用 -d 对该对象进行的更改)。 watch 有用的一个例子是,如果你想监控 cpu 的温度,你可以打开一个新终端,并运行以下命令,输出将每 2 秒更新一次,传感器记录的温度。
watch -x cat /sys/devices/pci0000:00/0000:00:18.3/hwmon/hwmon0/temp1_input
我不确定您为什么想要观看“ls -l” 您可以创建一个记录输出的 shell 脚本吗?
#!/bin/bash
while :
do
date +"%H:%M:%S" >> /var/log/ls.log
ls -l >> /var/log/ls.log
sleep 2
done
如果您想记录新文件或修改的文件,则:
#!/bin/bash
while :
do
find -newer /var/log/ls.log >> /var/log/ls.log
date +"%H:%M:%S" >> /var/log/ls.log
sleep 2
done
你可能想增加睡眠时间,我把它设置为2,因为这是手表的默认设置。
输出缩进并且您看不到输出后键入的字符的原因是您的终端而不是 Bash。
检查终端程序上的设置并检查术语类型以确保它们与编码(例如:utf8、ANSII 等)匹配。终端仅将光标向下移动一行 (\n),而不是将光标重置回行的开头行 (\r)。如果文件是在 Windows 中创建然后移动到 Linux,或者在 Linux 中创建并移动到 Windows,也可能会发生这种情况。
您键入的字符将显示在输出的最后一行后面。因此你看不到它。
答案2
有没有办法阻止进程更改终端?
并不真地。终端状态对于终端来说是全局的,并且可以由任何有权执行此操作的进程进行更改。
$ tty
/dev/ttys007
$ stty -a | grep ' erase'
eol2 = <undef>; erase = ^?; intr = ^C; kill = ^U; lnext = ^V;
$ stty erase '#'
$ stty -a | grep ' erase'
eol2 = <undef>; erase = #; intr = ^C; kill = ^U; lnext = ^V;
作为练习,您可以弄清楚如何撤消该更改。另一个练习是看看哪些 shell 或程序erase
是传统的#
(如“UNIX 编程环境”(1984 年)中所示)。
否则,交互式程序不是设计为在后台运行的,即使它们不改变终端状态,它们的输出也可能与其他程序的输出交错并且难以阅读,或者它们可能永远受到 SIGTTIN 或 SIGTTOU 信号的影响。尝试从后台与终端进行交互。阶梯式是一个常见问题,其中终端状态(或行式打印机)与进程期望的状态不同步;手册页中记录了影响 CR/NL 处理的各种标志termios
(INLCR
、IGNCR
等)。如果您的后台进程需要设置 X,但 shell 将其更改回 Y,那么您就会遇到冲突。
某些操作系统可能具有安全框架,可以让您阻止程序更改终端设置。在这种情况下,交互式程序可能无法运行或无法按设计运行,并且您最终可能会花费大量时间摆弄安全框架以获得正确的配置。
另一种选择可能是在唯一的 pty 下运行该进程(例如,在 下tmux
),它不应干扰在其他窗口中运行的其他程序。
stty -g
(如果支持)将允许您保存(某些)终端设置以便稍后恢复,但是如果后台进程永远在摆弄终端状态,或者如果后台程序需要设置,则这将不起作用与恢复的值冲突。大多数程序仅在启动时或在其他特定事件时(例如,对control+做出反应z,然后进入前台时)进行终端状态更改。一个程序可以使用tcsetattr(3)
用来直接修改终端状态。
有些 shell 在程序退出后恢复终端状态方面比其他 shell 更好。将 ZSH 与 Heirloom Bourne Shell 等进行比较。各种程序会忽略某些终端设置,例如ZSH将忽略erase
设置为#
,而在其他程序下(cat
例如)#
应删除前一个字符。
练习提示:lnext
“字面下一个”的缩写通常是
control+ v,或者无论stty -a
它是什么。程序可能不尊重这一点...
答案3
- 对于
watch
您的守护程序,您也可以尝试重定向 stdin ie add< /dev/null
,这样它就永远不会首先访问您的终端。 - 你说它是一个守护进程,所以另一种方法是从你的 systemd 或 init 运行它,再次防止它接触你的 tty
- 如果这只是一个测试并且您需要恢复,那么还有
stty sane