Discussion:
Comparing strings
(too old to reply)
ELCV
2021-07-13 17:46:43 UTC
Permalink
Hello

I can't get this right. What I have is a script to backup VM guests. The command is called with an argument, for example:

/usr/local/bin/vm-backup.sh FOO

Some of the VMs have two disks and I want to back them both up. Two of the VMs have vert large data partitions that are backed up separately and I want to exclude them.

If I do this:

if [ "$1" != "FOO" ];
then
echo "I can backup the 2nd volume";
else
exit;
fi

It works. But if I add an "or" condition as follows:

if [ "$1" != "FOO" ] || [ "$1" != "BAR" ] ;
then
echo "I can backup the 2nd volume";
else
exit;
fi

It fails. I have tried this a number of different ways and I can't get it. Any guidance is appreciated. Thanks.
Grant Taylor
2021-07-13 20:29:37 UTC
Permalink
Post by ELCV
Hello
Hi,
Post by ELCV
I can't get this right. What I have is a script to backup VM
/usr/local/bin/vm-backup.sh FOO
Some of the VMs have two disks and I want to back them both up. Two of
the VMs have vert large data partitions that are backed up separately
and I want to exclude them.
Okay. That sounds like some VMs can use a default, some need slightly
different, and still others need something special.
Post by ELCV
if [ "$1" != "FOO" ];
then
echo "I can backup the 2nd volume";
else
exit;
fi
if [ "$1" != "FOO" ] || [ "$1" != "BAR" ] ;
then
echo "I can backup the 2nd volume";
else
exit;
fi
It fails.
ORed negative logic is ... tricksy.
Post by ELCV
I have tried this a number of different ways and I can't get it. Any
guidance is appreciated. Thanks.
I would be tempted to try a case statement:

case ${1} in
FOO)
# FOO's specific backup.
BAR|BOB)
# specific backup for BAR and BOB.
*)
# default backup for all other systems.
esac

I also find that such a case statement is a lot easier to maintain long
term as systems are added / changed / removed.

Depending on how the backups work, you might consider breaking out the
actual backup actions to their discrete steps and call them as a
function. E.g. FOO would call functions 1 and 2, while BAR & BOB call
functions 2 and 3, and then everyone else would only call functions 1
and 3. Use the case as a method to choosoe which pieces to run and then
call the necessary common pieces.
--
Grant. . . .
unix || die
Lewis
2021-07-13 21:00:29 UTC
Permalink
Post by Grant Taylor
Post by ELCV
if [ "$1" != "FOO" ];
if [[ $1 != "FOO" ]];

work for me.
Post by Grant Taylor
case ${1} in
FOO)
# FOO's specific backup.
BAR|BOB)
# specific backup for BAR and BOB.
*)
# default backup for all other systems.
esac
Case is what I would do as well.
Post by Grant Taylor
I also find that such a case statement is a lot easier to maintain long
term as systems are added / changed / removed.
And that's why
Post by Grant Taylor
Depending on how the backups work, you might consider breaking out the
actual backup actions to their discrete steps and call them as a
function. E.g. FOO would call functions 1 and 2, while BAR & BOB call
functions 2 and 3, and then everyone else would only call functions 1
and 3. Use the case as a method to choosoe which pieces to run and then
call the necessary common pieces.
Agreed.
--
The more you tighten your grip, Tarkin, the more star systems will
slip through your fingers.
ELCV
2021-07-14 01:53:16 UTC
Permalink
Thank you for the replies. I did go with the case statement and functions.
Post by ELCV
Hello
Hi,
Post by ELCV
I can't get this right. What I have is a script to backup VM
/usr/local/bin/vm-backup.sh FOO
Some of the VMs have two disks and I want to back them both up. Two of
the VMs have vert large data partitions that are backed up separately
and I want to exclude them.
Okay. That sounds like some VMs can use a default, some need slightly
different, and still others need something special.
Post by ELCV
if [ "$1" != "FOO" ];
then
echo "I can backup the 2nd volume";
else
exit;
fi
if [ "$1" != "FOO" ] || [ "$1" != "BAR" ] ;
then
echo "I can backup the 2nd volume";
else
exit;
fi
It fails.
ORed negative logic is ... tricksy.
Post by ELCV
I have tried this a number of different ways and I can't get it. Any
guidance is appreciated. Thanks.
case ${1} in
FOO)
# FOO's specific backup.
BAR|BOB)
# specific backup for BAR and BOB.
*)
# default backup for all other systems.
esac
I also find that such a case statement is a lot easier to maintain long
term as systems are added / changed / removed.
Depending on how the backups work, you might consider breaking out the
actual backup actions to their discrete steps and call them as a
function. E.g. FOO would call functions 1 and 2, while BAR & BOB call
functions 2 and 3, and then everyone else would only call functions 1
and 3. Use the case as a method to choosoe which pieces to run and then
call the necessary common pieces.
--
Grant. . . .
unix || die
ELCV
2021-07-14 15:42:21 UTC
Permalink
A new issue. I am evaluating my script so I am using echo to display the commands.

