2

我有一些我不得不使用的 Plesk 服务器,并且我编写了一个脚本来通过 CLI 处理备份。问题在于,如果 Plesk 备份工具在备份域时遇到问题,它输出有用信息的唯一方法是整个备份作业是否使用详细标志运行。这样做的问题是它Domains [0/1]\n在作业运行时每秒使工具输出一次,如果它运行一个小时,那么你就有 3600 行无用信息将有用信息推出缓冲区。例如:

Domains [0/1]
Domains [0/1]
Domains [0/1]
Domains [0/1]
Domains [0/1]
Domains [0/1]
Domains [0/1]
Domains [0/1]
Domains [0/1]
-------------- Start print backup log hire --------------
<?xml version="1.0" encoding="UTF-8"?>
  <execution-result status="success" log-location="/usr/local/psa/PMM/sessions/2013-11-08-114156.109/migration.result"/>
-------------- End print backup log hire --------------

我一直在尝试做的是制作一个命令来通过它简单地替换\nDomains [\d+/\d+]为一个井号,所以上面将变成:

Domains [0/1]########
-------------- Start print backup log hire --------------
<?xml version="1.0" encoding="UTF-8"?>
  <execution-result status="success" log-location="/usr/local/psa/PMM/sessions/2013-11-08-114156.109/migration.result"/>
-------------- End print backup log hire --------------

我已经找到了使用sed'sN标志的方法,sed ':a;N;$!ba;s:\nDomains \[[0-9]\+/[0-9]\+\]:#:g'或者使用 's 的一些捏造tr,但这会导致整个输出被缓冲,并且只有在备份脚本完全完成后才会生成输出。

我怎样才能让这个替代品在流中工作,这样我仍然可以获得实时状态输出?

有问题的命令是:

ssh ${server} sudo ${pbackup} domains-name -v --output-file=${ftp_spec} $domain 2>&1 | \
    sed ':a;N;$!ba;s:\nDomains \[0/1\]:X:g'

编辑:我还想出了一个简短的测试脚本来生成相关文本而无需运行十几个备份:

#!/bin/bash
echo "blah blah pre text"
i=0
while [ $i -lt 5 ]; do
        echo 'Domains [0/1]'
        sleep 1
        i=$(($i + 1))
done
echo "blah blah post text"
4

3 回答 3

1

我认为编写自己的小工具可能是个好主意,我的首选语言是 PHP。它并不漂亮,但如果您对匹配和替换单个尾随换行符感兴趣,它可以完成工作。

<?php
if( $argc != 3 ) {
    echo "Bad args";
    exit(1);
} else if( ! $in = fopen('php://stdin', 'r') ) {
    echo "Could not open stdin.\n";
    exit(1);
}
while( $line = fgets($in) ) {
    $oline = preg_replace($argv[1], $argv[2], $line);
    if( is_null($oline) ) {
        echo "PCRE Error.";
        exit(1);
    } else { echo $oline; }
}
fclose($in);

它的调用方式如下:

ssh ${server} sudo ${pbackup} domains-name -v --output-file=${ftp_spec} $domain 2>&1 | \
    php streamedit.php ':Domains \[\d+/\d+\]\n:' '#'

并产生输出:

#######-------------- Start print backup log hire --------------
<?xml version="1.0" encoding="UTF-8"?>
  <execution-result status="success" log-location="/usr/local/psa/PMM/sessions/2013-11-08-142159.357/migration.result"/>
-------------- End print backup log hire --------------

这不是我想要的,但它可以完成工作。

如果有人有不同/更好的解决方案,我非常愿意试一试。

于 2013-11-08T20:29:31.163 回答
0

据我所知,没有换行符就无法让 sed 输出任何内容。您可以编写一个 sed 脚本,当您想要保留一行时,它会输出指定数量的哈希值和换行符。您当前的脚本不这样做,而是只读取整个输入,然后才进行编辑。

如果您不需要#-符号,您可以使用

| fgrep -v 'Domains [0/1]'

简单地忽略这些行。

于 2013-11-08T22:02:27.110 回答
0
| sed -n -u "/Domains \[0\/1\]/ !p"

-u 是 sed 的流版本,sed 一直工作到第一个 EOF,但在给出结果之前不要缓冲整个结果

于 2013-11-11T06:28:49.050 回答