Discussion:
[Help-bash] Brace expansions in if statement
Felipe Salvador
2018-03-29 18:12:21 UTC
Permalink
Hi list,
I'm trying to make bash to expand a brace expansion in a if statement.

So, I've

if [ "$GTTY" = tty{0..10} ]; then
msger=echo
else
msger=notify-send
fi

where $GTTY is $(tty | cut -d'/' -f3).
It doesn't work.
I'm reading allot of web pages, but I cannot get over.
Could you please help me?

Kind regards
--
Felipe Salvador
Pierre Gaston
2018-03-29 18:54:11 UTC
Permalink
Post by Felipe Salvador
Hi list,
I'm trying to make bash to expand a brace expansion in a if statement.
So, I've
if [ "$GTTY" = tty{0..10} ]; then
msger=echo
else
msger=notify-send
fi
where $GTTY is $(tty | cut -d'/' -f3).
It doesn't work.
I'm reading allot of web pages, but I cannot get over.
Could you please help me?
Kind regards
--
Felipe Salvador
Well, you will not be able to make it work, you can only test one value at
a time and { } will create 10 different arguments for [.
in the end calling [ "$GTTY" = tty1 tty2 ....tty10]
I'd probably use a case statement like:

case $(tty) in
*tty[0-9]|*tty10) msger=echo;;
*) msger=notifysend ;;
esac
Marco Silva
2018-03-29 19:02:54 UTC
Permalink
Post by Felipe Salvador
Hi list,
I'm trying to make bash to expand a brace expansion in a if statement.
So, I've
if [ "$GTTY" = tty{0..10} ]; then
msger=echo
else
msger=notify-send
fi
where $GTTY is $(tty | cut -d'/' -f3).
It doesn't work.
I'm reading allot of web pages, but I cannot get over.
Could you please help me?
Kind regards
That won't work. tty{0..10} . You want a OR operation to all
= tty{0..10}

you can write:

echo tty{0..10} | while read term; do
if [ "$GTTY" == "$term" ]; then
msger=echo
break
done

msger="${msger:-notify-send}

for same behaviour.
--
Marco Arthur @ https://optdyn.com
Nick Chambers
2018-03-29 21:16:11 UTC
Permalink
Post by Marco Silva
Post by Felipe Salvador
Hi list,
I'm trying to make bash to expand a brace expansion in a if statement.
So, I've
if [ "$GTTY" = tty{0..10} ]; then
msger=echo
else
msger=notify-send
fi
where $GTTY is $(tty | cut -d'/' -f3).
It doesn't work.
I'm reading allot of web pages, but I cannot get over.
Could you please help me?
Kind regards
That won't work. tty{0..10} . You want a OR operation to all
= tty{0..10}
echo tty{0..10} | while read term; do
if [ "$GTTY" == "$term" ]; then
if this is sh, you should be =, not == (== isn't POSIX). If it's bash, use [[
Post by Marco Silva
msger=echo
break
done
msger="${msger:-notify-send}
this is going to break due to http://mywiki.wooledge.org/BashFAQ/024

ubuntu:~ nchambers$ unset foo
ubuntu:~ nchambers$ printf 'here is some text\nand another\n' | while
read -r line; do
Post by Marco Silva
foo=$line
done
ubuntu:~ nchambers$ declare -p foo
-bash: declare: foo: not found
ubuntu:~ nchambers$
Post by Marco Silva
for same behaviour.
--
John McKown
2018-03-29 22:10:01 UTC
Permalink
Post by Marco Silva
Post by Felipe Salvador
Hi list,
I'm trying to make bash to expand a brace expansion in a if statement.
So, I've
if [ "$GTTY" = tty{0..10} ]; then
msger=echo
else
msger=notify-send
fi
where $GTTY is $(tty | cut -d'/' -f3).
It doesn't work.
I'm reading allot of web pages, but I cannot get over.
Could you please help me?
Kind regards
That won't work. tty{0..10} . You want a OR operation to all
= tty{0..10}
echo tty{0..10} | while read term; do
if [ "$GTTY" == "$term" ]; then
msger=echo
break
done
msger="${msger:-notify-send}
for same behaviour.
​How about this?

msger=notify-send
printf "%s\n" tty{0..10} | fgrep -q "${GTTY}" && msger=echo
echo ${msger}

​​

​I do admit to liking the more "unusual" approach at times. I also don't
like interpreted loops.​
Post by Marco Silva
--
--
I have a theory that it's impossible to prove anything, but I can't prove
it.

Maranatha! <><
John McKown
João Eiras
2018-03-29 22:40:19 UTC
Permalink
Post by Felipe Salvador
Hi list,
I'm trying to make bash to expand a brace expansion in a if statement.
So, I've
if [ "$GTTY" = tty{0..10} ]; then
msger=echo
else
msger=notify-send
fi
a) Use echo as a helper to expand inside expressions
b) bash has substring matching
c) mind the spaces

