2012-12-02 67 views
2

我有一个shell脚本,看起来像下面的代码片段:修改出口变量在shell脚本

... 
export updates=0 

processFiles() { 
    updates=$((updates+1)) 
} 

export -f processFiles 
find $path -exec /bin/bash -c "processFiles '{}'" \; 

echo $updates 

使用是计算的更新,插入和文件数量,以保持。不幸的是,最后的回声总是打印0.

我已经尝试在函数中使用导出 - 没有工作。

+2

变量'updates'在子进程中被修改。父进程永远不会看到它的修改。现在告诉我们你想要达到的目标,也许还有另一种解决方案比你想要的效率更高。 –

+0

目标是在脚本完成后打印一些“统计信息”。 processFiles可以保持原样,插入新文件或更新现有文件。所有文件处理完毕后,我想知道每个操作发生的次数。这个统计信息是在查找完成它的职责后打印的,因此在processFiles函数中不可能这样做。 – sge

回答

1

代替使用find,您可以直接使用bash,前提是您的搜索条件足够简单。例如,

for file in *; do 
    processFiles "$file" 
done 

将与参数上的所有文件和当前目录的目录执行功能processFiles(除了隐藏的)每个文件和目录的名称。如果你需要递归其应用到所有文件和目录和子目录(除隐藏的),使用globstar外壳选项:

#!/bin/bash 

shopt -s globstar 
shopt -s nullglob 

updates=0 

processFiles() { 
    ((++updates)) 
} 

for file in **; do 
    processFiles "$file" 
done 

echo "$updates" 

如果你只想文件,并没有目录,在插入这个for循环:

[[ -f "$file" ]] || continue 

将继续循环,如果file不是一个文件(即,如果是别的东西,就像一个目录)。

要通过扩大可变path获取目录仅匹配文件,写你的for循环这样的:

for file in "$path"/*; do 

(或"$path"/**如果你使用globstar,想递归)。

如果您需要更复杂的搜索条件,则始终可以使用extglob选项。如果您还需要包含隐藏文件,请使用dotglob选项。

可以找到有关的参考手册bash的更多信息,特别是以下部分:

最后一点:如果你真的不喜欢这个100%bash解决方案,并且你还想做点什么在OP中保留脚本,然后不使用bash变量,而是使用(临时)文件来存储需要从一个进程传递到另一个进程的值。这是一种便宜的IPC方法,运行良好,但安全实施起来更加困难。

+0

我真的很喜欢这个解决方案!现在只剩下一件事了:当找到最后一个文件时,for循环会启动。是否有可能修改此解决方案,以便在找到该文件时正确执行该功能(如find -exec)? – sge

+0

@Lorunification我不知道这是否可能......事实上,我真的怀疑这是可能的,但也许有人更聪明会想出更好的(简单)解决方案。 –

+0

不过,非常感谢你! – sge