我有一个非常简单的类似聊天的工具,可以在 GNUscreen
会话中运行。窗口screen
被分割,顶部部分正在运行tail -f file.txt
,底部部分正在运行包含以下内容的脚本:
#!/bin/bash
while : ; do
read -p "Message: " msg
ctime=$(date +"%H:%M:%S")
echo "[${ctime}] User: ${msg}" >> file.txt
done
很简单,但是按照我的要求完成了工作。只有一个问题:当我按ESC或任何箭头键时,它会插入一个转义序列,例如^[[D
。这会弄乱文件,导致糟糕的输出。
所以我的问题很简单:如何转义输入read
以便可以安全地写入文件?
我已经尝试过,echo "[${ctime}] User: ${msg}" | strings >> file.txt
这使它好多了,不再有大的混乱(例如,没有任何内容被覆盖或错误地输出),但事情仍然不完美(例如,输入te^[[Dst
会变成te\n[Dst
(\n
是一个实际的新行) )。
答案1
稍微不同的方法怎么样?您可以允许用户使用转义字符和序列来编辑输入行,而不是删除转义字符和序列read -e
。
如果需要,您可以通过记录聊天消息历史记录来更进一步,如下所示:
...
read -e -p "Message: " msg
history -s "$msg"
...
这样,如果有人在消息中出现拼写错误,他们可以点击向上箭头,使用左右箭头编辑和修复拼写错误,然后点击返回发送更正的消息。
答案2
从消息字符串中去除所有非打印字符:
#!/bin/bash
while read -p 'Message: ' message; do
printf '[%s] User: %s\n' "$( date +%T )" "${message//[^[:print:]]/}"
done >>file.txt
参数替换${message//[^[:print:]]/}
将扩展到变量的值,message
并删除任何不可打印的字符。在 POSIX 语言环境中,可打印的字符是字母数字字符、标点符号字符和空格([[:alnum:][:punct:] ]
基本上是 )。