我有一个简单的bash脚本,它构成了我开发的内部web应用程序的一部分。
当用户删除原始图像时,其目的是自动删除图像的缩略图。
该脚本将一些基本状态信息logging到/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
。
例如,手动创build一些孤立的缩略图,然后运行我的脚本,手动生成的孤立的拇指被删除,但日志显示:
星期四9月23日23:30:12 BST 2011:删除了0条额外的拇指
我做错了什么是阻止$ filecounter显示一个非零数字,当文件被删除。
我已经创build了下面的bash脚本来testing这个,这个工作完美,输出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))
replacecount=$[$count+1]
,但不是在我的初始脚本中。
你正在使用错误的操作符。 尝试使用$(( ... ))
,例如:
$ x=4 $ y=$((x + 1)) $ echo $y 5 $
编辑
你遇到的另一个问题是管道问题。 碰到这个之前(用ksh
,但是不会让我惊讶的发现其他shell有同样的问题)。 管道分叉了另一个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,而是分叉的subshell(纯粹由while循环组成)。
一种方法,你可以得到的价值是这样的…
#!/bin/bash filecount=0 filecount=`ls /bin | while read x do filecount=$((filecount + 1)) echo $filecount done | tail -1` echo $filecount
这只会在你不关心循环中的任何其他标准输出的情况下工作,因为除了我们输出的最后一行( filecount
的最终值)之外,它将把它全部抛出。 这是有效的,因为我们使用stdout和stdin将数据反馈到父shell。
根据你的观点,这可能是一个讨厌的黑客或者一个漂亮的shell jiggery-pokery。 我会离开你来决定你的想法是什么:-)
如果将管道移到while
构造中,则删除bash需要创建一个子shell。
改变这个:
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"
Chris J是正确的 ,你正在使用错误的操作符和POSIX子shell变量范围意味着你不能以这种方式得到最终计数。
作为一个侧面说明,当做数学运算时,你也可以考虑使用let
shell像这样:
$ filecount=4 $ let filecount=$filecount+1 $ echo $filecount 5
另外,如果您希望范围正常工作,就像您期望的那样,尽管如此,您可以使用zsh而不是bash。 在这种情况下,它应该是一个下降的更换和按预期工作。