skip to Main Content

I’ve got some Plesk servers I’m forced to work with, and I’ve written a script to handle backups via the CLI. The trouble is that if the Plesk backup tool encounters a problem backing up a domain the only way it will output useful information is if the entire backup job is run with a verbose flag. The trouble with that is it makes the tool output Domains [0/1]n once per second while the job runs, and if it runs for an hour then you’ve got 3600 lines of useless info pushing useful info out of the buffer. For example:

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 --------------

What I’ve been trying to do is craft a command to pipe this through that simply replaces nDomains [d+/d+] with a hashmark so the above will turn into:

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 --------------

I have found ways using sed‘s N flag as in sed ':a;N;$!ba;s:nDomains [[0-9]+/[0-9]+]:#:g' or some fudgery with tr, but this causes the entire output to be buffered and the output only generated once the backup script has completely finished.

How can I get this replacement to work in-stream so I can still get a live status output?

The command in question is:

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

Edit: I also came up with a short test script to generate the relevant text without running a dozen backups:

#!/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"

3

Answers


  1. Chosen as BEST ANSWER

    I decided it was probably a good idea to write my own little tool, and my go-to language is PHP. It's not pretty, but it gets the job done if you're interested in matching and replacing single trailing line breaks.

    <?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);
    

    and it is invoked like:

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

    and produces output:

    #######-------------- 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 --------------
    

    It's not exactly what I was looking for, but it gets the job done.

    If anyone has a different/better solution I am more than willing to give it a go.


  2. As far as I can tell there is no way to get sed to output anything without a newline. You could write a sed script that outputs the specified amount of hashes and a newline when there is a line that you want to keep. Your current script doesn’t do this, instead it just reads the whole input and only then does the editing.

    If you don’t need the #-signs, you could use

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

    to simply ignore those lines.

    Login or Signup to reply.
  3. | sed -n -u "/Domains [0/1]/ !p"
    

    the -u is a stream version of sed, sed is working until the first EOF but don’t buffer the entire result before giving the result

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search