我有一个简单的bash脚本,它构成了我开发的内部Web应用程序的一部分。
目的是在用户删除原始图像时自动删除图像的缩略图。
该脚本将一些基本状态信息记录到文件/var/log/images.log
#!/bin/bash
cd $thumbpath
filecount=0
# Purge extraneous thumbs
find . -type f | while read file
do
if [ ! -f "$imagepath/$file" ]
then
filecount=$[$filecount+1]
rm -f "$file"
fi
done
echo `date`: $filecount extraneous thumbs removed>>/var/log/images.log
虽然脚本正确地删除了拇指,但它没有正确输出正在清除的拇指数量,它始终显示0
。
例如,只需手动创建一些孤立的缩略图,然后运行我的脚本,就会删除手动生成的孤立拇指,但日志会显示:
Thu Jun 9 23:30:12 BST 2011:0删除了无关的拇指
如果文件 被删除,那么阻止$ filecounter显示非零数字的错误是什么?
我已经创建了以下bash脚本来测试它,这很有效,输出0
然后1
:
#!/bin/bash
count=0
echo $count
count=$[$count+1]
echo $count
修改
感谢您的回答,但为什么以下工作
$ x=3
$ x=$[$x+1]
$ echo $x
4
...第二个例子也有效,但它在第一个脚本中不起作用吗?
第二次修改:
这有效
count=0
echo Initial Value $count
for i in `seq 1 5`
do
count=$[$count+1]
echo $count
done
echo Final Value $count
Initial Value 0
1
2
3
4
5
Final Value 5
将count=$[$count+1]
替换为count=$((count+1))
,而不是在我的初始脚本中。
答案 0 :(得分:6)
你使用的是错误的操作员。请尝试使用$(( ... ))
,例如:
$ x=4
$ y=$((x + 1))
$ echo $y
5
$
修改强>
你遇到的另一个问题是管道问题。之前碰到了这个(用ksh
,但我不会惊讶地发现其他炮弹有同样的问题)。管道正在分支另一个bash进程,因此当你执行增量时,filcount会在管道之后分叉的子shell 中递增。由于子shell具有自己独立的环境(环境变量在被调用的进程中继承,但被调用的进程无法修改调用进程的环境),因此该值不会传递回调用shell。
作为一个例子,这表明filecount增加好了:
#!/bin/bash
filecount=0
ls /bin | while read x
do
filecount=$((filecount + 1))
echo $filecount
done
echo $filecount
...所以你应该看到循环中的filecount增加,但是最终的filecount将为零,因为这个echo属于主shell,但是分叉的子shell(纯粹由while循环组成)。
你可以获得价值的一种方法就是这样......
#!/bin/bash
filecount=0
filecount=`ls /bin | while read x
do
filecount=$((filecount + 1))
echo $filecount
done | tail -1`
echo $filecount
这只有在你不关心循环中的任何其他stdout输出时才会起作用,因为这会将它从我们输出的最后一行(filecount
的最终值)抛出。这是有效的,因为我们使用stdout和stdin将数据反馈给父shell。
根据你的观点,这可能是一个令人讨厌的黑客或一个漂亮的shell jiggery-pokery。我会让你决定你的想法: - )
答案 1 :(得分:2)
如果将管道移除到while
构造中,则删除bash创建子壳的需要。
改变这个:
filecount=0
find . -type f | while read file; do
if [ ! -f "$imagepath/$file" ]; then
filecount=$[$filecount+1]
rm -f "$file"
fi
done
echo $filecount
到此:
filecount=0
while read file; do
if [ ! -f "$imagepath/$file" ]; then
rm -f "$file" && (( filecount++ ))
fi
done < <(find . -type f)
echo $filecount
由于最后隐藏了find
命令,因此难以阅读。另一种可能性是:
files=$( find . -type f )
while ...; do
:
done <<< "$files"
答案 2 :(得分:1)
Chris J is quite right您使用了错误的运算符和POSIX子shell变量作用域意味着您无法以这种方式获得最终计数。
作为旁注,在进行数学运算时,您还可以考虑使用let
shell bultin:
$ filecount=4
$ let filecount=$filecount+1
$ echo $filecount
5
此外,如果您希望范围尽可能像您预期的那样工作,尽管有管道,您可以使用zsh而不是bash。在这种情况下,它应该是替代品,并按预期工作。