谁能一步一步解释这bash行中会发生什么?我是这里的新手,试图了解这段代码的工作原理,尤其是从echo
:
read char; echo -e "YES\nNO\n" | grep -i $char
该行上的命令char
可能会从用户以交互方式将字符串读取到变量中。
在echo
+grep
管道尝试确定输入的字符串是否是肯定与否。它通过不区分大小写地将单词YES
与NO
输入的字符串(以输入的字符串作为模式)相匹配来做到这一点。如果用户输入单词中存在的大写或小写字符或子字符串YES
,则结果为YES
; 如果他们输入字符串中存在的大写或小写字符或子字符串NO
,则结果为NO
。输入类似的内容maybe
将导致输出为空。
这种方法的缺点是,如果用户输入,例如,.
,都YES
和NO
将匹配作为grep
将治疗的点为正则表达式相匹配的任何字符。由于$char
在对的调用中未加引号grep
,因此如果用户输入诸如输入之类的shell遍历模式,则也有可能导致对机器的拒绝服务攻击/*/*/*/*/../../../../*/*/*/*
(示例取自于安全性,忘记了在bash中引用变量) / POSIX shell)。您还可以通过输入eg来引起命令输出混乱-r -o -e . /
(例如,将单独输出一行中每个非二进制文件的每个字符,然后输出其所属文件的路径名)。
您显示的代码是“奇怪且不寻常的”,因为它将用户输入用作本质上是代码的东西,即,它将用户输入用作模式,并针对此可变模式测试静态数据。这与通常所做的相反,后者从用户那里获取输入,并根据静态模式测试此可变数据。
更常见的是使用类似于以下内容的代码:
read -p 'Yes/[N]o: ' yesno
if [[ $yesno == [Yy]* ]]; then
# code for affirmative
else
# code for non-affirmative
fi
上面的代码从用户读取一个字符串,并测试它是否以ay
或Y
字符开头。if
如果这样做,则将采用该语句的第一个分支,但默认情况下将采用该else
分支。
显然,您也可以对整个单词进行测试YES
,或者[Yy][Ee][Ss]
对大小写不敏感的匹配进行测试,或者通过验证进行适当的输入循环:
while true; do
read -p 'Yes/No: ' yesno
if [ "$yesno" = Yes ] || [ "$yesno" = No ]; then
break
fi
echo 'Please enter "Yes" or "No"' >&2
done
# $yesno is either Yes or No here
(或类似的内容)。
请注意,以上两个示例代码如何仅将用户输入用作数据,而不用作模式。
最少地将原始命令重写为一些惯用的东西(但功能上有所不同,并且可能并非万无一失)会将其转换为
read yesno; printf '%s\n' "${yesno^^}" | grep -i -w -E 'yes|no'
这将返回大写YES
或者NO
是用户输入yes
或no
。这在功能上有所不同,因为例如,它要求用户键入的内容不只是e
为yes
。
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句