if [[ "$(echo " "tty{0..10}" ")" == *" $GTTY "* ]]; then
msger=echo
else
msger=notify-send
fi

But I'd simplify your expression to

if tty | cut -d'/' -f3 | grep -q '^tty[0-9]\+$'; then
# ...
fi
Post by Felipe Salvador
where $GTTY is $(tty | cut -d'/' -f3).
I'm on ubuntu, which tells me
$ tty
/dev/pts/2
$ tty | cut -d'/' -f3
pts

So I'm not entirely sure your approach is inter-operable, in case
that's an issue for you.
Greg Wooledge
2018-03-30 12:29:23 UTC
Permalink
Post by João Eiras
if [[ "$(echo " "tty{0..10}" ")" == *" $GTTY "* ]]; then
Bleh!

There is no need to fork a subshell to generate a list of words
concatenated into a string with spaces around them so that you can
do a brute force substring match of " foo " against " foo bar baz ".
That's simply unnecessary, and inefficient, and outright *weird*,
compared to the more obvious alternatives.

The answer previously given is sufficient, and is much nicer in my
opinion:

case $GTTY in
tty[0-9]|tty10) ...

If you have an allergy to case for some reason, and absolutely *insist*
that it simply *must* with be done an if, you can use extglob matching:

if [[ $GTTY = tty@([0-9]|10) ]]; then ...

Or even ERE matching:

if [[ $GTTY =~ ^tty([0-9]|10)$ ]]; then ...

Because I know how much some people like their EREs.

Or hell, you could even use two matches:

if [[ $GTTY = tty[0-9] || $GTTY = tty10 ]]; then ...

That way you don't have to worry about whether extglob is enabled or
disabled or enabled-implicitly-inside-[[ only or anything else.
And that's *still* shorter and more efficient than the $(echo) thing.
Plus, it's the most readable one.
Felipe Salvador
2018-04-04 16:45:24 UTC
Permalink
Post by Greg Wooledge
Post by João Eiras
if [[ "$(echo " "tty{0..10}" ")" == *" $GTTY "* ]]; then
Bleh!
There is no need to fork a subshell to generate a list of words
concatenated into a string with spaces around them so that you can
do a brute force substring match of " foo " against " foo bar baz ".
That's simply unnecessary, and inefficient, and outright *weird*,
compared to the more obvious alternatives.
The answer previously given is sufficient, and is much nicer in my
case $GTTY in
tty[0-9]|tty10) ...
Thank you all, I've opted for case.
Post by Greg Wooledge
If you have an allergy to case for some reason, and absolutely *insist*
if [[ $GTTY =~ ^tty([0-9]|10)$ ]]; then ...
Because I know how much some people like their EREs.
if [[ $GTTY = tty[0-9] || $GTTY = tty10 ]]; then ...
That way you don't have to worry about whether extglob is enabled or
disabled or enabled-implicitly-inside-[[ only or anything else.
And that's *still* shorter and more efficient than the $(echo) thing.
Plus, it's the most readable one.
--
Felipe Salvador
Loading...