使用用户输入和 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

我们比较 inputwordreverse 是否相同,如果相同则我们正在处理回文。

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"