Bash,如何检查变量中的控制字符(不可打印的字符)?

时间:2014-06-18 03:56:52

标签: linux bash

我有一个Bash语句将用户输入(单个字符)转换为tmpchar

read -n 1 -t 1 tmpchar

我可以检查这样的可打印字符输入:

if [ "$tmpchar" = "n" ] || [ "$tmpchar" = "N" ]; then
  # do something...
fi

现在我的问题是:如果用户只输入一个Return,或ESC,或者Ctrl + a,Ctrl + b等,我该如何检查它们?

ENV:openSUSE 12.3,Bash 4.2.42(1)-release

5 个答案:

答案 0 :(得分:3)

也许你正在寻找ANSI-C quoting。例如,Ctrl-a表示为$'\ca'

答案 1 :(得分:2)

使用=~内的正则表达式匹配运算符[[ ... ]]

if [[ $tmpchar =~ [[:cntrl:]] ]]; then
  # It's a control character
else
  # It's not a control character
fi

请注意,read -n1不会对各种特殊字符做出您期望的事情。至少应该使用:

IFS= read -r -n1

即便如此,您也永远不会看到换行符:如果您输入换行符,read会将回复变量设置为空字符串。

答案 2 :(得分:2)

如果您想知道某个字符是否不是可打印字符集的成员,请使用互补集表达式。这似乎适用于case

for c in $'\x20' $'\x19'; do
    case "$c" in
        [[:print:]]) echo printable;;
        [^[:print:]]) echo 'not printable';;
        *) echo 'more than one character?';;
    esac
done

(输出printable然后non printable

for c in $'\x20' $'\x19'; do
    if [[ $c = [[:print:]] ]]; then
        echo printable
    fi
    if [[ $c = [^[:print:]] ]]; then
        echo not printable
    fi
done

也可以。如果您想知道系统支持哪些字符集,请查看Linux上的man 7 regex或OS X上的man 7 re_format

答案 3 :(得分:0)

您可以使用tr

过滤输入
read -n 1 -t 1 tmpchar
clean=$(tr -cd '[:print:]' <<< $tmpchar)
if [ -z "$clean"]; then
    echo "No printable"
else
    echo "$clean"
fi

答案 4 :(得分:0)

我找到了一个检查唯一返回输入的技巧。

if [ "$tmpchar" = "$(echo -e '')" ]; then
  echo "You just pressed Return."
fi

换句话说,@ ooga的高度期待的方式,

if [ "$tmpchar" = $'\x0a' ]; then
  echo "You just pressed Return." # Oops!
fi

无论如何都不适用于Return,很难解释。