BASH:在一行上打印输出

HTF*_*HTF 20 bash

我在下面有这个简单的脚本来并行地将压缩的MySQL转储流式传输到Amazon S3存储桶:

#!/bin/bash

COMMIT_COUNT=0
COMMIT_LIMIT=2

for i in $(cat list.txt); do

        echo "$i "

        mysqldump -B $i | bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2 &


        (( COMMIT_COUNT++ ))

        if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]; then
        COMMIT_COUNT=0
        wait
        fi

done

if [ ${COMMIT_COUNT} -gt 0 ]; then
        wait
fi
Run Code Online (Sandbox Code Playgroud)

输出如下所示:

database1 
database2 
duration: 2.311823213s
duration: 2.317370326s
Run Code Online (Sandbox Code Playgroud)

有没有办法在每个转储的一行上打印这个?

database1 - duration: 2.311823213s
database2 - duration: 2.317370326s
Run Code Online (Sandbox Code Playgroud)

echo -n在这种情况下,开关没有帮助.

编辑:5月6日星期三15:17:29 BST 2015

我能够根据公认的答案达到预期的结果:

echo "$i -" $(mysqldump -B $i| bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2 2>&1) &
Run Code Online (Sandbox Code Playgroud)

- 但是在子shell中运行的命令没有将退出状态返回到父shell,因为它并行运行,因此我无法验证它是成功还是失败.

tiv*_*ivn 6

我认为这个命令会做你想要的:

echo "$i -" `(mysqldump -B $i | bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2) 2>&1` &
Run Code Online (Sandbox Code Playgroud)

或者,用来$()代替反引号:

echo "$i -" $( (mysqldump -B $i| bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2) 2>&1 ) &
Run Code Online (Sandbox Code Playgroud)

echo命令将mysqldump ..在尝试与之一起打印之前等待结果完成$i.子shell ( … )和错误重定向2>&1确保错误消息也进入回显输出.之后的空间$(是必要的,因为$((没有空格是一个不同的特殊操作 - 算术扩展.


HTF*_*HTF 5

感谢您的帮助,但我想我终于找到了最佳解决方案.

基本上我习惯于xargs格式化输出,因此每个条目(转储名称+持续时间)都在一行上.我还添加了作业规范来wait命令获取退出状态:

男人打击

wait [n ...]等待每个指定的进程并返回其终止状态.每个n可以是进程ID或作业规范; 如果给出了作业规范,则等待该作业管道中的所有进程.如果未给出n,则等待所有当前活动的子进程,并且返回状态为零.如果n指定不存在的进程或作业,则返回状态为127.否则,返回状态是最后一个进程或作业等待的退出状态.

测试:

# sh -c 'sleep 5; exit 1' &
[1] 29970
# wait; echo $?
0
# sh -c 'sleep 5; exit 1' &
[1] 29972
# wait $(jobs -p); echo $?
1
Run Code Online (Sandbox Code Playgroud)

最后的脚本:

#!/bin/bash

COMMIT_COUNT=0
COMMIT_LIMIT=2


while read -r i; do

    mysqldump -B $i | bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2 |& xargs -I{} echo "${DB} - {}" &

    (( COMMIT_COUNT++ ))

    if [ ${COMMIT_COUNT} -eq ${COMMIT_LIMIT} ]; then
        COMMIT_COUNT=0
        wait $(jobs -p)
    fi

done < list.txt

if [ ${COMMIT_COUNT} -gt 0 ]; then
     wait $(jobs -p)
fi

if [ $? -ne 0 ]; then
     echo "ERROR: Backups failed"
     exit 1
fi  
Run Code Online (Sandbox Code Playgroud)