如何在 bash 中安全地转义变量字符串(用户输入)?

如何在 bash 中安全地转义变量字符串(用户输入)?

我有一个非常简单的类似聊天的工具,可以在 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:] ]基本上是 )。

相关内容