Unix Shell脚本编程-循环直到找不到文件

3

我正在编写shell脚本。我需要检查特定目录中是否存在具有两个特定文件扩展名"eob"和"inp"的文件,如果存在,我希望保持循环并继续检查,直到文件不存在,然后我想从循环中退出并继续使用其余逻辑。

以下是我目前拥有的代码,但它无法正常工作...

while true
do
  [ ! find /home/mpcmi/cm -type f \( -name "*.eob" -o -name "*.inp" \) ] && break
  echo "eob or inp file exists"
  sleep 2
done
echo "eob or inp file doesn't exists" 

首先,运行脚本时我遇到了这个错误:

"/home/mpcmi/cm: unknown test operator"

其次,我认为它能够正确地检查并找到具有这些扩展名的文件,因为我得到了输出:“eob或inp文件存在”,但是当我删除我的测试“eob”和“inp”文件时,脚本似乎无法检测到它,它停止打印“eob或inp文件存在”,但它从未打印“eob或inp文件不存在”。
以下是完整的输出,然后在我删除测试“eob”和“inp”文件后它就停止了:
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists
employees_load.sh[9]: /home/mpcmi/cm: unknown test operator
eob or inp file exists

有人能帮忙吗?

谢谢!

5个回答

1

您没有说明使用的是哪个 shell。我假设您使用的是 bash。

  1. 您应该使用 '[[' 和 ']]' 而不是 '[' 和 ']' 来判断 'find' 命令的结果是否为空。
  2. 您应该在 'find' 命令周围使用 '`' 来执行并将结果馈送到上面的评估中。

这是修改后的脚本:

while true
do
  [[ ! `find /home/smb -type f \( -name "*.eob" -o -name "*.inp" \)` ]] && break
  echo "eob or inp file exists"
  sleep 2
done
echo "eob or inp file doesn't exists"

1
假设使用 bash,并且文件不在子目录中。
shopt -s nullglob
while true; do
    unset f
    f=( /home/mpcmi/cm/*.{eob,inp} )
    if (( ${#f[@]} > 0 )); then
        echo "${#f[@]} eob or inp files present"
        sleep 2
    else
        break
    fi
done
echo "no eob or inp files"

1
简化你的逻辑:
while find /home/mpcmi/cm -type f \( -name "*.eob" -o -name "*.inp" \) | 
    grep -q . ; do
  echo "eob or inp file exists"
  sleep 2
done
echo "No extant eob or inp files" 

谢谢大家的回复!问题 - 如何让它只查找 /home/mpcmi/cm 目录,而不深入到子目录?谢谢! - user2179092

0

仅在bash中,不在循环中创建子进程:

check_dir=/home/mpcmi/cm

my_tmp_dir=$(mktemp -d --tmpdir=/tmp)    # Create a unique tmp dir for the fifo.
mkfifo $my_tmp_dir/fifo                  # Empty fifo for sleep by read.

found=1
while [[ $found == 1 ]]; do
  found=0
  for f in $check_dir/*.inp $check_dir/*.eob; do
    [[ -e $f ]] && found=1 && break
  done
  read -t 1 <> $my_tmp_dir/fifo          # Same as sleep 1, but without sub-process.
done

rm $my_tmp_dir/fifo; rmdir $my_tmp_dir   # Cleanup, could be done in a trap.

通过避免在循环中使用sleep,我不会创建任何子进程,因此我可以节省系统资源。为了实现这一点,我必须在bash中实现自己的sleep,我只发现了一个带有fifo超时的read
您可以使用trap来进行清理,从而改善此脚本。

0

如果存在以 .inp 或 .eob 结尾的文件,则打印 exists,否则不打印。

 if ls *.inp || ls *.eob
 then
     echo "exists"
 else
     echo "does not exist"
 fi

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接