我正在尝试创建一个嵌套的 case 语句,其中需要用户输入 (Y/N)。然而,系统从不等待输入,总是转到第三个选项,“请回答是或否”。谁能告诉我我错过了什么?
这是案例陈述
#!/bin/bash
STATUS=status
find /etc/init.d/* -name '*' -print0 | while IFS= read -r -d '' FILE;
do
if [ "$FILE" != "." -o "$FILE" != ".." ]; then
OUTPUT=$($FILE $STATUS)
case "$OUTPUT" in
*disabled* )
echo "Do you wish to start $FILE ?"
read yn
case $yn in
[yY] | [yY][Ee][Ss] )
$FILE start
;;
[nN] | [n|N][O|o] )
;;
* )
echo "Please answer yes or no.";;
esac
;;
* )
echo "App $FILE is running"
;;
esac
fi
done
在 Ubuntu 14.04 LTS 下运行
示例输出
App /etc/init.d/reboot is running
App /etc/init.d/resolvconf is running
App /etc/init.d/rsync is running
App /etc/init.d/rsyslog is running
App /etc/init.d/samba is running
App /etc/init.d/samba-ad-dc is running
Do you wish to start /etc/init.d/saned ?
Please answer yes or no.
您正在将
find
输出传送到 while 循环。内部读取命令从find
的输出中读取一行,而不是从标准输入中读取。您可以像这样重组:将
find
输出发送到不同文件描述符上的 while 循环。这使得 stdin 可以免费用于内部读取。这使用进程替换而不是管道来读取
find
这次的上下文给出了答案。您正在将 find 的输出通过管道输送到整个 while 循环中,这也包括您的内部读取......意思是,您的“read yn”也将从“find”提供的相同输出中读取,而不是从您的键盘。
我也不喜欢您对文件循环的一般处理。一个简单的:
现在通常效果很好,即使对于大量文件也是如此。
如果你真的必须使用 find,你可以将你的处理程序包装在另一个脚本中,并为每个文件调用它:
这将找到所有具有可执行权限的文件,并以名称作为参数为每个文件调用 myhandlerscript.sh。在脚本中,文件名将出现在 $1 特殊变量中。
如果它真的必须在同一个文件中,将代码包装在一个函数中,用“export -f myfunction”导出它,然后使用“-exec bash -c 'myfunction “$0”' {} \;” 作为查找的参数。
您对“读取”命令的用法似乎不太正确。
-p 开关需要在它旁边有一个字符串,它将用作提示。因此它认为“yn”是要显示的东西,而不是存储答案的变量。