bash 带通配符的文件循环

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/19842449/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 08:32:06  来源:igfitidea点击:

File loop with wildcard

bashfileloopswildcard

提问by user2965857

I'm writing a small script, for starting scripts created in the background. This script is running in a loop and has to start the created file when it is found in the specified directory.

我正在编写一个小脚本,用于启动在后台创建的脚本。此脚本循环运行,并且必须在指定目录中找到创建的文件时启动该文件。

It works when only one file is in the directory, the created script removes itself when it's finisched. But when 2 or more scripts are created at the same time it failes to run the scripts.

当目录中只有一个文件时,它起作用,创建的脚本在完成时会自行删除。但是当同时创建 2 个或更多脚本时,它无法运行脚本。

I get a error : binary operator expected

我收到一个错误:预期的二元运算符

#!/bin/bash   
files="/var/svn/upload/*.sh"
x=1
while :
do
echo Sleeping $x..
  if [ -f $files ]
  then
    for file in $files
    do
      echo "Processing $file file..."
      sh $file
      echo $(date +%d-%m-%y) $(date +%H:%M:%S) - Sleep $x - Script $f >>/var/log/upload.log
      x=0
      wait
    done
  fi
  x=$(( $x + 1 ))
  sleep 1
done

I created a work around wich is working without any problems:

我创建了一个解决方法,它可以正常工作:

#!/bin/bash
files="/var/upload/*.sh"
x=1
while :
do
  count=$(ls $files 2> /dev/null | wc -l)
  echo Sleeping $x..
  if [ "$count" != "0" ]
  then
    for file in $files
    do
      echo "Processing $file file..."
      sh $file
      echo $(date +%d-%m-%y) $(date +%H:%M:%S) - Sleep $x - Script $f >>/var/log/upload.log
      x=0
      wait
    done
  fi
  x=$(( $x + 1 ))
  sleep 1
done

回答by chepner

The -foperator applies to only a single file, not the list that results by expanding your unquoted $files. If you really need to capture the full list of files in a single variable, use an array, not a string. The nullgloboption ensures that filesis truly empty if the glob fails to match any files, eliminating the need for the -ftest. There is also no need to call wait, as you aren't starting any background jobs.

-f运算符仅适用于单个文件,而不适用于扩展未加引号的$files. 如果您确实需要在单个变量中捕获完整的文件列表,请使用数组,而不是字符串。如果 glob 无法匹配任何文件,该nullglob选项可确保它files真正为空,从而无需进行-f测试。也无需调用wait,因为您没有启动任何后台作业。

#!/bin/bash  
shopt -s nullglob
x=1
while :
do
  echo Sleeping $x..
  for file in /var/svn/upload/*.sh
  do
    echo "Processing $file file..."
    sh "$file"
    echo $(date +%d-%m-%y) $(date +%H:%M:%S) - Sleep $x - Script "$f" >>/var/log/upload.log
    x=0
  done
  x=$(( $x + 1 ))
  sleep 1
done

回答by Yushin Washio

One potential source of a similar problem is when the files matching the wildcard do not exist. In that case it just handles the word containint the *as such.

类似问题的一个潜在来源是与通配符匹配的文件不存在时。在这种情况下,它只是处理单词 containsint*本身。

$ touch exist{1,2} alsoexist1
$ for file in exist* alsoexist* notexist* neitherexist*
> do echo $file
> done
exist1
exist2
alsoexist1
notexist*
neithereixt*