1

I have this command which will output 0, 1 or 2.

This line of code is part of a config file (zabbix), only reason for one-liner code.

mysql -u root -e  "show slave status\G" | \
grep -E 'Slave_IO_Running:|Slave_SQL_Running:' | cut -f2 -d':' | \
sed "s/No/0/;s/Yes/1/" | awk '{ SUM += $1} END { print SUM }'

But I want it to output values to be like this so I can setup alert with correct status:

If only Slave_IO_Running is No then output 1.

If only Slave_SQL_Running is No then output 2.

If both are Yes then output 3.

If both are No then output 0.

If no lines/output from show slave status command then output 4.

So something like modify first entry of No with a unique value using sed or awk. And second entry with unique value and so on.

Output of show slave status\G

mysql> show slave status\G
*************************** 1. row ***************************
               Slave_IO_State: Waiting for master to send event
                  Master_Host: 10.10.10.10
                  Master_User: replicationslave
                  Master_Port: 3306
                Connect_Retry: 60
              Master_Log_File: mysql-bin.009081
          Read_Master_Log_Pos: 856648307
               Relay_Log_File: mysqld-relay-bin.002513
                Relay_Log_Pos: 1431694
        Relay_Master_Log_File: mysql-bin.009081
             Slave_IO_Running: Yes
            Slave_SQL_Running: Yes
3
  • 1
    Can you include the output of just the mysql -u root -e "show slave status\G" command, so that we have a better idea of what data you're manipulating, and can test the solutions we might come up with? Commented Aug 10, 2017 at 12:21
  • You can use if statements without having to run the query twice, variables exist for a reason. Commented Aug 10, 2017 at 12:23
  • Note, if you end a line with a pipe, you don't need the line-continuation backslash -- bash knows you're not done. Commented Aug 10, 2017 at 15:00

3 Answers 3

2

You can do all the string processing here in awk:

mysql -u root -e  "show slave status\G" | awk 'BEGIN {output=0} /Slave_IO_Running.*No/ {output+=1} /Slave_SQL_Running.*No/ {output +=2} END {if(output==3}{print 0} else {if(output==0} {print 3} else {print output}}'

This will start the output counter at 0, if we match Slave_IO_Running with No we'll add 1. If we match Slave_SQL_Running with No we'll add 2, then at the end we'll print the total, which will be 0 if neither are matched, 1 if only IO is No, 2 if only SQL is No and 3 if both are No. Since you want to print 0 if both are Yes we reverse our count at the end, if we got a 3 then both were "No" so print 0, otherwise if it was 0 print 3, else print its own value.

Sign up to request clarification or add additional context in comments.

6 Comments

Some explanation of your answer would be lovely.
@ghoti was already underweigh, though I then saw the edit to the question about wanting 3 if both are yes and had to fix things a bit
Thank you. You first edit was still okay I think. If both were yes, it returned 0. Its 3 if both were No. I'm actually using your first edit. Correct me if I should updated one. I don't mind which number but the values have to be unique so I can assign each value to a status.
If you don't mind whether it's 0 or 3, then I'd go with the first one, it's simpler
Edit suggested to include "else if (NR==0) print 4;" because if there is no output due to any issues we can print 4.
|
2

The following awk code could be compacted into a single line if you feel the urge to do that:

awk -F: -v ret=0 '
  /Slave_IO_Running:.*No/ { ret=1 }
  /Slave_IO_Running:.*Yes/ { yes++ }
  /Slave_SQL_Running:.*No/ { ret=(ret==1) ? 0 : 2 }
  /Slave_SQL_Running:.*Yes/ { yes++ }
  END { print (yes==2) ? 3 : ret }
'

No grep or cut or sed is required, this takes the output of your mysql command directly. It also assumes that Slave_IO_Running will always appear before Slave_SQL_Running in the output of your command.

The notation in the third line and last line functions as an in-line "if" statement -- if the value of ret equals 1, set ret to 0; otherwise set ret to 2.

Comments

2

Whenever you have name to value pairs in your data it's usually clearest, simplest and easiest to enhance later to first create an array mapping the names to the values and then access the values by their names, e.g.:

awk '
{ f[$1]=$2 }
END {
    if (f["Slave_10_Running:"] == "Yes")
        rslt = (f["Slave_SQL_Running:"] == "Yes" ? 3 : 2)
    else
        rslt = (f["Slave_SQL_Running:"] == "Yes" ? 1 : 0)
    print rslt
}
' file
1

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.