Unix Shell脚本中的变量问题

时间:2009-08-10 11:14:32

标签: shell solaris unix

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

代码:

# 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 个答案:

答案 0 :(得分:6)

原因是while - 命令在管道内运行,这意味着它在子shell中运行,因此变量赋值不会传播到调用shell。

一种解决方案是重定向输入(您可能需要先将其写入临时文件):

while read f; do
    ...
done < foo.tmp

另一个解决方案是使用while命令中的stdout传播PROCESSED的值:

PROCESSED=`find | while read f; do
    echo "Echo other stuff on stderr" >&2 
    echo 1
done`

答案 1 :(得分: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变量。

答案 2 :(得分: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

# or, if you want to detect the filename as well:

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

答案 3 :(得分:0)

问题是您正在使用的shell。如果你这样做,它将不会按你想要的方式处理,但如果你做了ksh,它就会起作用。