Bash 中 read 的行为

在写这篇教程的时候本来想把 shell 语言批判一番,说什么太容易被注入,经常多打一个空格(见 bumblebee 事件)引发一场巨大灾难什么的大新闻,于是我就着手尝试各种能形成危险行为的输入,却没有能成功的……后来发现是自己比较 naive , echoread 的行为并不像表面上那么直接。那我就直接贴测试代码和用例咯。

测试文件 test.sh

#!/bin/bash
echo Please enter your name : 
read NAME
echo Your name is $NAME. Bye.

echo "Please enter your name : "
read NAME
echo "Your name is $NAME. Bye."

测试用例(为了便于阅读,所有输入与输入均有一个缩进;原来是没有的)

$ bash -x test.sh 
+ echo Please enter your name :
    Please enter your name :
+ read NAME
    ; xDroid
+ echo Your name is ';' xDroid. Bye.
    Your name is xDroid. Bye.
+ echo 'Please enter your name : '
    Please enter your name : 
+ read NAME
    ; xDroid 
+ echo 'Your name is ; xDroid. Bye.'
    Your name is ; xDroid. Bye.

在 zsh 下的行为

$ zsh -x test.sh 
+test.sh:2> echo Please enter your name :
    Please enter your name :
+test.sh:3> read NAME
    ; xDroid
+test.sh:4> echo Your name is '; xDroid.' Bye.
    Your name is ; xDroid. Bye.
+tesh.sh:6> echo 'Please enter your name : '
    Please enter your name : 
+test.sh:7> read NAME
    ; xDroid
+tesh.sh:8> echo 'Your name is ; xDroid. Bye.'
    Your name is ; xDroid. Bye.

稍有差异,但是都将双引号先转成单引号再执行。

因此由 read 读入的变量应该都会经过转义。


尝试了一下如果用 NAME=`cat` 的办法似乎也是不行的……

$ bash -x ./test.sh
+ echo Please enter your name :
    Please enter your name :
++ cat
    ; xDroid
+ NAME='; xDroid'
+ echo Your name is ';' xDroid. Bye.
    Your name is ; xDroid. Bye.