使用用户输入和 while 循环的回文检查器 bash
Palindrome checker using user input and while loop in bash
我正在尝试制作一个 bash 脚本来检查某个单词是否是我的家庭作业的回文,但我无法让我的 while 循环正常工作。该脚本应保持 运行 并要求回文,直到用户给出回文。有经验的人可以帮我解决这个问题,并解释一下我做错了什么吗?
#!/bin/bash
if [ $# -le 2 ]
then
echo "Enter the word"
read input
fi
echo $input > temp
reverse=`rev temp`
echo $reverse
while [ ! $input==$reverse ]
do echo "Not a palindrome"
read input
done
echo "it is a palindrome"
rm temp
应该这样做:
#!/bin/bash
set -euo pipefail;
while true; do
echo -n "Enter the word: ";
IFS=$'\n\t ' read -d$'\n' -r inputword restofsentence;
if [[ -n "${inputword}" && -z "${restofsentence}" ]] ; then
reverse="$( rev <( echo "${inputword}" ) )";
if [[ "${reverse}" == "${inputword}" ]] ; then
echo "it is a palindrome";
exit 0;
else
echo "Not a palindrome";
echo "";
echo "";
fi;
fi;
done;
我不确定 $#
(cli 参数的数量)在您的示例中起到了什么作用,因为您没有使用 cli 参数;所以我省略了那部分。
至于它的作用:
set -euo pipefail;
有效启用“严格模式”。使 BASH 不再是一种糟糕的脚本语言。它在这个脚本中并没有太大的影响,但在默认情况下始终在每个脚本中都有它是一个很好的做法。
while true; do
开始一个循环并一直重复下去。
echo -n "Enter the word: ";
-n
禁止在句末使用通常的换行符。
IFS=$'\n\t '
明确设置内部字段分隔符。这意味着 bash 对单词的解释是输入在换行符 (\n
)、制表符 (\t
) 和空格 (' ') 上“分开”;通常这是默认值,但最好在每个脚本的基础上或为每个类似 read
的命令手动设置 IFS
。
read -d$'\n' -r inputword restofsentence;
读取用户输入直到分隔符换行符 (-d$'\n'
),即回车键。不允许反斜杠转义 -r
用于多行输入之类的事情。输入行根据前面的 IFS
拆分为单词;之后第一个词进入 inputword
,潜在的第二/第三个/...-词进入 restofsentence
.
if [[ -n "${inputword}" && -z "${restofsentence}" ]] ; then
我们期望 inputword
有一个值(非空)并且我们期望 restofsentence
为空。如果不是这种情况,我们只需让 while
循环重复并再次请求输入。这样我们就不会处理空输入(因为 inputword
将是空的),也不会处理多词输入(因为 restofsentence
不会是空的)。
reverse="$( rev <( echo "${inputword}" ) )";
我们将 inputword
回显到一个虚拟文件中,并将其传递给 rev
程序,echo
是反向值。我们将其存储在变量 reverse
.
中
我们没有使用真实文件(存储在文件系统中,而不是仅存储在内存中)这一事实使我们不必在以后清理它。
if [[ "${reverse}" == "${inputword}" ]] ; then
我们比较 inputword
和 reverse
是否相同,如果相同则我们正在处理回文。
exit 0;
一旦我们有一个成功的回文,我们就退出(exitcode 0
表示没有错误)。
程序(特别是 while
循环)一直重复直到找到一个成功的回文。
试试这个:
#!/bin/bash
while :; do
read -p "Enter a word: "
if [[ ${REPLY} == "$(rev <(printf %s "${REPLY}"))" ]]; then
echo "It is a palindrome."
break
fi
echo "Not a palindrome."
done
或者,它可以像这样更简单地完成,但这是不正确的,因为理论上“这是一个回文”。即使循环中断不是由正确输入引起的,而是其他错误引起的,仍然会被发送。
#!/bin/bash
while read -p "Enter a word: "; [[ ${REPLY} != "$(rev <(printf %s "${REPLY}"))" ]]; do
echo "Not a palindrome."
done
echo "It is a palindrome"
顺便说一句,它使用 Process Substitution。
可以创建一个函数来反转字符串,这应该是微不足道的,但它是可选的范围。
首先让它工作。
你想检查一个参数。给出参数后,将其分配给输入。引用 $input
避免问题 特殊字符和空格。在==
两边加上空格,使其在循环中再次进行反向比较和计算。我还使用了 $(rev temp)
比 backtics 更好用的东西。
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Enter the word"
read input
else
input=""
fi
echo "$input" > temp
reverse=$(rev temp)
echo "$reverse"
while [ ! "$input" == "$reverse" ]
do
echo "Not a palindrome"
read input
echo "$input" > temp
reverse=$(rev temp)
done
echo "it is a palindrome"
rm temp
您可以避免这样的 tmp 文件:
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Enter the word"
read input
else
input=""
fi
while [ ! "$input" == "$(rev <<< "${input}")" ]
do
echo "Not a palindrome"
read input
done
echo "it is a palindrome"
我正在尝试制作一个 bash 脚本来检查某个单词是否是我的家庭作业的回文,但我无法让我的 while 循环正常工作。该脚本应保持 运行 并要求回文,直到用户给出回文。有经验的人可以帮我解决这个问题,并解释一下我做错了什么吗?
#!/bin/bash
if [ $# -le 2 ]
then
echo "Enter the word"
read input
fi
echo $input > temp
reverse=`rev temp`
echo $reverse
while [ ! $input==$reverse ]
do echo "Not a palindrome"
read input
done
echo "it is a palindrome"
rm temp
应该这样做:
#!/bin/bash
set -euo pipefail;
while true; do
echo -n "Enter the word: ";
IFS=$'\n\t ' read -d$'\n' -r inputword restofsentence;
if [[ -n "${inputword}" && -z "${restofsentence}" ]] ; then
reverse="$( rev <( echo "${inputword}" ) )";
if [[ "${reverse}" == "${inputword}" ]] ; then
echo "it is a palindrome";
exit 0;
else
echo "Not a palindrome";
echo "";
echo "";
fi;
fi;
done;
我不确定 $#
(cli 参数的数量)在您的示例中起到了什么作用,因为您没有使用 cli 参数;所以我省略了那部分。
至于它的作用:
set -euo pipefail;
有效启用“严格模式”。使 BASH 不再是一种糟糕的脚本语言。它在这个脚本中并没有太大的影响,但在默认情况下始终在每个脚本中都有它是一个很好的做法。
while true; do
开始一个循环并一直重复下去。
echo -n "Enter the word: ";
-n
禁止在句末使用通常的换行符。
IFS=$'\n\t '
明确设置内部字段分隔符。这意味着 bash 对单词的解释是输入在换行符 (\n
)、制表符 (\t
) 和空格 (' ') 上“分开”;通常这是默认值,但最好在每个脚本的基础上或为每个类似 read
的命令手动设置 IFS
。
read -d$'\n' -r inputword restofsentence;
读取用户输入直到分隔符换行符 (-d$'\n'
),即回车键。不允许反斜杠转义 -r
用于多行输入之类的事情。输入行根据前面的 IFS
拆分为单词;之后第一个词进入 inputword
,潜在的第二/第三个/...-词进入 restofsentence
.
if [[ -n "${inputword}" && -z "${restofsentence}" ]] ; then
我们期望 inputword
有一个值(非空)并且我们期望 restofsentence
为空。如果不是这种情况,我们只需让 while
循环重复并再次请求输入。这样我们就不会处理空输入(因为 inputword
将是空的),也不会处理多词输入(因为 restofsentence
不会是空的)。
reverse="$( rev <( echo "${inputword}" ) )";
我们将 inputword
回显到一个虚拟文件中,并将其传递给 rev
程序,echo
是反向值。我们将其存储在变量 reverse
.
我们没有使用真实文件(存储在文件系统中,而不是仅存储在内存中)这一事实使我们不必在以后清理它。
if [[ "${reverse}" == "${inputword}" ]] ; then
我们比较 inputword
和 reverse
是否相同,如果相同则我们正在处理回文。
exit 0;
一旦我们有一个成功的回文,我们就退出(exitcode 0
表示没有错误)。
程序(特别是 while
循环)一直重复直到找到一个成功的回文。
试试这个:
#!/bin/bash
while :; do
read -p "Enter a word: "
if [[ ${REPLY} == "$(rev <(printf %s "${REPLY}"))" ]]; then
echo "It is a palindrome."
break
fi
echo "Not a palindrome."
done
或者,它可以像这样更简单地完成,但这是不正确的,因为理论上“这是一个回文”。即使循环中断不是由正确输入引起的,而是其他错误引起的,仍然会被发送。
#!/bin/bash
while read -p "Enter a word: "; [[ ${REPLY} != "$(rev <(printf %s "${REPLY}"))" ]]; do
echo "Not a palindrome."
done
echo "It is a palindrome"
顺便说一句,它使用 Process Substitution。
可以创建一个函数来反转字符串,这应该是微不足道的,但它是可选的范围。
首先让它工作。
你想检查一个参数。给出参数后,将其分配给输入。引用 $input
避免问题 特殊字符和空格。在==
两边加上空格,使其在循环中再次进行反向比较和计算。我还使用了 $(rev temp)
比 backtics 更好用的东西。
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Enter the word"
read input
else
input=""
fi
echo "$input" > temp
reverse=$(rev temp)
echo "$reverse"
while [ ! "$input" == "$reverse" ]
do
echo "Not a palindrome"
read input
echo "$input" > temp
reverse=$(rev temp)
done
echo "it is a palindrome"
rm temp
您可以避免这样的 tmp 文件:
#!/bin/bash
if [ $# -ne 1 ]
then
echo "Enter the word"
read input
else
input=""
fi
while [ ! "$input" == "$(rev <<< "${input}")" ]
do
echo "Not a palindrome"
read input
done
echo "it is a palindrome"