繁体   English   中英

Shell脚本中的奇怪输出

[英]Strange output in shell script

在编写shell脚本时遇到了非常奇怪的事情。

最初我有以下脚本。

OUTPUT_FOLDER=/home/user/output
HOST_FILE=/home/user/host.txt
LOG_DIR=/home/user/log
SLEEPTIME=60

mkdir -p $OUTPUT_FOLDER

while true
do
    rm -f $OUTPUT_FOLDER/*
    DATE=`date +"%Y%m%d"`
    DATETIME=`date +"%Y%m%d_%H%M%S"`
    pssh -h $HOST_FILE -o $OUTPUT_FOLDER
    while read host
    do
        numline=0
        while read line
        do
            if [[ $numline == 0 ]]
            then
                FIELD1=`echo $line | cut -d':' -f2 | cut =d' ' -f2`
            fi
            ((numline+=1))
        done < ${OUTPUT_FOLDER}/${host}
        echo "$DATETIME,$FIELD1" >> ${LOG_DIR}/${DATE}.log
    done < $HOST_FILE
    sleep $SLEEPTIME
done

当我运行此脚本时,每60秒,我将在日志文件中看到$DATETIME,$FIELD1值。

十分奇怪的是,在第一分钟过去之后,每隔30秒左右,我会看到20160920_120232, ,,这意味着在不应该存在的地方有输出,我想是因为我删除了输出文件夹的内容, FIELD1为空。

更奇怪的是,在尝试调试时,我添加了一些其他echo语句以打印到日志文件,然后删除了这些行。 但是,第一分钟过去后,它们仍每30秒左右打印一次。

仍然很奇怪的是,我然后注释掉了while true块中的所有内容,即

OUTPUT_FOLDER=/home/user/output
HOST_FILE=/home/user/host.txt
LOG_DIR=/home/user/log
SLEEPTIME=60

mkdir -p $OUTPUT_FOLDER

while true
do
: << 'END'
    rm -f $OUTPUT_FOLDER/*
    DATE=`date +"%Y%m%d"`
    DATETIME=`date +"%Y%m%d_%H%M%S"`
    pssh -h $HOST_FILE -o $OUTPUT_FOLDER
    while read host
    do
        numline=0
        while read line
        do
            if [[ $numline == 0 ]]
            then
                FIELD1=`echo $line | cut -d':' -f2 | cut =d' ' -f2`
            fi
            ((numline+=1))
        done < ${OUTPUT_FOLDER}/${host}
        echo "$DATETIME,$FIELD1" >> ${LOG_DIR}/${DATE}.log
    done < $HOST_FILE
    sleep $SLEEPTIME
END
done

即使使用此脚本,我也不希望将任何内容打印到日志文件中,但仍会看到我之前删除的echo语句,以及带有空FIELD1的行。 我已经检查过我每次都在运行正确版本的脚本。

到底是怎么回事?

不确定,这可能是搞砸的实际原因。 你有一个不正确使用cut的行数22可能已经毁损了FIELD1不经意间。

FIELD1=`echo $line | cut -d':' -f2 | cut =d' ' -f2`
#                                        ^ incorrect usage of the delimiter '-d' flag

应该被用作

FIELD1=`echo $line | cut -d':' -f2 | cut -d' ' -f2`
#                                        ^ Proper usage of the '-d' flag with space delimiter

我试图捕获管道命令的输出,以查看上一条命令是否可以成功执行,以下是我的观察结果。

echo $line | cut -d':' -f2 | cut =d' ' -f2;echo "${PIPESTATUS[@]}"
cut: =d : No such file or directory     # --> Error from the failed 'cut' command
0 0 1                                   # --> Return codes of each of the command being piped

另外,如果您是bash纯粹主义者,则可以避免使用传统的`` style命令扩展,并使用$(cmd)语法,例如

FIELD1=$(echo "$line" | cut -d':' -f2 | cut -d' ' -f2)

另一个更简单的方法是避免使用cutecho并进行纯bash字符串操作。

假设您的$line包含: 分隔字符串,例如"What Hell:Hello World" ,您正在尝试提取World部分,就像我看到的那样

FIELD1="${line##* }"   # Strips-off characters until last occurrence of whitespace

我试图重现它,但是不能。 这样就没有理由让该脚本(当有评论时)产生任何输出。

有几种情况:

  1. 正如其他人指出的那样,可能还有其他脚本正在写入您的日志文件
  2. 您可能已经在其他终端上运行了该脚本的少量实例
  3. 您可能每5分钟从crontab运行一次此脚本

为了排除可能性,请执行“ ps -aef”并检查所有可能类似于脚本名称的进程。 要从crontab捕获消息,您可能需要更长的时间来观察“ ps -aef”的输出(或者只是检查crontab条目)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM