Unix Shell脚本中的变量问题

4

我在循环内部无法传递变量。

代码:

# find all output.txt that has been modified last 24h ...
PROCESSED=1
find ${PROCESSED_DIR} -mtime -1 -name "output.txt" | while read i
do
    # .. and compare those with TMP_TXT
    if diff $i ${TMP_TXT} > /dev/null   
    then
        # If both are same EXIT search loop 
        PROCESSED=0
        exit
    fi
done
echo "PROCESSED=${PROCESSED}"

这将始终输出1。有什么办法可以使PROCESSED=0吗?
这是在Solaris 9机器上完成的。
4个回答

6
原因是while命令在管道内运行,这意味着它在子shell中运行,因此变量赋值不会传递到调用的shell。
一种解决方法是重定向输入(您可能需要先将其写入临时文件):
while read f; do
    ...
done < foo.tmp

另一个解决方案是使用 while 命令的标准输出来传播“PROCESSED”值:
PROCESSED=`find | while read f; do
    echo "Echo other stuff on stderr" >&2 
    echo 1
done`

0

这行代码

PROCESSED=0

将作为管道的一部分由while命令执行,而不是由shell执行。 如果您改用xargs并将while循环和比较放入一个单独的shell脚本中,该脚本返回适当的返回值,则可以使用

find ${PROCESSED_DIR} -mtime -1 -name "output.txt" | xargs -n1 your_compare_script.sh && PROCESSED=0

为了在shell脚本中更新PROCESSED变量。

0
问题在于您使用的shell。如果您使用sh,它将无法按照您想要的方式处理,但如果您使用ksh,它将起作用。

欢迎来到SO。感谢您的回复,但如果您能提供一些代码或链接来使您的答案更正确,那对其他用户将非常有帮助! - Prahalad Gaggar

0

你可以使用子shell的返回值将这种类型的信息传递给调用的shell:

#!/bin/sh
find $PROCESSED_DIR -type f | { while read -r i; do cmp "$i" "$TMP_TXT" > /dev/null && exit 0; done; exit 1; } PROCESSED=$? echo $PROCESSED
# 或者,如果你想要检测文件名字:
filename=$(find $PROCESSED_DIR -type f | { while read -r i; do if cmp "$i" "$TMP_TXT" > /dev/null; then echo $i; exit 0; fi done; exit 1; }) PROCESSED=$? echo $PROCESSED: $filename

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接