首页 > 解决方案 > Bash 脚本 - 在 case 结构或 if else 语句中不执行读取命令

问题描述

我有一个$empIc,它是用户输入的变量。我尝试从文本文件中读取一些详细信息并检查变量$ic。如果输入不匹配,将执行无效的脚本文件,让用户选择重新输入输入或返回菜单。但是,无效脚本中的读取命令永远不会执行并导致无限循环。

 while IFS=':' read -r dep ic name phone email gender birthDate jobTitle joinDate
 do
  if [ "$empIc" = "$ic" ]
  then
    echo -n "Employee Name : $name"; echo
    echo -n "Job Title     : $jobTitle"; echo
    echo -n "Department    : $dep"; echo 
    break
  else
    match=0
  fi
  case $match in
  0) echo "No such record!"; ./invalidic; break;;
  *) 
  esac
done <Employee.txt

这是无效脚本文件的代码:

#!/bin/bash

while true
do
  echo "========================================="
  echo "1. Enter Performance Review again"
  echo "2. Back to Human Resource Management Menu"
  echo "========================================="
  echo "What would you like to do? Please enter choice in number: "; read action
  case $action in
  1) ./task4_main; break;;
  2) ./task1_menu; break;;
  *) echo "Please enter 1 for Performance Review, 2 to back to Human Resource Management Menu"
  esac
done

这是输入与存储的数据不匹配时得到的输出

标签: bashubuntu

解决方案


直接的问题是它invalidic在循环内运行while ... read ... done <Employee.txt,因此它是从 Employee.txt 文件而不是终端读取的。invalidic但这是另一个问题的结果:如果Employees.txt 文件中没有匹配项,您可能想运行它,但如果Employees.txt 中的第一行不匹配$empIc,则当前脚本运行它。它还尝试为每个不匹配的行运行它,但是因为它永远不会超过第一个不会发生的行。

您需要等到循环完成对Employees.txt 文件中每一行的检查,如果它到达末尾而没有找到匹配项,那么您应该运行invalidic. 也就是说,做这样的事情:

match=0   # No match found *yet*, because we haven't started looking

while IFS=':' read -r dep ic name phone email gender birthDate jobTitle joinDate
 do
  if [ "$empIc" = "$ic" ]
  then
    echo "Employee Name : $name"    # Don't use `echo -n`, then `echo` to add a newline. Just skip the -n
    echo "Job Title     : $jobTitle"
    echo "Department    : $dep" 
    match=1    # Found a match
    break
  fi
done <Employee.txt

# If we *still* haven't found a match (now that we've now scanned the
# entire file) then there isn't a match there.
case $match in
  0) echo "No such record!"; ./invalidic;;
  *) 
esac

实际上,我会case用一个简单的替换最后一个if [ "$match" = 0 ]- 您不需要case这里的功能和复杂性,而 IMO anif是更好的选择。

注意:我也有点担心您正在使用 GOTO 之类的脚本执行。在内部invalidic,您可以运行task4_maintask1_main,这两个听起来都像是任务,而不是无效 ID 处理程序的子任务。当你运行类似的东西时./somescript,你真的应该运行一个任务,而不仅仅是那是下一个合乎逻辑的事情。


推荐阅读