我在下面有这个简单的脚本来并行地将压缩的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
输出如下所示:
database1 
database2 
duration: 2.311823213s
duration: 2.317370326s
有没有办法在每个转储的一行上打印这个?
database1 - duration: 2.311823213s
database2 - duration: 2.317370326s
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) &
- 但是在子shell中运行的命令没有将退出状态返回到父shell,因为它并行运行,因此我无法验证它是成功还是失败.
我认为这个命令会做你想要的:
echo "$i -" `(mysqldump -B $i | bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2) 2>&1` &
或者,用来$()代替反引号:
echo "$i -" $( (mysqldump -B $i| bzip2 -zc | gof3r put -b s3bucket -k $i.sql.bz2) 2>&1 ) &
该echo命令将mysqldump ..在尝试与之一起打印之前等待结果完成$i.子shell ( … )和错误重定向2>&1确保错误消息也进入回显输出.之后的空间$(是必要的,因为$((没有空格是一个不同的特殊操作 - 算术扩展.
感谢您的帮助,但我想我终于找到了最佳解决方案.
基本上我习惯于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
最后的脚本:
#!/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