My function is as follows:
singleVolume(){
# OS Volumes
echo "virsh suspend $ARG"
echo "dd if=/dev/vg0/$ARG_0 | ssh ***@111.111.111.111 dd of=/backup/images/$ARG_0.img"
echo "virsh resume $ARG"
}

When I run my command the $ARG variable in the second line is not echoed:

virsh suspend FOO
dd if=/dev/vg0/ | ssh ***@111.111.111.111 dd of=/backup/images/.img
virsh resume LIMS2

So the variable and the _0 are being dropped. I've tested without "echo" and obtained the same result.

If I create a new variable, SUFF="_0" and then use echo "dd if=/dev/vg0/$ARG$SUFF | ssh ***@111.111.111.111 dd of=/backup/images/$ARG$SUFF.img"

It works. Is this expected? It only seems an issue using functions.

Thanks.
Post by ELCV
Thank you for the replies. I did go with the case statement and functions.
Post by ELCV
Hello
Hi,
Post by ELCV
I can't get this right. What I have is a script to backup VM
/usr/local/bin/vm-backup.sh FOO
Some of the VMs have two disks and I want to back them both up. Two of
the VMs have vert large data partitions that are backed up separately
and I want to exclude them.
Okay. That sounds like some VMs can use a default, some need slightly
different, and still others need something special.
Post by ELCV
if [ "$1" != "FOO" ];
then
echo "I can backup the 2nd volume";
else
exit;
fi
if [ "$1" != "FOO" ] || [ "$1" != "BAR" ] ;
then
echo "I can backup the 2nd volume";
else
exit;
fi
It fails.
ORed negative logic is ... tricksy.
Post by ELCV
I have tried this a number of different ways and I can't get it. Any
guidance is appreciated. Thanks.
case ${1} in
FOO)
# FOO's specific backup.
BAR|BOB)
# specific backup for BAR and BOB.
*)
# default backup for all other systems.
esac
I also find that such a case statement is a lot easier to maintain long
term as systems are added / changed / removed.
Depending on how the backups work, you might consider breaking out the
actual backup actions to their discrete steps and call them as a
function. E.g. FOO would call functions 1 and 2, while BAR & BOB call
functions 2 and 3, and then everyone else would only call functions 1
and 3. Use the case as a method to choosoe which pieces to run and then
call the necessary common pieces.
--
Grant. . . .
unix || die
Grant Taylor
2021-07-14 15:58:22 UTC
Permalink
Post by ELCV
A new issue. I am evaluating my script so I am using echo to display the commands.
singleVolume(){
# OS Volumes
echo "virsh suspend $ARG"
echo "virsh resume $ARG"
}
virsh suspend FOO
virsh resume LIMS2
So the variable and the _0 are being dropped. I've tested without
"echo" and obtained the same result.
If I create a new variable, SUFF="_0" and then use echo
of=/backup/images/$ARG$SUFF.img"
It works. Is this expected? It only seems an issue using functions.
I don't know if I would /expect/ it per se or not. But I am not at all
surprised by it.

This hints at an escaping problem to me. Maybe. Maybe not.

Try changing your ssh command to be:

ssh ***@111.111.111.111 dd of=/backup/images/${ARG}_0.img

Avoid the abiguity of what is variable vs appended string.

Aside: That might not be the escaping that I was referring to as
escaping would usually be how your local shell interprets $ARG, or not,
prior to sending it to the remote shell / sub-command. Escaping is more
about where the expansion should happen. And I think your primary /
current issue is what is the variable vs data.
Post by ELCV
Thanks.
You're welcome.
--
Grant. . . .
unix || die
ELCV
2021-07-14 17:09:17 UTC
Permalink
That works! Thank you again.
Post by ELCV
A new issue. I am evaluating my script so I am using echo to display the commands.
singleVolume(){
# OS Volumes
echo "virsh suspend $ARG"
echo "virsh resume $ARG"
}
virsh suspend FOO
virsh resume LIMS2
So the variable and the _0 are being dropped. I've tested without
"echo" and obtained the same result.
If I create a new variable, SUFF="_0" and then use echo
of=/backup/images/$ARG$SUFF.img"
It works. Is this expected? It only seems an issue using functions.
I don't know if I would /expect/ it per se or not. But I am not at all
surprised by it.
This hints at an escaping problem to me. Maybe. Maybe not.
Avoid the abiguity of what is variable vs appended string.
Aside: That might not be the escaping that I was referring to as
escaping would usually be how your local shell interprets $ARG, or not,
prior to sending it to the remote shell / sub-command. Escaping is more
about where the expansion should happen. And I think your primary /
current issue is what is the variable vs data.
Post by ELCV
Thanks.
You're welcome.
--
Grant. . . .
unix || die
Grant Taylor
2021-07-14 17:37:10 UTC
Permalink
Post by ELCV
That works!
Good. :-)
Post by ELCV
Thank you again.
You're welcome.
--
Grant. . . .
unix || die
Lewis
2021-07-14 23:34:10 UTC
Permalink
Post by ELCV
A new issue. I am evaluating my script so I am using echo to display the commands.
singleVolume(){
# OS Volumes
echo "virsh suspend $ARG"
echo "virsh resume $ARG"
}
Because you are specifying a variable named $ARG_0 try

echo "if=/dev/vg0/${ARG}_0 ..."
--
You know what they say about paradigms: Shift happens.
Michael F. Stemper
2021-07-13 21:23:52 UTC
Permalink
Post by ELCV
if [ "$1" != "FOO" ];
then
echo "I can backup the 2nd volume";
else
exit;
fi
if [ "$1" != "FOO" ] || [ "$1" != "BAR" ] ;
I've never seen this syntax. I always thought that the "or"
needed to be within the test, as in:

if [[ "$1" != "FOO" ||$1 != "BAR" ]]
--
Michael F. Stemper
Psalm 94:3-6
Lewis
2021-07-14 00:07:14 UTC
Permalink
Post by Michael F. Stemper
Post by ELCV
if [ "$1" != "FOO" ];
then
echo "I can backup the 2nd volume";
else
exit;
fi
if [ "$1" != "FOO" ] || [ "$1" != "BAR" ] ;
I've never seen this syntax. I always thought that the "or"
if [[ "$1" != "FOO" ||$1 != "BAR" ]]
There's a difference between [[ ]] and [ ] ([[ ]] is superior and you
should probably just get used to using [[ ]] exclusively).

But the syntax used in the sample above is incorrect, i believe, as
single brackets require that you use -o for or.

you really only need to deal with single [ ] if you want to be
compatible with sh.
--
"Are you pondering what I'm pondering?"
"I think so, but where is a fish?"
Loading...