I'm trying to force the restart of my rsyslog server. I have sanitary reboot during the day, and sometimes the restart fails, so I want to restart it until the restart is a success.
At this point I'm trying to check if the output of the restart matches the output it is supposed to give when the restart is good.
But I don't understand why the if statement below doesn't work. It always goes to the else statement whether I put a == or != in the test condition.
Is there a way to check if a multi-line string is equal to another predefined multi-line string?
#!/bin/sh
endv=0
testv="Shutting down system logger: [ OK ]
Starting system logger: [ OK ]"
startv="$(/etc/init.d/rsyslog restart)"
while [ $endv == 0 ]; do echo "$startv" if [[ "$startv" != "$testv" ]]; then startv="$(/etc/init.d/rsyslog restart)" echo THEN else echo ELSE endv=1 fi
done 4 1 Answer
A few preliminaries:
You should probably be moving away from invoking SysV init scripts directly; you are at least one and likely two steps behind the curve ( SysV init was replaced by
upstartand then bysystemd). For example:systemctl restart rsyslog.serviceWhichever init interface you use, it's likely that you can use the command's
EXIT_STATUSdirectly rather than capturing its output and testing string equality. For example:systemctl restart rsyslog.service if [ $? -ne 0 ]; then ... fi(in any case, as @choroba poined out in comments, the '[OK]' message may in fact be going to standard error rather than standard output).
In Ubuntu,
/bin/shis notbash: see DashAsBinSh. Among other things, that means it won't support the[[ . . . ]]extended test syntax.
Having got those out of the way, bash does indeed support string equality tests on multiline strings e.g.
$ str1='This is
a string'
$ str2='That is
a string'
$ str3='This is
a string'
$
$ [[ "$str1" != "$str1" ]] && echo "No match" || echo "Match"
Match
$ [[ "$str1" != "$str2" ]] && echo "No match" || echo "Match"
No match
$ [[ "$str1" != "$str3" ]] && echo "No match" || echo "Match"
Match