Case fallthrough based on if condition
Clash Royale CLAN TAG#URR8PPP
up vote
10
down vote
favorite
I am looking for a way to have fallthrough happen based on an if condition within a case condition in bash. For example:
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
# perform fallthrough
else
# do not perform fallthrough
fi
;;
*)
echo "fallthrough worked!"
;;
esac
In the above code, if the variable VAR
is 1
, I would like to have the case condition perform fallthrough.
bash shell-script case
add a comment |Â
up vote
10
down vote
favorite
I am looking for a way to have fallthrough happen based on an if condition within a case condition in bash. For example:
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
# perform fallthrough
else
# do not perform fallthrough
fi
;;
*)
echo "fallthrough worked!"
;;
esac
In the above code, if the variable VAR
is 1
, I would like to have the case condition perform fallthrough.
bash shell-script case
1
Small question: Are you trying to jump fromif [ $VAR -eq 1 ]; then
part of the code to whatever is in*)
? Because that's entirely different from what fallthrough is called, thus making your question phrasing just slightly misleading.
â Sergiy Kolodyazhnyy
May 28 at 20:24
add a comment |Â
up vote
10
down vote
favorite
up vote
10
down vote
favorite
I am looking for a way to have fallthrough happen based on an if condition within a case condition in bash. For example:
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
# perform fallthrough
else
# do not perform fallthrough
fi
;;
*)
echo "fallthrough worked!"
;;
esac
In the above code, if the variable VAR
is 1
, I would like to have the case condition perform fallthrough.
bash shell-script case
I am looking for a way to have fallthrough happen based on an if condition within a case condition in bash. For example:
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
# perform fallthrough
else
# do not perform fallthrough
fi
;;
*)
echo "fallthrough worked!"
;;
esac
In the above code, if the variable VAR
is 1
, I would like to have the case condition perform fallthrough.
bash shell-script case
asked May 28 at 19:07
Smashgen
984
984
1
Small question: Are you trying to jump fromif [ $VAR -eq 1 ]; then
part of the code to whatever is in*)
? Because that's entirely different from what fallthrough is called, thus making your question phrasing just slightly misleading.
â Sergiy Kolodyazhnyy
May 28 at 20:24
add a comment |Â
1
Small question: Are you trying to jump fromif [ $VAR -eq 1 ]; then
part of the code to whatever is in*)
? Because that's entirely different from what fallthrough is called, thus making your question phrasing just slightly misleading.
â Sergiy Kolodyazhnyy
May 28 at 20:24
1
1
Small question: Are you trying to jump from
if [ $VAR -eq 1 ]; then
part of the code to whatever is in *)
? Because that's entirely different from what fallthrough is called, thus making your question phrasing just slightly misleading.â Sergiy Kolodyazhnyy
May 28 at 20:24
Small question: Are you trying to jump from
if [ $VAR -eq 1 ]; then
part of the code to whatever is in *)
? Because that's entirely different from what fallthrough is called, thus making your question phrasing just slightly misleading.â Sergiy Kolodyazhnyy
May 28 at 20:24
add a comment |Â
8 Answers
8
active
oldest
votes
up vote
8
down vote
You can't. The way to have a case
fall through is to replace the ;;
separator with ;&
(or ;;&
). And it's a syntax error to put that inside an if.
You could write the whole logic out as a regular conditional:
if [ "$input" != "foo" ] ||ÃÂ [ "$VAR" = 1 ]; then
one branch ...
else # $input = "foo" && $VAR != 1
another branch...
fi
Yes, He can ! :)
â Isaac
May 29 at 8:46
@Isaac, well, yeah, though they did specify basing the fallthrough on anif
.
â ilkkachu
May 29 at 9:10
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
add a comment |Â
up vote
7
down vote
I'd suggest restructuring your logic: put the "fallthrough" code into a function instead:
fallthrough() echo 'fallthrough worked!';
for input in foo bar; do
for var in 1 2; do
echo "$input $var"
case $input in
foo)
if (( var == 1 )); then
echo "falling through"
fallthrough
else
echo "not falling through"
fi
;;
*) fallthrough;;
esac
done
done
outputs
foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!
add a comment |Â
up vote
7
down vote
The following script turns your test "inside out" in the sense that we test $var
first and then perform the fallthrough (using ;&
in a case
) depending on $input
.
We do this because the question of whether or not to "perform the fallthrough" is really only dependent on $input
if $var
is 1
. If it's any other value, the question of whether to do the fallthrough does not even have to be asked.
#/bin/bash
input='foo'
var='1'
case $var in
1)
case $input in
foo)
echo 'perform fallthrough'
;&
*)
echo 'fallthough worked'
esac
;;
*)
echo 'what fallthrough?'
esac
Or, without case
:
if [ "$var" -eq 1 ]; then
if [ "$input" = 'foo' ]; then
echo 'perform fallthrough'
fi
echo 'fallthough worked'
else
echo 'what fallthrough?'
fi
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in*)
. Already have my +1.
â Sergiy Kolodyazhnyy
May 28 at 20:26
add a comment |Â
up vote
5
down vote
Not something that I would do, but you could achieve something approaching with:
shopt -s extglob # for !(*)
default='*'
case $input in
(foo)
if [ "$VAR" = 1 ]; then
echo going for fallthrough
else
echo disabling fallthrough
default='!(*)'
fi ;;&
($default)
echo fallthrough
esac
add a comment |Â
up vote
2
down vote
Test both variables at once (bash 4.0-alpha+):
#!/bin/bash
while (($#>1)); do
input=$1 VAR=$2
echo "input=$input VAR=$VAR"; shift 2
if [ "$VAR" = 1 ]; then new=1; else new=0; fi
case $input$new in
foo0) echo "do not perform fallthrough" ;;
foo*) echo "perform fallthrough" ;&
*) echo "fallthrough worked!" ;;
esac
echo
done
On testing:
$ ./script foo 0 foo 1 bar baz
input=foo VAR=0
do not perform fallthrough
input=foo VAR=1
perform fallthrough
fallthrough worked!
input=bar VAR=baz
fallthrough worked!
Clean and simple.
Understand that the tested value ($new
) must have only two possible values, that is why the if clause is there, to transform VAR to a Boolean value. If VAR may be made to be a Boolean, then test for 0
(not 1
) in the case
and remove the if
.
add a comment |Â
up vote
1
down vote
You can make the fallthrough default but place a condition that the code only executes only if the condition is met
#!/bin/bash
input='foo'
var='1'
case $input in
foo)
echo "Do fall through"
;& #always fall through
*)
if [ $var = "1" ] #execute only if condition matches
then
echo "fallthrough took place"
fi
esac
But as ilkkachu suggested you can also use conditions rather than switch.
add a comment |Â
up vote
1
down vote
If you don't mind someone complaining about they don't understand your code, you could simply switch the order of the two conditionals:
input="foo"
VAR="1"
if
case $input in
foo)
[ $VAR = "1" ]
;;
esac
then
echo "fallthrough worked!"
fi
Or:
input="foo"
VAR="1"
case $input in
foo)
[ $VAR = "1" ]
;;
esac &&
echo "fallthrough worked!"
Simple and clear (at least to me). case
doesn't support fallthrough itself. But you can replace *)
with &&
after esac
to make it respect to the return values of other branches.
add a comment |Â
up vote
-4
down vote
New ;&
and ;;&
operators were introduced in Bash
4.0
and although they both might be useful in similar situations I think
they are of no use in your case. This is what man bash
says about
these operators:
If the ;; operator is used, no subsequent matches are attempted after
the first pattern match. Using ;& in place of ;; causes execution to
continue with the list associated with the next set of patterns. Using
;;& in place of ;; causes the shell to test the next pattern list in
the statement, if any, and execute any associated list on a successful
match.
In other words, ;&
is a fall through and as we know it from C
and;;&
makes bash
check remaining cases instead of returning fromcase
block entirely. You can find a nice example of ;;&
in action
here: https://stackoverflow.com/a/24544780/3691891.
That being said, neither ;&
nor ;;&
could be used in your script
because both of them would go to *)
that would be always run.
The following script works and does what you want without re-arranging
the logic but consider it only as an example and never rely on it, it's too fragile.
I've taken the idea from
here:
#!/usr/bin/env bash
function jumpto
grep -v ':$')
cmd=$(echo "$cmd"
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
printf "perform fallthroughn"
jumpto ft
else
printf "do not perform fallthroughn"
fi
;;
*)
ft:
echo "fallthrough worked!"
;;
esac
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
1
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from thejumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block betweenft:
and;;
is a coincidence becausejumpto
is the last command in the same complex command as the jumped-to block.
â Gilles
May 28 at 20:59
1
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
add a comment |Â
8 Answers
8
active
oldest
votes
8 Answers
8
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
8
down vote
You can't. The way to have a case
fall through is to replace the ;;
separator with ;&
(or ;;&
). And it's a syntax error to put that inside an if.
You could write the whole logic out as a regular conditional:
if [ "$input" != "foo" ] ||ÃÂ [ "$VAR" = 1 ]; then
one branch ...
else # $input = "foo" && $VAR != 1
another branch...
fi
Yes, He can ! :)
â Isaac
May 29 at 8:46
@Isaac, well, yeah, though they did specify basing the fallthrough on anif
.
â ilkkachu
May 29 at 9:10
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
add a comment |Â
up vote
8
down vote
You can't. The way to have a case
fall through is to replace the ;;
separator with ;&
(or ;;&
). And it's a syntax error to put that inside an if.
You could write the whole logic out as a regular conditional:
if [ "$input" != "foo" ] ||ÃÂ [ "$VAR" = 1 ]; then
one branch ...
else # $input = "foo" && $VAR != 1
another branch...
fi
Yes, He can ! :)
â Isaac
May 29 at 8:46
@Isaac, well, yeah, though they did specify basing the fallthrough on anif
.
â ilkkachu
May 29 at 9:10
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
add a comment |Â
up vote
8
down vote
up vote
8
down vote
You can't. The way to have a case
fall through is to replace the ;;
separator with ;&
(or ;;&
). And it's a syntax error to put that inside an if.
You could write the whole logic out as a regular conditional:
if [ "$input" != "foo" ] ||ÃÂ [ "$VAR" = 1 ]; then
one branch ...
else # $input = "foo" && $VAR != 1
another branch...
fi
You can't. The way to have a case
fall through is to replace the ;;
separator with ;&
(or ;;&
). And it's a syntax error to put that inside an if.
You could write the whole logic out as a regular conditional:
if [ "$input" != "foo" ] ||ÃÂ [ "$VAR" = 1 ]; then
one branch ...
else # $input = "foo" && $VAR != 1
another branch...
fi
answered May 28 at 20:05
ilkkachu
47.8k668131
47.8k668131
Yes, He can ! :)
â Isaac
May 29 at 8:46
@Isaac, well, yeah, though they did specify basing the fallthrough on anif
.
â ilkkachu
May 29 at 9:10
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
add a comment |Â
Yes, He can ! :)
â Isaac
May 29 at 8:46
@Isaac, well, yeah, though they did specify basing the fallthrough on anif
.
â ilkkachu
May 29 at 9:10
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
Yes, He can ! :)
â Isaac
May 29 at 8:46
Yes, He can ! :)
â Isaac
May 29 at 8:46
@Isaac, well, yeah, though they did specify basing the fallthrough on an
if
.â ilkkachu
May 29 at 9:10
@Isaac, well, yeah, though they did specify basing the fallthrough on an
if
.â ilkkachu
May 29 at 9:10
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
+1 To be clear: I up voted your answer. :).
â Isaac
May 29 at 9:16
add a comment |Â
up vote
7
down vote
I'd suggest restructuring your logic: put the "fallthrough" code into a function instead:
fallthrough() echo 'fallthrough worked!';
for input in foo bar; do
for var in 1 2; do
echo "$input $var"
case $input in
foo)
if (( var == 1 )); then
echo "falling through"
fallthrough
else
echo "not falling through"
fi
;;
*) fallthrough;;
esac
done
done
outputs
foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!
add a comment |Â
up vote
7
down vote
I'd suggest restructuring your logic: put the "fallthrough" code into a function instead:
fallthrough() echo 'fallthrough worked!';
for input in foo bar; do
for var in 1 2; do
echo "$input $var"
case $input in
foo)
if (( var == 1 )); then
echo "falling through"
fallthrough
else
echo "not falling through"
fi
;;
*) fallthrough;;
esac
done
done
outputs
foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!
add a comment |Â
up vote
7
down vote
up vote
7
down vote
I'd suggest restructuring your logic: put the "fallthrough" code into a function instead:
fallthrough() echo 'fallthrough worked!';
for input in foo bar; do
for var in 1 2; do
echo "$input $var"
case $input in
foo)
if (( var == 1 )); then
echo "falling through"
fallthrough
else
echo "not falling through"
fi
;;
*) fallthrough;;
esac
done
done
outputs
foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!
I'd suggest restructuring your logic: put the "fallthrough" code into a function instead:
fallthrough() echo 'fallthrough worked!';
for input in foo bar; do
for var in 1 2; do
echo "$input $var"
case $input in
foo)
if (( var == 1 )); then
echo "falling through"
fallthrough
else
echo "not falling through"
fi
;;
*) fallthrough;;
esac
done
done
outputs
foo 1
falling through
fallthrough worked!
foo 2
not falling through
bar 1
fallthrough worked!
bar 2
fallthrough worked!
answered May 28 at 19:56
glenn jackman
45.7k265100
45.7k265100
add a comment |Â
add a comment |Â
up vote
7
down vote
The following script turns your test "inside out" in the sense that we test $var
first and then perform the fallthrough (using ;&
in a case
) depending on $input
.
We do this because the question of whether or not to "perform the fallthrough" is really only dependent on $input
if $var
is 1
. If it's any other value, the question of whether to do the fallthrough does not even have to be asked.
#/bin/bash
input='foo'
var='1'
case $var in
1)
case $input in
foo)
echo 'perform fallthrough'
;&
*)
echo 'fallthough worked'
esac
;;
*)
echo 'what fallthrough?'
esac
Or, without case
:
if [ "$var" -eq 1 ]; then
if [ "$input" = 'foo' ]; then
echo 'perform fallthrough'
fi
echo 'fallthough worked'
else
echo 'what fallthrough?'
fi
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in*)
. Already have my +1.
â Sergiy Kolodyazhnyy
May 28 at 20:26
add a comment |Â
up vote
7
down vote
The following script turns your test "inside out" in the sense that we test $var
first and then perform the fallthrough (using ;&
in a case
) depending on $input
.
We do this because the question of whether or not to "perform the fallthrough" is really only dependent on $input
if $var
is 1
. If it's any other value, the question of whether to do the fallthrough does not even have to be asked.
#/bin/bash
input='foo'
var='1'
case $var in
1)
case $input in
foo)
echo 'perform fallthrough'
;&
*)
echo 'fallthough worked'
esac
;;
*)
echo 'what fallthrough?'
esac
Or, without case
:
if [ "$var" -eq 1 ]; then
if [ "$input" = 'foo' ]; then
echo 'perform fallthrough'
fi
echo 'fallthough worked'
else
echo 'what fallthrough?'
fi
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in*)
. Already have my +1.
â Sergiy Kolodyazhnyy
May 28 at 20:26
add a comment |Â
up vote
7
down vote
up vote
7
down vote
The following script turns your test "inside out" in the sense that we test $var
first and then perform the fallthrough (using ;&
in a case
) depending on $input
.
We do this because the question of whether or not to "perform the fallthrough" is really only dependent on $input
if $var
is 1
. If it's any other value, the question of whether to do the fallthrough does not even have to be asked.
#/bin/bash
input='foo'
var='1'
case $var in
1)
case $input in
foo)
echo 'perform fallthrough'
;&
*)
echo 'fallthough worked'
esac
;;
*)
echo 'what fallthrough?'
esac
Or, without case
:
if [ "$var" -eq 1 ]; then
if [ "$input" = 'foo' ]; then
echo 'perform fallthrough'
fi
echo 'fallthough worked'
else
echo 'what fallthrough?'
fi
The following script turns your test "inside out" in the sense that we test $var
first and then perform the fallthrough (using ;&
in a case
) depending on $input
.
We do this because the question of whether or not to "perform the fallthrough" is really only dependent on $input
if $var
is 1
. If it's any other value, the question of whether to do the fallthrough does not even have to be asked.
#/bin/bash
input='foo'
var='1'
case $var in
1)
case $input in
foo)
echo 'perform fallthrough'
;&
*)
echo 'fallthough worked'
esac
;;
*)
echo 'what fallthrough?'
esac
Or, without case
:
if [ "$var" -eq 1 ]; then
if [ "$input" = 'foo' ]; then
echo 'perform fallthrough'
fi
echo 'fallthough worked'
else
echo 'what fallthrough?'
fi
edited May 30 at 19:51
Barmar
6,6801122
6,6801122
answered May 28 at 20:18
Kusalananda
102k13199314
102k13199314
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in*)
. Already have my +1.
â Sergiy Kolodyazhnyy
May 28 at 20:26
add a comment |Â
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in*)
. Already have my +1.
â Sergiy Kolodyazhnyy
May 28 at 20:26
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in
*)
. Already have my +1.â Sergiy Kolodyazhnyy
May 28 at 20:26
I think you nailed what OP actually wanted, which seems to be jumping from their original if statement to whatever in
*)
. Already have my +1.â Sergiy Kolodyazhnyy
May 28 at 20:26
add a comment |Â
up vote
5
down vote
Not something that I would do, but you could achieve something approaching with:
shopt -s extglob # for !(*)
default='*'
case $input in
(foo)
if [ "$VAR" = 1 ]; then
echo going for fallthrough
else
echo disabling fallthrough
default='!(*)'
fi ;;&
($default)
echo fallthrough
esac
add a comment |Â
up vote
5
down vote
Not something that I would do, but you could achieve something approaching with:
shopt -s extglob # for !(*)
default='*'
case $input in
(foo)
if [ "$VAR" = 1 ]; then
echo going for fallthrough
else
echo disabling fallthrough
default='!(*)'
fi ;;&
($default)
echo fallthrough
esac
add a comment |Â
up vote
5
down vote
up vote
5
down vote
Not something that I would do, but you could achieve something approaching with:
shopt -s extglob # for !(*)
default='*'
case $input in
(foo)
if [ "$VAR" = 1 ]; then
echo going for fallthrough
else
echo disabling fallthrough
default='!(*)'
fi ;;&
($default)
echo fallthrough
esac
Not something that I would do, but you could achieve something approaching with:
shopt -s extglob # for !(*)
default='*'
case $input in
(foo)
if [ "$VAR" = 1 ]; then
echo going for fallthrough
else
echo disabling fallthrough
default='!(*)'
fi ;;&
($default)
echo fallthrough
esac
answered May 28 at 21:41
Stéphane Chazelas
279k53513844
279k53513844
add a comment |Â
add a comment |Â
up vote
2
down vote
Test both variables at once (bash 4.0-alpha+):
#!/bin/bash
while (($#>1)); do
input=$1 VAR=$2
echo "input=$input VAR=$VAR"; shift 2
if [ "$VAR" = 1 ]; then new=1; else new=0; fi
case $input$new in
foo0) echo "do not perform fallthrough" ;;
foo*) echo "perform fallthrough" ;&
*) echo "fallthrough worked!" ;;
esac
echo
done
On testing:
$ ./script foo 0 foo 1 bar baz
input=foo VAR=0
do not perform fallthrough
input=foo VAR=1
perform fallthrough
fallthrough worked!
input=bar VAR=baz
fallthrough worked!
Clean and simple.
Understand that the tested value ($new
) must have only two possible values, that is why the if clause is there, to transform VAR to a Boolean value. If VAR may be made to be a Boolean, then test for 0
(not 1
) in the case
and remove the if
.
add a comment |Â
up vote
2
down vote
Test both variables at once (bash 4.0-alpha+):
#!/bin/bash
while (($#>1)); do
input=$1 VAR=$2
echo "input=$input VAR=$VAR"; shift 2
if [ "$VAR" = 1 ]; then new=1; else new=0; fi
case $input$new in
foo0) echo "do not perform fallthrough" ;;
foo*) echo "perform fallthrough" ;&
*) echo "fallthrough worked!" ;;
esac
echo
done
On testing:
$ ./script foo 0 foo 1 bar baz
input=foo VAR=0
do not perform fallthrough
input=foo VAR=1
perform fallthrough
fallthrough worked!
input=bar VAR=baz
fallthrough worked!
Clean and simple.
Understand that the tested value ($new
) must have only two possible values, that is why the if clause is there, to transform VAR to a Boolean value. If VAR may be made to be a Boolean, then test for 0
(not 1
) in the case
and remove the if
.
add a comment |Â
up vote
2
down vote
up vote
2
down vote
Test both variables at once (bash 4.0-alpha+):
#!/bin/bash
while (($#>1)); do
input=$1 VAR=$2
echo "input=$input VAR=$VAR"; shift 2
if [ "$VAR" = 1 ]; then new=1; else new=0; fi
case $input$new in
foo0) echo "do not perform fallthrough" ;;
foo*) echo "perform fallthrough" ;&
*) echo "fallthrough worked!" ;;
esac
echo
done
On testing:
$ ./script foo 0 foo 1 bar baz
input=foo VAR=0
do not perform fallthrough
input=foo VAR=1
perform fallthrough
fallthrough worked!
input=bar VAR=baz
fallthrough worked!
Clean and simple.
Understand that the tested value ($new
) must have only two possible values, that is why the if clause is there, to transform VAR to a Boolean value. If VAR may be made to be a Boolean, then test for 0
(not 1
) in the case
and remove the if
.
Test both variables at once (bash 4.0-alpha+):
#!/bin/bash
while (($#>1)); do
input=$1 VAR=$2
echo "input=$input VAR=$VAR"; shift 2
if [ "$VAR" = 1 ]; then new=1; else new=0; fi
case $input$new in
foo0) echo "do not perform fallthrough" ;;
foo*) echo "perform fallthrough" ;&
*) echo "fallthrough worked!" ;;
esac
echo
done
On testing:
$ ./script foo 0 foo 1 bar baz
input=foo VAR=0
do not perform fallthrough
input=foo VAR=1
perform fallthrough
fallthrough worked!
input=bar VAR=baz
fallthrough worked!
Clean and simple.
Understand that the tested value ($new
) must have only two possible values, that is why the if clause is there, to transform VAR to a Boolean value. If VAR may be made to be a Boolean, then test for 0
(not 1
) in the case
and remove the if
.
edited May 30 at 2:13
answered May 29 at 8:46
Isaac
6,3241633
6,3241633
add a comment |Â
add a comment |Â
up vote
1
down vote
You can make the fallthrough default but place a condition that the code only executes only if the condition is met
#!/bin/bash
input='foo'
var='1'
case $input in
foo)
echo "Do fall through"
;& #always fall through
*)
if [ $var = "1" ] #execute only if condition matches
then
echo "fallthrough took place"
fi
esac
But as ilkkachu suggested you can also use conditions rather than switch.
add a comment |Â
up vote
1
down vote
You can make the fallthrough default but place a condition that the code only executes only if the condition is met
#!/bin/bash
input='foo'
var='1'
case $input in
foo)
echo "Do fall through"
;& #always fall through
*)
if [ $var = "1" ] #execute only if condition matches
then
echo "fallthrough took place"
fi
esac
But as ilkkachu suggested you can also use conditions rather than switch.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
You can make the fallthrough default but place a condition that the code only executes only if the condition is met
#!/bin/bash
input='foo'
var='1'
case $input in
foo)
echo "Do fall through"
;& #always fall through
*)
if [ $var = "1" ] #execute only if condition matches
then
echo "fallthrough took place"
fi
esac
But as ilkkachu suggested you can also use conditions rather than switch.
You can make the fallthrough default but place a condition that the code only executes only if the condition is met
#!/bin/bash
input='foo'
var='1'
case $input in
foo)
echo "Do fall through"
;& #always fall through
*)
if [ $var = "1" ] #execute only if condition matches
then
echo "fallthrough took place"
fi
esac
But as ilkkachu suggested you can also use conditions rather than switch.
answered May 29 at 8:02
yashC
116
116
add a comment |Â
add a comment |Â
up vote
1
down vote
If you don't mind someone complaining about they don't understand your code, you could simply switch the order of the two conditionals:
input="foo"
VAR="1"
if
case $input in
foo)
[ $VAR = "1" ]
;;
esac
then
echo "fallthrough worked!"
fi
Or:
input="foo"
VAR="1"
case $input in
foo)
[ $VAR = "1" ]
;;
esac &&
echo "fallthrough worked!"
Simple and clear (at least to me). case
doesn't support fallthrough itself. But you can replace *)
with &&
after esac
to make it respect to the return values of other branches.
add a comment |Â
up vote
1
down vote
If you don't mind someone complaining about they don't understand your code, you could simply switch the order of the two conditionals:
input="foo"
VAR="1"
if
case $input in
foo)
[ $VAR = "1" ]
;;
esac
then
echo "fallthrough worked!"
fi
Or:
input="foo"
VAR="1"
case $input in
foo)
[ $VAR = "1" ]
;;
esac &&
echo "fallthrough worked!"
Simple and clear (at least to me). case
doesn't support fallthrough itself. But you can replace *)
with &&
after esac
to make it respect to the return values of other branches.
add a comment |Â
up vote
1
down vote
up vote
1
down vote
If you don't mind someone complaining about they don't understand your code, you could simply switch the order of the two conditionals:
input="foo"
VAR="1"
if
case $input in
foo)
[ $VAR = "1" ]
;;
esac
then
echo "fallthrough worked!"
fi
Or:
input="foo"
VAR="1"
case $input in
foo)
[ $VAR = "1" ]
;;
esac &&
echo "fallthrough worked!"
Simple and clear (at least to me). case
doesn't support fallthrough itself. But you can replace *)
with &&
after esac
to make it respect to the return values of other branches.
If you don't mind someone complaining about they don't understand your code, you could simply switch the order of the two conditionals:
input="foo"
VAR="1"
if
case $input in
foo)
[ $VAR = "1" ]
;;
esac
then
echo "fallthrough worked!"
fi
Or:
input="foo"
VAR="1"
case $input in
foo)
[ $VAR = "1" ]
;;
esac &&
echo "fallthrough worked!"
Simple and clear (at least to me). case
doesn't support fallthrough itself. But you can replace *)
with &&
after esac
to make it respect to the return values of other branches.
answered May 29 at 12:38
user23013
457210
457210
add a comment |Â
add a comment |Â
up vote
-4
down vote
New ;&
and ;;&
operators were introduced in Bash
4.0
and although they both might be useful in similar situations I think
they are of no use in your case. This is what man bash
says about
these operators:
If the ;; operator is used, no subsequent matches are attempted after
the first pattern match. Using ;& in place of ;; causes execution to
continue with the list associated with the next set of patterns. Using
;;& in place of ;; causes the shell to test the next pattern list in
the statement, if any, and execute any associated list on a successful
match.
In other words, ;&
is a fall through and as we know it from C
and;;&
makes bash
check remaining cases instead of returning fromcase
block entirely. You can find a nice example of ;;&
in action
here: https://stackoverflow.com/a/24544780/3691891.
That being said, neither ;&
nor ;;&
could be used in your script
because both of them would go to *)
that would be always run.
The following script works and does what you want without re-arranging
the logic but consider it only as an example and never rely on it, it's too fragile.
I've taken the idea from
here:
#!/usr/bin/env bash
function jumpto
grep -v ':$')
cmd=$(echo "$cmd"
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
printf "perform fallthroughn"
jumpto ft
else
printf "do not perform fallthroughn"
fi
;;
*)
ft:
echo "fallthrough worked!"
;;
esac
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
1
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from thejumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block betweenft:
and;;
is a coincidence becausejumpto
is the last command in the same complex command as the jumped-to block.
â Gilles
May 28 at 20:59
1
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
add a comment |Â
up vote
-4
down vote
New ;&
and ;;&
operators were introduced in Bash
4.0
and although they both might be useful in similar situations I think
they are of no use in your case. This is what man bash
says about
these operators:
If the ;; operator is used, no subsequent matches are attempted after
the first pattern match. Using ;& in place of ;; causes execution to
continue with the list associated with the next set of patterns. Using
;;& in place of ;; causes the shell to test the next pattern list in
the statement, if any, and execute any associated list on a successful
match.
In other words, ;&
is a fall through and as we know it from C
and;;&
makes bash
check remaining cases instead of returning fromcase
block entirely. You can find a nice example of ;;&
in action
here: https://stackoverflow.com/a/24544780/3691891.
That being said, neither ;&
nor ;;&
could be used in your script
because both of them would go to *)
that would be always run.
The following script works and does what you want without re-arranging
the logic but consider it only as an example and never rely on it, it's too fragile.
I've taken the idea from
here:
#!/usr/bin/env bash
function jumpto
grep -v ':$')
cmd=$(echo "$cmd"
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
printf "perform fallthroughn"
jumpto ft
else
printf "do not perform fallthroughn"
fi
;;
*)
ft:
echo "fallthrough worked!"
;;
esac
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
1
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from thejumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block betweenft:
and;;
is a coincidence becausejumpto
is the last command in the same complex command as the jumped-to block.
â Gilles
May 28 at 20:59
1
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
add a comment |Â
up vote
-4
down vote
up vote
-4
down vote
New ;&
and ;;&
operators were introduced in Bash
4.0
and although they both might be useful in similar situations I think
they are of no use in your case. This is what man bash
says about
these operators:
If the ;; operator is used, no subsequent matches are attempted after
the first pattern match. Using ;& in place of ;; causes execution to
continue with the list associated with the next set of patterns. Using
;;& in place of ;; causes the shell to test the next pattern list in
the statement, if any, and execute any associated list on a successful
match.
In other words, ;&
is a fall through and as we know it from C
and;;&
makes bash
check remaining cases instead of returning fromcase
block entirely. You can find a nice example of ;;&
in action
here: https://stackoverflow.com/a/24544780/3691891.
That being said, neither ;&
nor ;;&
could be used in your script
because both of them would go to *)
that would be always run.
The following script works and does what you want without re-arranging
the logic but consider it only as an example and never rely on it, it's too fragile.
I've taken the idea from
here:
#!/usr/bin/env bash
function jumpto
grep -v ':$')
cmd=$(echo "$cmd"
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
printf "perform fallthroughn"
jumpto ft
else
printf "do not perform fallthroughn"
fi
;;
*)
ft:
echo "fallthrough worked!"
;;
esac
New ;&
and ;;&
operators were introduced in Bash
4.0
and although they both might be useful in similar situations I think
they are of no use in your case. This is what man bash
says about
these operators:
If the ;; operator is used, no subsequent matches are attempted after
the first pattern match. Using ;& in place of ;; causes execution to
continue with the list associated with the next set of patterns. Using
;;& in place of ;; causes the shell to test the next pattern list in
the statement, if any, and execute any associated list on a successful
match.
In other words, ;&
is a fall through and as we know it from C
and;;&
makes bash
check remaining cases instead of returning fromcase
block entirely. You can find a nice example of ;;&
in action
here: https://stackoverflow.com/a/24544780/3691891.
That being said, neither ;&
nor ;;&
could be used in your script
because both of them would go to *)
that would be always run.
The following script works and does what you want without re-arranging
the logic but consider it only as an example and never rely on it, it's too fragile.
I've taken the idea from
here:
#!/usr/bin/env bash
function jumpto
grep -v ':$')
cmd=$(echo "$cmd"
input="foo"
VAR="1"
case $input in
foo)
if [ $VAR = "1" ]; then
printf "perform fallthroughn"
jumpto ft
else
printf "do not perform fallthroughn"
fi
;;
*)
ft:
echo "fallthrough worked!"
;;
esac
answered May 28 at 20:05
Arkadiusz Drabczyk
7,15521532
7,15521532
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
1
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from thejumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block betweenft:
and;;
is a coincidence becausejumpto
is the last command in the same complex command as the jumped-to block.
â Gilles
May 28 at 20:59
1
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
add a comment |Â
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
1
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from thejumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block betweenft:
and;;
is a coincidence becausejumpto
is the last command in the same complex command as the jumped-to block.
â Gilles
May 28 at 20:59
1
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
Why a downvote?
â Arkadiusz Drabczyk
May 28 at 20:15
1
1
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from the
jumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block between ft:
and ;;
is a coincidence because jumpto
is the last command in the same complex command as the jumped-to block.â Gilles
May 28 at 20:59
This may work in a toy example but it's near-incomprehensible and wouldn't work in a larger script. The way you simulate goto is extremely fragile, and to say that it really simulates goto is an exaggeration. The code returns from the
jumpto
function and executes whatever comes after it. The fact that this is equivalent to continuing executing after the block between ft:
and ;;
is a coincidence because jumpto
is the last command in the same complex command as the jumped-to block.â Gilles
May 28 at 20:59
1
1
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
OK, I clearly emphasized that in my answer.
â Arkadiusz Drabczyk
May 28 at 21:01
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2funix.stackexchange.com%2fquestions%2f446537%2fcase-fallthrough-based-on-if-condition%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
Small question: Are you trying to jump from
if [ $VAR -eq 1 ]; then
part of the code to whatever is in*)
? Because that's entirely different from what fallthrough is called, thus making your question phrasing just slightly misleading.â Sergiy Kolodyazhnyy
May 28 at 20:24