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