【发布时间】:2020-10-15 15:30:18
【问题描述】:
我的系统是 Arch Linux,我的窗口管理器是 DWM。我使用 dash 作为我的 shell 解释器。
我已经为我的计时器编写了这个扩展 shell 脚本。
xev -root |
awk -F'[ )]+' '/^KeyPress/ { a[NR+2] }
NR in a {
if ($8 == "Return") {
exit 0;
} else if ($8 == "BackSpace") {
system("truncate -s-1 timer.txt");
} else if (length($8) == 1) {
printf "%s", $8;
fflush(stdout);
}
system("pkill -RTMIN+3 dwmblocks");
}' | tee timer.txt
计时器本身位于dwmblocks 状态栏中。我想先命名我的计时器,然后让它启动。但我认为这并不重要。
此脚本的目的 - 我想在 DWM 的根窗口中输入字符并让它们立即出现在我的状态栏中。因此,xev 生成按键信息,然后 awk 获取该信息,找到确切的键(从 xev 输出的所有信息中)并检查。如果键是“返回”,awk 退出(工作完成)。如果键是“BackSpace”,则 awk 从系统调用 truncate。如果它是常规字符键,则 awk 将其与 tee 一起输出到 timer.txt (我想我也可以使用 "> timer.txt" ,但我想在我的终端中查看输出以进行调试。
每次相关按键(单个字符)后,我都会刷新标准输出。毕竟我最终调用 pkill 以便 dwmblocks 知道它应该更新。 (dwmblocks 对文件发出 cat 操作)
好的,“返回”和字符输入工作正常。但是“BackSpace”存在问题。我已经读过一点(我想说我仍然是 Unix 新手,即使我已经使用 Linux 两年了),我发现从不同进程写入同一个文件是个坏消息。仍然。可以以某种方式完成吗?事实是 truncate 只在 awk 时写入文件,而不是,所以,也许这没什么大不了的?
这个确切的脚本昨天早些时候工作了,但现在不行了。起初,我尝试使用 sed 而不是 truncate 并且 truncate 似乎可以让我从 timer.txt 中删除字符,但现在 truncate 似乎不起作用也不再。嗯,它有点工作。我可以输入我的字符,然后我可以删除它们。 但是。 按 Backspace 后,我无法再输入任何字符。如果我尝试输入字符 Backspace 也会停止工作。
是的。我有几个问题。首先 - 到底是什么问题?正如我所说,它曾经有效,但现在无效。我是否在此脚本中徘徊在未定义的行为中?
第二 - 可以这样做吗 - 意思是 - 我可以以某种方式从同一个文件中写入和删除。也许使用其他工具,而不是 awk?
提前致谢。
【问题讨论】: