为什么这个bash while循环无限?

时间:2014-06-22 14:54:32

标签: bash while-loop infinite

这是我第一次制作bash脚本......

我试图创建一个bash脚本,它将删除目录中最旧的文件,直到所述目录的大小不一致为止。一旦目录不到10000字节,我希望while看起来停止。 10000仅用于测试;我稍后会增加它。

du和cut将目录大小以字节为单位放入名为check的变量中 当文件大小大于10000字节时,应该运行while外观。 对于每次迭代,目录中最旧的文件都将被删除。

当我运行这个脚本时,最旧的文件被删除,但是当$ check变得小于10000时,它会无限重复。为什么这个脚本会无限运行?

check = $(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)

while [ $check -gt 10000 ]
check = $(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)
do
cd /home/chris/Dropbox/VideoMonitor
ls /home/chris/Dropbox/VideoMonitor -1tr | head -1 | xargs rm
done

这是脚本从目录中删除所有文件后得到的输出。

rm: missing operand
Try 'rm --help' for more information.

这一遍又一遍地运行

4 个答案:

答案 0 :(得分:2)

我认为do必须在重新分配check之前。否则它实际上不是循环体的一部分。在主体执行之后(以及在循环条件的下一个测试之前),也可以完成赋值:

check=$(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)

while [ $check -gt 10000 ]
do
cd /home/chris/Dropbox/VideoMonitor
ls /home/chris/Dropbox/VideoMonitor -1tr | head -1 | xargs rm
check=$(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)
done

我还删除了=周围的空格,以使check=...行实际分配语句。

答案 1 :(得分:2)

您的脚本中有两个错误:

第一个错误是损坏的while子句,应该是

while condition; do
    commands
done

while condition
do
    commands
done

condition可能是一个测试表达式,当正确写时,它会返回零或非零:

[ $check -gt 10000 ]

该行

check = $(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)
do错位之前

。我打赌你想把它放在do之后再次获得价值。

第二个错误是您的xargs用法。由于您要传递给xargs的文件列表可能为空,因此您需要添加切换--no-run-if-empty以修复rm: missing operand错误。

为了避免两次写check行,你可以编写一个while-true循环并检查内部条件并跳出循环,因为bash没有头控制的while循环。

while [ true ]; do
   check = ...
   if [ $check -le 10000 ]; then
       break
   fi

   ...
done

其他sugestions

  • 您不需要每次都在循环中执行cd,在
  • 之前执行此操作
  • 如果您要删除超过特定时间的文件而不是检查目录大小,可以使用find -mtime +N(查找修改日期较早(+)的文件而不是{{ 1}}天)
  • 有时bash的Npushdpopd更方便,因为cd在脚本执行后更改了目录,您需要记住前一个目录cd 1}} pushd cd back. With popd`将您带回上一个目录。在directory stack functions

答案 2 :(得分:0)

你的while循环子句中有两个命令,[ $check -gt 10000 ]check = $(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)(由于= - 符号周围的空格,这是一个错误的命令而不是一个分配。后一个命令是唯一一个确定while循环是否永远终止的命令。如果它的返回码总是0,则while循环永远不会结束..

如果没有文件,那么rm命令没有操作数,因此错误消息..

答案 3 :(得分:0)

不要在作业中的=周围放置空格

check=$(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)

while [ $check -gt 10000 ]
check = $(du -sb /home/chris/Dropbox/VideoMonitor | cut -f1)
do
cd /home/chris/Dropbox/VideoMonitor
ls /home/chris/Dropbox/VideoMonitor -1tr | head -1 | xargs rm
done