如何在bash中将命令输出转换为函数?

时间:2017-05-21 12:15:01

标签: bash

我正在尝试编写定期压缩特定目录的简单脚本。这是我的代码

#!/bin/bash
exec &> zipLogFile.log

log(){
CURRENT_TIME=$(date '+%Y-%m-%d %H:%M:%S')
if [ -n "$1" ]
then
        LEVEL=${1}
        MESSAGE=${2}
        echo "$LEVEL  $CURRENT_TIME  $MESSAGE"
else
        read IN
        LEVEL="INFO"
        echo "$LEVEL  $CURRENT_TIME  $IN"
fi
}

YESTERDAY=$(date -d "yesterday" '+%Y%m%d')
ROOT="/home/ubuntu/test"
YESTERDAY_DIR=$ROOT"/"$YESTERDAY

log "INFO" "checking directory $YESTERDAY_DIR"
if [ -d "$YESTERDAY_DIR" ]; then
        zip -r $ROOT"/"$YESTERDAY".zip" $ROOT"/"$YESTERDAY | log
        log "INFO" "Zip file $YESTERDAY_DIR.zip has been created"
else
        log "ERROR" "$YESTERDAY_DIR not exist."
fi

我的问题是我想将zip命令的输出转换为日志功能并从函数中打印出来。当我尝试使用管道时,它只打印第一行输出和break zip命令。这是我运行脚本时在logFile中得到的内容。

INFO  2017-05-21 15:09:22  checking directory /home/ubuntu/test/20170520
INFO  2017-05-21 15:09:22  adding: home/ubuntu/test/20170520/ (stored 0%)
INFO  2017-05-21 15:09:22  Zip file /home/ubuntu/test/20170520.zip has been created

我在这里做错了什么?谢谢你的帮助。

1 个答案:

答案 0 :(得分:2)

read只会读取第一行,因此您的函数会返回。当zip下一次尝试写入该管道时,它会发现管道已关闭(因为该函数已退出)并且本身已退出。

相反,您可以在循环中读取(假设您只想使用函数开头的时间):

else
    while read -r line; do
        printf '%s %s %s\n' "$LEVEL" "$CURRENT_TIME" "$line"
    done
fi

您实际上只能使用sed

else
    sed -e "s/^/$LEVEL $CURRENT_TIME /"
fi

如果你想要每一行的时间,你必须在循环的每次迭代中得到日期:

else
    while read -r line; do
        printf '%s %s %s\n' "$LEVEL" "$(date '+%Y-%m-%d %H:%M:%S')" "$line"
    done
fi