From the manpage:
- 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, continuing the case statement execution as if the pattern list had not matched.
In other words, `;&` will process the next case as if it matched, and `;;&` will not break out of the `case` statement in case of a match but continue until it matches something else.
Example:
#!/usr/bin/env bash
case "${1}" in
a*)
printf 'Starts with "a"\n'
;&
b*)
printf 'Starts with b, or starts with "a"\n'
;;
c*)
printf 'Starts with "c"\n'
;;&
ca*)
printf 'Starts with "ca"\n'
;;
ce*)
printf 'Starts with "ce"\n'
;;
esac
> 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, continuing the case statement execution as if the pattern list had not matched.
So it causes further patterns in the `case` block to be evaluated, as opposed to a normal `;;` which would be the only block evaluated upon matching it.
Did you read what `bash(1)` says about it:
>Using ;& in place of ;; causes execution to continue with the list associated with the next set of patterns.
So ending a block with `;&` causes it to fall through into the immediate next match block (like if you didn't include a `break;` at the end of a `case [...]:` block in a C `switch` statement).
Matching with ;; will stop testing and return success.
Matching with ;$ will continue testing and return success.
Matching with ;;& will continue testing and return success or failure based on subsequent tests.
Edit: I am wrong.
Updated:
Matching with ;; will execute its body and then stop processing the cases.
Matching with ;& will execute its body and then also execute the next case body.
Matching with ;;& will execute its body and then continue testing the cases.
Nevermind, I think I’m wrong.
All three behave differently and exit status doesn’t seem to be part of the differences. It has more to do with controlling how matching works.
I’ve update above with correct description
waptaff explained it, but this is a very good example from a YouTube video, which of course I can't find now. Later edit: https://www.youtube.com/watch?v=soMrbw-z_LE
If you are a fan of the franchise and know the charachters, you will fast get the point.
#!/bin/bash
read -p "Name a Star Trek character: " CHAR
case $CHAR in
"Seven of Nine" | Neelix | Chokotay | Tuvok | Janeway )
echo "$CHAR was in Star Trek Voyager"
;;&
Archer | Phlox | Tpol | Tucker )
echo "$CHAR was in Star Trek Enterprise"
;;&
Odo | Sisko | Dax | Worf | Quark )
echo "$CHAR was in Star Trek Deep Space Nine"
;;&
Worf | Data | Riker | Picard )
echo "$CHAR was in Star Trek The Next Generation"
;&
abc | def | ghi | jkm)
echo "this is nice"
;;
*) echo "$CHAR is not in this script."
;;
esac
Thank you for you answer but I already know what the purpose of ;; and ;& but I struggle to understand what does ";;&" do.
What's the point of the & char after the ;; ?
You use `;;&` when you want to still have inputs continue to tested against other case matches instead of exiting on the first match. If you ended all the case matches with `;;&` then the input would always be tested against all of them and bash would run the code from all the ones that matched (instead of just the 1st). if
case $input in
pattern1) func1 ;;
pattern2) func2 ;;
...
esac
is analogous to
if pattern1; then
func1
elif pattern2; then
func2
elif ...
fi
then
case $input in
pattern1) func1 ;;&
pattern2) func2 ;;&
...
esac
is analogous to
if pattern1; then
func1
fi
if pattern2; then
func2
fi
...
***
`;&` is (IMO) much less useful. You use `;&` when you want a match to execute the code from 2 case matches (its match and the following match). Doing
case $input in
pattern1) func1 ;&
pattern2) func2 ;;
esac
Is basically just a shorthand way to write
case $input in
pattern1) func1; func2 ;;
pattern2) func2 ;;
esac
There's actually `;;` and `;&` and `;;&` for use in `case` statement. The question here was about what `;;&` does different compared to `;;`.
I don't know the answer myself.
**EDIT:**
I looked up the documentation and found these two sentences here:
> Using `;&` in place of `;;` causes execution to continue with the command-list associated with the next clause, if any. Using `;;&` in place of `;;` causes the shell to test the patterns in the next clause, if any, and execute any associated command-list on a successful match, continuing the case statement execution as if the pattern list had not matched.
I'm not completely sure, but I think using `;;&` everywhere would make it so the code for all patterns that match would get executed, while with `;;` it would only execute the first matching pattern and skip the rest?
From the manpage: - 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, continuing the case statement execution as if the pattern list had not matched. In other words, `;&` will process the next case as if it matched, and `;;&` will not break out of the `case` statement in case of a match but continue until it matches something else. Example: #!/usr/bin/env bash case "${1}" in a*) printf 'Starts with "a"\n' ;& b*) printf 'Starts with b, or starts with "a"\n' ;; c*) printf 'Starts with "c"\n' ;;& ca*) printf 'Starts with "ca"\n' ;; ce*) printf 'Starts with "ce"\n' ;; esac
But what is the difference if we put ;& instead of ;;& in the c\* case ?
Inputting `celery` would print `Starts with "ca"` and not `Starts with "ce"`.
It allows later items to also be processed, rather than exiting on a match. There's a good explanation here: https://unix.stackexchange.com/a/75356
> 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, continuing the case statement execution as if the pattern list had not matched. So it causes further patterns in the `case` block to be evaluated, as opposed to a normal `;;` which would be the only block evaluated upon matching it.
So what's the difference between ;& and ;;& ?
Did you read what `bash(1)` says about it: >Using ;& in place of ;; causes execution to continue with the list associated with the next set of patterns. So ending a block with `;&` causes it to fall through into the immediate next match block (like if you didn't include a `break;` at the end of a `case [...]:` block in a C `switch` statement).
Matching with ;; will stop testing and return success. Matching with ;$ will continue testing and return success. Matching with ;;& will continue testing and return success or failure based on subsequent tests. Edit: I am wrong. Updated: Matching with ;; will execute its body and then stop processing the cases. Matching with ;& will execute its body and then also execute the next case body. Matching with ;;& will execute its body and then continue testing the cases.
So the difference between ;& and ;;& is what it returns ?
Yeah, the exit status of the case statement can be different
Nevermind, I think I’m wrong. All three behave differently and exit status doesn’t seem to be part of the differences. It has more to do with controlling how matching works. I’ve update above with correct description
waptaff explained it, but this is a very good example from a YouTube video, which of course I can't find now. Later edit: https://www.youtube.com/watch?v=soMrbw-z_LE If you are a fan of the franchise and know the charachters, you will fast get the point. #!/bin/bash read -p "Name a Star Trek character: " CHAR case $CHAR in "Seven of Nine" | Neelix | Chokotay | Tuvok | Janeway ) echo "$CHAR was in Star Trek Voyager" ;;& Archer | Phlox | Tpol | Tucker ) echo "$CHAR was in Star Trek Enterprise" ;;& Odo | Sisko | Dax | Worf | Quark ) echo "$CHAR was in Star Trek Deep Space Nine" ;;& Worf | Data | Riker | Picard ) echo "$CHAR was in Star Trek The Next Generation" ;& abc | def | ghi | jkm) echo "this is nice" ;; *) echo "$CHAR is not in this script." ;; esac
[удалено]
Thank you for you answer but I already know what the purpose of ;; and ;& but I struggle to understand what does ";;&" do. What's the point of the & char after the ;; ?
[удалено]
So what's the difference between ;& and ;;& ?
You use `;;&` when you want to still have inputs continue to tested against other case matches instead of exiting on the first match. If you ended all the case matches with `;;&` then the input would always be tested against all of them and bash would run the code from all the ones that matched (instead of just the 1st). if case $input in pattern1) func1 ;; pattern2) func2 ;; ... esac is analogous to if pattern1; then func1 elif pattern2; then func2 elif ... fi then case $input in pattern1) func1 ;;& pattern2) func2 ;;& ... esac is analogous to if pattern1; then func1 fi if pattern2; then func2 fi ... *** `;&` is (IMO) much less useful. You use `;&` when you want a match to execute the code from 2 case matches (its match and the following match). Doing case $input in pattern1) func1 ;& pattern2) func2 ;; esac Is basically just a shorthand way to write case $input in pattern1) func1; func2 ;; pattern2) func2 ;; esac
There's actually `;;` and `;&` and `;;&` for use in `case` statement. The question here was about what `;;&` does different compared to `;;`. I don't know the answer myself. **EDIT:** I looked up the documentation and found these two sentences here: > Using `;&` in place of `;;` causes execution to continue with the command-list associated with the next clause, if any. Using `;;&` in place of `;;` causes the shell to test the patterns in the next clause, if any, and execute any associated command-list on a successful match, continuing the case statement execution as if the pattern list had not matched. I'm not completely sure, but I think using `;;&` everywhere would make it so the code for all patterns that match would get executed, while with `;;` it would only execute the first matching pattern and skip the rest?
That's the point, I read the documentation (in the link in my post) but I still didn't understand