如果标准输入中没有用户输入,则使 bash 脚本退出
Make bash script exit if no user input in stdin
我的 bash 脚本应该获取用户输入以处理退出的特定文件,如:
if [ -e "formatted_log.csv" ]
then
printf "\nPresence of formatted_log.csv file detected: It appears this script has already been run is this dir.\n"
printf "Appending can cause errors.\n"
read -e -p "Would you like to continue?[y/n]" stdin
此逻辑检查用户的输入:
if [ $stdin = "n" ] || [ $stdin = "N" ];
then
printf "\nOkay, exiting.\n"
exit;
fi
if [ $stdin != "y" ]&&[ $stdin != "Y" ]&&[ $stdin != "n" ]&&[ $stdin != "N" ];
then
printf "\nPlease use a valid input (y/n)...exiting.\n"
exit;
fi
fi
问题是,如果您只需按回车键,脚本就会像输入 "y" 或 "Y" 一样执行,我不知道为什么。我的理解是这样写的,如果用户输入 y、Y、n 或 N 以外的任何内容,它应该退出。
当你没有输入时它打印这个:
master_script.sh: line 14: [: =: unary operator expected
master_script.sh: line 14: [: =: unary operator expected
master_script.sh: line 19: [: !=: unary operator expected
但不退出 – 我怎样才能让它退出?
问题是 NOT 在变量 $stdin
周围有引号,当引号不存在时,它不会保留空值,
例如[...]
当变量为空时看到如下表达式,
+ '[' = n ']'
script.sh: line 9: [: =: unary operator expected
+ '[' = N ']'
script.sh: line 9: [: =: unary operator expected
+ '[' '!=' y ']'
script.sh: line 14: [: !=: unary operator expected
+ '[' 0 eq 0 ']'
您需要正确地引用它们,以使其正常工作
9 if [ "$stdin" = "n" ] || [ "$stdin" = "N" ];
和
14 if [ "$stdin" != "y" ] && [ "$stdin" != "Y" ] && [ "$stdin" != "n" ] && [ "$stdin" != "N" ];
有了这个,回车键被安全地处理为,
+ '[' '' = n ']'
+ '[' '' = N ']'
+ '[' '' '!=' y ']'
+ '[' '' '!=' Y ']'
+ '[' '' '!=' n ']'
+ '[' '' '!=' N ']'
通过以上更改 运行 完整脚本并在提示符下按 Enter,在调试器模式下,
bash -x script.sh
+ '[' -f file ']'
+ printf '\nPresence of formatted_log.csv file detected: It appears this script has already been run is this dir.\n'
Presence of formatted_log.csv file detected: It appears this script has already been run is this dir.
+ printf 'Appending can cause errors.\n'
Appending can cause errors.
+ read -e -p 'Would you like to continue?[y/n]' stdin
Would you like to continue?[y/n]
+ '[' '' = n ']'
+ '[' '' = N ']'
+ '[' '' '!=' y ']'
+ '[' '' '!=' Y ']'
+ '[' '' '!=' n ']'
+ '[' '' '!=' N ']'
+ printf '\nPlease use a valid input (y/n)...exiting.\n'
Please use a valid input (y/n)...exiting.
+ exit
作为一种健康的替代方法,您可以在允许的提示列表中使用否定正则表达式匹配,如下所示
if [[ ! $stdin =~ ^(y|Y|n|N)$ ]]
另一种只检查变量上的空字符串的有效方法,
if [ "$stdin" = "" ]
既然你用 "Bash" 标记了它,你应该可以使用更强大的 [[ ]]
运算符。然后你可以简化成这样:
read stdin
if [[ $stdin == [Nn] ]]; then
echo "Exiting"
exit
fi
if [[ $stdin != [YyNn] ]]; then
echo "Invalid input, exiting"
exit
fi
==
(或=
)和[[ ]]
中的!=
执行模式匹配,因此您可以使用模式来在 [YyNn]
.
这样的单个表达式中检查您的输入是否有效
如果你想在用户输入有效内容之前请求输入,你可以像这样循环:
while [[ $stdin != [YyNn] ]]; do
read -p 'Continue? ' stdin
done
请注意,虽然在 Bash 中引用变量几乎总是好的做法,但您不必在 [[ ]]
中引用。如果你的模式在变量中,它实际上 不能 被引用,否则它不会被解释为模式。
我的 bash 脚本应该获取用户输入以处理退出的特定文件,如:
if [ -e "formatted_log.csv" ]
then
printf "\nPresence of formatted_log.csv file detected: It appears this script has already been run is this dir.\n"
printf "Appending can cause errors.\n"
read -e -p "Would you like to continue?[y/n]" stdin
此逻辑检查用户的输入:
if [ $stdin = "n" ] || [ $stdin = "N" ];
then
printf "\nOkay, exiting.\n"
exit;
fi
if [ $stdin != "y" ]&&[ $stdin != "Y" ]&&[ $stdin != "n" ]&&[ $stdin != "N" ];
then
printf "\nPlease use a valid input (y/n)...exiting.\n"
exit;
fi
fi
问题是,如果您只需按回车键,脚本就会像输入 "y" 或 "Y" 一样执行,我不知道为什么。我的理解是这样写的,如果用户输入 y、Y、n 或 N 以外的任何内容,它应该退出。
当你没有输入时它打印这个:
master_script.sh: line 14: [: =: unary operator expected
master_script.sh: line 14: [: =: unary operator expected
master_script.sh: line 19: [: !=: unary operator expected
但不退出 – 我怎样才能让它退出?
问题是 NOT 在变量 $stdin
周围有引号,当引号不存在时,它不会保留空值,
例如[...]
当变量为空时看到如下表达式,
+ '[' = n ']'
script.sh: line 9: [: =: unary operator expected
+ '[' = N ']'
script.sh: line 9: [: =: unary operator expected
+ '[' '!=' y ']'
script.sh: line 14: [: !=: unary operator expected
+ '[' 0 eq 0 ']'
您需要正确地引用它们,以使其正常工作
9 if [ "$stdin" = "n" ] || [ "$stdin" = "N" ];
和
14 if [ "$stdin" != "y" ] && [ "$stdin" != "Y" ] && [ "$stdin" != "n" ] && [ "$stdin" != "N" ];
有了这个,回车键被安全地处理为,
+ '[' '' = n ']'
+ '[' '' = N ']'
+ '[' '' '!=' y ']'
+ '[' '' '!=' Y ']'
+ '[' '' '!=' n ']'
+ '[' '' '!=' N ']'
通过以上更改 运行 完整脚本并在提示符下按 Enter,在调试器模式下,
bash -x script.sh
+ '[' -f file ']'
+ printf '\nPresence of formatted_log.csv file detected: It appears this script has already been run is this dir.\n'
Presence of formatted_log.csv file detected: It appears this script has already been run is this dir.
+ printf 'Appending can cause errors.\n'
Appending can cause errors.
+ read -e -p 'Would you like to continue?[y/n]' stdin
Would you like to continue?[y/n]
+ '[' '' = n ']'
+ '[' '' = N ']'
+ '[' '' '!=' y ']'
+ '[' '' '!=' Y ']'
+ '[' '' '!=' n ']'
+ '[' '' '!=' N ']'
+ printf '\nPlease use a valid input (y/n)...exiting.\n'
Please use a valid input (y/n)...exiting.
+ exit
作为一种健康的替代方法,您可以在允许的提示列表中使用否定正则表达式匹配,如下所示
if [[ ! $stdin =~ ^(y|Y|n|N)$ ]]
另一种只检查变量上的空字符串的有效方法,
if [ "$stdin" = "" ]
既然你用 "Bash" 标记了它,你应该可以使用更强大的 [[ ]]
运算符。然后你可以简化成这样:
read stdin
if [[ $stdin == [Nn] ]]; then
echo "Exiting"
exit
fi
if [[ $stdin != [YyNn] ]]; then
echo "Invalid input, exiting"
exit
fi
==
(或=
)和[[ ]]
中的!=
执行模式匹配,因此您可以使用模式来在 [YyNn]
.
如果你想在用户输入有效内容之前请求输入,你可以像这样循环:
while [[ $stdin != [YyNn] ]]; do
read -p 'Continue? ' stdin
done
请注意,虽然在 Bash 中引用变量几乎总是好的做法,但您不必在 [[ ]]
中引用。如果你的模式在变量中,它实际上 不能 被引用,否则它不会被解释为模式。