Unix & Linux Stack Exchange
Q&A for users of Linux, FreeBSD and other Unix-like operating systems
Latest Questions
2
votes
2
answers
2630
views
Passing options/args/parameters with spaces from the script to a function within
I've got a script that I am passing arguments/options/parameters to at the command line. One of the values has a space in it, which I have put in double quotes. It might be easier to provide an example. Forgive my usage of arguments/options/parameters. $: ./test1.ksh -n -b -d "Home Videos" My proble...
I've got a script that I am passing arguments/options/parameters to at the command line. One of the values has a space in it, which I have put in double quotes. It might be easier to provide an example. Forgive my usage of arguments/options/parameters.
$: ./test1.ksh -n -b -d "Home Videos"
My problem is setting a variable to "Home Videos" and it being used together. In my example, the -d is to specify a directory. Not all the directories have spaces, but some do in my case.
This is an example of the code I have that is not working as expected:
#!/bin/ksh
Function1()
{
echo "Number of Args in Function1: $#"
echo "Function1 Args: $@"
SetArgs $*
}
SetArgs()
{
echo -e "\nNumber of Args in SetArgs: $#"
echo "SetArgs Args: $@"
while [ $# -gt 0 ]
do
case $1 in
-[dD])
shift
export DirectoryName=$1
;;
-[nN])
export Var1=No
shift
;;
-[bB])
export Var2=Backup
shift
;;
*)
shift
;;
esac
done
Function2
}
Function2()
{
echo "Directory Name: ${DirectoryName}"
}
Function1 $*
When I run this, I'm getting only Home for the DirectoryName instead of Home Videos. Seen below.
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 5
Function1 Args: -n -b -d Home Videos
Number of Args in SetArgs: 5
SetArgs Args: -n -b -d Home Videos
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home
What I am expecting and I have not been able to get it to happen is:
$ ./test1.ksh -n -b -d "Home Videos"
Number of Args in Function1: 4
Function1 Args: -n -b -d "Home Videos"
Number of Args in SetArgs: 4
SetArgs Args: -n -b -d "Home Videos"
Var1 is set to: No
Var2 is set to: Backup
Directory Name: Home Videos <-- Without double quotes in the final usage.
I've tried escaping the double quotes, without any success.
DNadler
(23 rep)
Nov 21, 2017, 11:05 AM
• Last activity: Dec 31, 2024, 10:23 AM
4
votes
4
answers
24219
views
Matching numbers with regex in case statement
I want to check whether an argument to a shell script is a whole number (i.e., a non-negative integer: 0, 1, 2, 3, …, 17, …, 42, …, etc, but not 3.1416 or −5) expressed in decimal (so nothing like 0x11 or 0x2A).  How can I write a case statement using regex as condition (to...
I want to check whether an argument to a shell script is a whole number
(i.e., a non-negative integer: 0, 1, 2, 3, …, 17, …, 42, …, etc,
but not 3.1416 or −5) expressed in decimal (so nothing like 0x11 or 0x2A).
How can I write a case statement using regex as condition (to match numbers)? I tried a few different ways I came up with (e.g.,
[0-9]+
or ^[0-9][0-9]*$
); none of them works. Like in the following example, valid numbers are falling through the numeric regex that's intended to catch them and are matching the *
wildcard.
i=1
let arg_n=$#+1
while (( $i < $arg_n )); do
case ${!i} in
[0-9]+)
n=${!i}
;;
*)
echo 'Invalid argument!'
;;
esac
let i=$i+1
done
Output:
$ ./cmd.sh 64
Invalid argument!
siery
(221 rep)
Mar 21, 2018, 07:21 PM
• Last activity: Jun 22, 2024, 02:54 AM
-1
votes
1
answers
113
views
How to specify several alternative conditions (OR operator) for single case statement? (Or Alternatively, where is shell case syntax description?)
I want something like this: ```shell time="1m" case "$time" in *h*) *m*) *s*) echo "handling several cases for h, m, s tokens" ;; *) echo "handling other cases" ;; esac ``` How to achieve this for POSIX shell?
I want something like this:
time="1m"
case "$time" in
*h*)
*m*)
*s*)
echo "handling several cases for h, m, s tokens" ;;
*)
echo "handling other cases" ;;
esac
How to achieve this for POSIX shell?
Anton Samokat
(289 rep)
May 10, 2024, 02:08 PM
• Last activity: Jun 9, 2024, 06:35 AM
-1
votes
1
answers
138
views
Nested 'case' statements where the user can return to the outer one from the inner one
I am trying to put a `case` statement inside another `case` statement, but I want the user to be able to return to the first `case` statement if they want. The idea is something like this: ```lang-bash read choice case $choice in 1) read pattern case $pattern in pattern1) Statement() ;; pattern2) St...
I am trying to put a
case
statement inside another case
statement, but I want the user to be able to return to the first case
statement if they want.
The idea is something like this:
-bash
read choice
case $choice in
1)
read pattern
case $pattern in
pattern1)
Statement()
;;
pattern2)
Statement(return to the first case)
;;
*)
echo "Error"
;;
esac
;;
2)
echo "test"
;;
3)
break
;;
*)
echo "error"
;;
esac
zellez11
(147 rep)
Jan 6, 2020, 01:41 AM
• Last activity: May 14, 2024, 01:48 PM
7
votes
3
answers
4575
views
How to specify AND / OR operators (conditions) for case statement?
I have the following code. ```lang-shell read -p "Enter a word: " word case $word in [aeiou]* | [AEIOU]*) echo "The word begins with a vowel." ;; [0-9]*) echo "The word begins with a digit." ;; *[0-9]) echo "The word ends with a digit." ;; [aeiou]* && [AEIOU]* && *[0-9]) echo "The word begins with v...
I have the following code.
-shell
read -p "Enter a word: " word
case $word in
[aeiou]* | [AEIOU]*)
echo "The word begins with a vowel." ;;
[0-9]*)
echo "The word begins with a digit." ;;
*[0-9])
echo "The word ends with a digit." ;;
[aeiou]* && [AEIOU]* && *[0-9])
echo "The word begins with vowel and ends with a digit." ;;
????)
echo "You entered a four letter word." ;;
*)
echo "I don't know what you've entered," ;;
esac
When I run this:
Enter a word: apple123
case2.sh: line 10: syntax error near unexpected token `&&'
case2.sh: line 10: ` [aeiou]* && [AEIOU]* && *[0-9])'
It looks like case
statement doesn't support AND
operator, and also I believe the &&
operator in my above case
statement logically incorrect.
I understand that we can use if
...else
to check if the input starts with a vowel and digit. But I am curious if case has any builtin function like AND operator.
smc
(621 rep)
Oct 28, 2019, 05:40 PM
• Last activity: May 13, 2024, 04:19 PM
13
votes
9
answers
4504
views
Case fallthrough based on if condition
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 co...
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.
Smashgen
(403 rep)
May 28, 2018, 07:07 PM
• Last activity: Apr 10, 2024, 09:00 PM
2
votes
1
answers
312
views
How is the correct syntax for a more complex case statement?
``` case "$1","$name" in -py | --python | --python3,*) if [[ "$name" =~ \..+$ ]]; then ``` That doesn't catch stuff, which actually it should, like… ``` USERNAME@HOSTNAME:~$ myscript --python surfer ``` Funny thing: Simplify the multi pattern conditional to… ``` --python,*) if [[ "$name" =~ \..+$ ]]...
case "$1","$name" in
-py | --python | --python3,*) if [[ "$name" =~ \..+$ ]]; then
That doesn't catch stuff, which actually it should,
like…
USERNAME@HOSTNAME:~$ myscript --python surfer
Funny thing:
Simplify the multi pattern conditional to…
--python,*) if [[ "$name" =~ \..+$ ]]; then
and it works!
With the bitterly-repetitive outlook to have to place that section 3 times: 1st for -py
, then for --python
, and finally for --python3
for catching all patterns.
But the other thing is - the other way around:
case "$1" in
-py | --python | --python3) if [[ ! "$name" =~ \.py$ ]]; then
That's fine, that works!
So, that disproves my assumption, that the multi pattern syntax might be incorrect,
might needs the spaces to be removed, or any kind of bracket around the sum of all 3 patterns to be interpreted as a group, where the first OR the second OR the third pattern is supposed to be catched.
And with all this I really have the impression, that you can't have both in
GNU bash, version 4.3, multi pattern AND aside of that conditional a second conditional like "$name". Could that be? Or have I made a mistake in trying to acchieve that?
futurewave
(213 rep)
Apr 4, 2024, 10:13 PM
• Last activity: Apr 4, 2024, 11:11 PM
5
votes
2
answers
2081
views
Case ... in, file type cases
I was given homework where I need to test if `$1` is a file, special file or a folder in a **Case `$1` In statement**. I tried some things but wasn't able to make it work. Do you have any idea on how to implement this (in a case statement) What I need to achieve is : if [ -f $1 ] then exit 1 elif [...
I was given homework where I need to test if
$1
is a file, special file or a folder in a **Case $1
In statement**.
I tried some things but wasn't able to make it work. Do you have any idea on how to implement this (in a case statement)
What I need to achieve is :
if [ -f $1 ]
then
exit 1
elif [ -d $1 ]
then
exit 2
elif [ -c $1 -o -b $1 ]
then
exit 3
else
exit 0
fi
I'm not asking for the final code, just a way to make the following work:
Case $1 in
-d) ...
JeanneD4RK
(161 rep)
Dec 10, 2015, 07:06 PM
• Last activity: Feb 18, 2024, 07:47 PM
2
votes
2
answers
623
views
For loop through a variable vector
I have a for loop and case statements. The for loop has quite a bit element list and the case statement will assign an 1D array or a vector. These values will be used in for loop after. I have the following code. What happens is that the for loop does the job only for the first value in the vector....
I have a for loop and case statements. The for loop has quite a bit element list and the case statement will assign an 1D array or a vector. These values will be used in for loop after. I have the following code.
What happens is that the for loop does the job only for the first value in the vector. For example, if the f=C, the case is "C") isotope=(6012 6013);;
for n in $isotope: It loops only for 6012 not for 6013. Same issue with f=Ce, it only does the loop for 58136 not for the rest.
# loop through elements
for f in C Ce
do
cd ${f}
case $f in
"Al") isotope=(13027) ;;
"C") isotope=(6012 6013);;
"Ce") isotope=(58136 58138 58140 58142);;
esac
for n in $isotope
do
....# loop through elements
for f in C Ce
do
cd ${f}
case $f in
"Al") isotope=(13027) ;;
"C") isotope=(6012 6013);;
"Ce") isotope=(58136 58138 58140 58142);;
esac
for n in $isotope
do
....
Thank you for the help
Birsen
BircanA
(21 rep)
May 2, 2023, 05:59 PM
• Last activity: May 3, 2023, 03:24 PM
0
votes
0
answers
30
views
Case Statement Not Working as Expected
I am attempting to write a bash script that takes input from the keyboard and displays text depending on what number was entered: ```bash #!/bin/bash read -p "Enter your age: " AGE case $AGE in [1-12]*) echo "You are just a child." ;; [13-19]*) echo "You are just a teenager." ;; [20-29]*) echo "You...
I am attempting to write a bash script that takes input from the keyboard and displays text depending on what number was entered:
#!/bin/bash
read -p "Enter your age: " AGE
case $AGE in
[1-12]*)
echo "You are just a child." ;;
[13-19]*)
echo "You are just a teenager." ;;
[20-29]*)
echo "You are a young adult." ;;
[30-39]*)
echo "You are a moderate age adult." ;;
*)
echo "You are really old."
esac
When you enter numbers like 3 or 4, it doesn't fall in the first range. It falls withing the 30-39 and the default.
Where am I messing up?
Randy Haley
(1 rep)
Feb 22, 2023, 03:23 PM
• Last activity: Feb 22, 2023, 03:36 PM
-2
votes
1
answers
365
views
Was `esac` intentionally `case` just in reverse?
I just realized that in shell scripting `esac`, the closing statement for `case` is just `case` reversed. This may be a stupid question but does `esac` actually mean something (ie an abbreviation) or was it chosen solely due to it being the literal opposite of `case`?
I just realized that in shell scripting
esac
, the closing statement for case
is just case
reversed. This may be a stupid question but does esac
actually mean something (ie an abbreviation) or was it chosen solely due to it being the literal opposite of case
?
Kaiden Prince
(101 rep)
Jan 19, 2023, 02:50 AM
• Last activity: Jan 19, 2023, 03:31 AM
0
votes
1
answers
342
views
bash script - printing a value of an array based on the value of another array
I have two arrays and want to print a value from ARRAY2 depending on the applicable value in ARRAY1. ``` #!/usr/bin/env bash ARRAY1=(bb.service.sql bw.service.sql) ARRAY2=(bb bw) case $ARRAY1[@] in ${ARRAY1[1]}) echo ${ARRAY2[1]} ;; *) echo "unknown" ;; esac ``` I m getting `unknown` here though. Wh...
I have two arrays and want to print a value from ARRAY2 depending on the applicable value in ARRAY1.
#!/usr/bin/env bash
ARRAY1=(bb.service.sql bw.service.sql)
ARRAY2=(bb bw)
case $ARRAY1[@] in
${ARRAY1})
echo ${ARRAY2} ;;
*)
echo "unknown" ;;
esac
I m getting unknown
here though. What am I doing wrong?
vrms
(287 rep)
Jan 18, 2023, 12:19 PM
• Last activity: Jan 18, 2023, 03:06 PM
2
votes
3
answers
5833
views
Case statement allow only alphabetic characters?
case "$1" in all) echo "$1" ;; [a-z][a-z][a-z][a-z][a-z][a-z]) echo "$1" ;; *) printf 'Invalid: %s\n' "$3" exit 1 ;; esac With this the only input accepted is all, and 6 characters. It won't accept 4 characters or more than 6. What I want to do here is to only allow characters, not digits or symbols...
case "$1" in
all)
echo "$1"
;;
[a-z][a-z][a-z][a-z][a-z][a-z])
echo "$1"
;;
*)
printf 'Invalid: %s\n' "$3"
exit 1
;;
esac
With this the only input accepted is all, and 6 characters. It won't accept 4 characters or more than 6.
What I want to do here is to only allow characters, not digits or symbols, but of unlimited length.
What is the correct syntax? Thanks
Freedo
(1384 rep)
Jan 19, 2018, 02:31 PM
• Last activity: Jan 8, 2023, 09:55 AM
5
votes
4
answers
15922
views
Using case and arrays together in bash
Is it possible to check if a variable is contained inside an array using `case`? I would like to do something like ARR=( opt1 opt2 opt3 ); case $1 in $ARR) echo "Option is contained in the array"; *) echo "Option is not contained in the array"; esac
Is it possible to check if a variable is contained inside an array using
case
? I would like to do something like
ARR=( opt1 opt2 opt3 );
case $1 in
$ARR)
echo "Option is contained in the array";
*)
echo "Option is not contained in the array";
esac
red_trumpet
(345 rep)
Dec 15, 2017, 08:46 AM
• Last activity: Dec 8, 2022, 03:41 PM
1
votes
1
answers
105
views
Bash - How to make dynamic menu selection without eval
I'm making a script for Docker environments, and I'm a bit stuck with a pigeonhole I've gotten myself into. #!/bin/bash set -euo pipefail # Variables gituser="modem7" gitrepo="docker-devenv" gitfolder="Environments" buildername="DockerDevBuilder" # Colours RED="\e[31m" GREEN="\e[32m" END="\e[0m" ech...
I'm making a script for Docker environments, and I'm a bit stuck with a pigeonhole I've gotten myself into.
#!/bin/bash
set -euo pipefail
# Variables
gituser="modem7"
gitrepo="docker-devenv"
gitfolder="Environments"
buildername="DockerDevBuilder"
# Colours
RED="\e[31m"
GREEN="\e[32m"
END="\e[0m"
echo "========================================="
printf " Checking Dependencies\n"
echo "========================================="
printf "Checking if dependencies are installed...\n"
pkg_list=(docker jq)
tc() { set ${*,,} ; echo ${*^} ; }
for pkg in "${pkg_list[@]}"
do
titlecase=$(tc $pkg)
isinstalled=$(dpkg-query -l $pkg > /dev/null 2>&1)
if [ $? -eq 0 ];
then
printf "~ $titlecase is...${GREEN}installed${END}\n"
else
printf "~ $titlecase is...${RED}not installed${END}\n"
printf "Exiting Script. Install $pkg.\n"
echo "========================================="
exit
fi
done
echo "========================================="
cat /dev/null 2>&1; then
echo ""
echo "Builder $buildername created"
else
echo "Builder already created, using $buildername"
docker buildx use "DockerDevBuilder"
echo ""
fi
echo "Creating $dev_name Environment..."
docker buildx build --rm=true --build-arg BUILDKIT_INLINE_CACHE=1 --load -t $lowerdev:dev https://github.com/$gituser/$gitrepo.git#:$gitfolder/$dev_name \
&& clear \
&& echo "=========================================" \
&& echo "Activating $dev_name Dev Environment..." \
&& echo "Press CTRL + D or type exit to leave the container" \
&& docker run --rm -it --name "$dev_name"Dev"$RANDOM" --hostname "$dev_name"Dev"$RANDOM" "$lowerdev:dev"
break
;;
"Prune")
echo "Clearing Docker cache..."
docker system prune -af
echo ""
echo "Removing Docker buildx builder..."
if docker buildx rm "$buildername" > /dev/null 2>&1; then
echo ""
echo "Builder $buildername removed"
else
echo "Builder already removed, no action performed"
echo ""
fi
exec bash $0
;;
"Quit")
echo "Exiting script"
exit
;;
*)
echo "invalid option $REPLY"
;;
esac"
done
exit 0
I'm currently using "
eval "case \"$dev_name\" in
" but that seems problematic from what I've read.
It works, but I'm not sure if there is a better way to achieve what the results.
The choices are created from the folder names in the repo , but I'm not quite sure how to get out of using eval. Am I worrying about something pointless?
Modem7
(11 rep)
Nov 3, 2022, 06:56 PM
• Last activity: Nov 4, 2022, 01:17 AM
1
votes
1
answers
68
views
Selecting from various media using awk shell script
I have made a simple backup program for my bin folder. It works. Code and resultant STDOUT below. Using rsync to copy from local ~/bin folder to a /media/username/code/bin folder. The code works fine when only one result from `mount | grep media` but I can not quite fathom how to advance it to letti...
I have made a simple backup program for my bin folder. It works.
Code and resultant STDOUT below.
Using rsync to copy from local ~/bin folder to a /media/username/code/bin folder. The code works fine when only one result from
mount | grep media
but I can not quite fathom how to advance it to letting me select from multiple results from the mount/grep
.
I suspect the for LINE
below is lucky to work at all as I believe for
is delimited by spaces, in shell scripting, but as there are no spaces in the results it then delimited on the \n
? I tried find /media
and of course got a *lot* of results. Not the way to go I think. O_O
check_media () {
FOUNDMEDIA=$(mount | awk -F' ' '/media/{print $3}')
echo -e "foundmedia \n$FOUNDMEDIA"
echo For Loop
for LINE in $FOUNDMEDIA
do
echo $LINE
done
CHOSENMEDIA="${FOUNDMEDIA}/code/bin/"
echo -e "\nchosenmedia \n$CHOSENMEDIA\n"
exit
}
bin is /home/dee/bin/
foundmedia
/media/dee/D-5TB-ONE
/media/dee/DZ61
For Loop
/media/dee/D-5TB-ONE
/media/dee/DZ61
chosenmedia
/media/dee/D-5TB-ONE
/media/dee/DZ61/code/bin/
You can see how I add the save path /code/bin
to the found media but with multiple results I get a chosenmedia
which cannot work. I would like to be able to choose the media to which I want to rsync my backup to, or restore from.
Dee
(33 rep)
Oct 17, 2022, 10:58 AM
• Last activity: Oct 17, 2022, 12:44 PM
0
votes
1
answers
559
views
getopt and case function not executing
I encountered such a problem when passing a parameter to a script, the function corresponding to the case menu is not executed. The script accepts parameters as input and performs the appropriate actions ``` #!/bin/bash usage () { echo " Usage: -h, --help #Displaying help -p, --proc #Working with di...
I encountered such a problem when passing a parameter to a script, the function corresponding to the case menu is not executed. The script accepts parameters as input and performs the appropriate actions
#!/bin/bash
usage () {
echo " Usage:
-h, --help #Displaying help
-p, --proc #Working with directory /proc
-c, --cpu #Working with CPU
-m, --memory #Working with memory
-d, --disks #Working with disks
-n, --network #Working with networks
-la, --loadaverage #Displaying the load average on the system
-k, --kill #Sending signals to processes
-o, --output #Saving the results of script to disk"
exit2
}
proc () {
if [ -n "$1" ]
then
if [ -z "$2" ]
then
ls /proc
else
cat /proc/"$2"
fi
fi
}
parsed_arguments=$(getopt -o hp:c:m:d:n:la:k:o: --long help,proc:,cpu:,memory:,disks:,network:,loadaverage:,kill:,output:)
if [[ "${#}" -eq "" ]]
then
usage
fi
eval set -- "$parsed_arguments"
while :
do
case "$1" in
-h | --help) echo " Showing usage!"; usage
;;
-p | --proc) proc
;;
esac
done
f the script does not receive any parameters, then a description of the options should be displayed, but if the script receives the first parameter starting with "-" or "--" as input, then the functions corresponding to the letter or word following the "-" or "--" should be executed.
Example
No parameters:
./script.sh
Usage:
-h, --help #Displaying help
-p, --proc #Working with directory /proc
-c, --cpu #Working with CPU
-m, --memory #Working with memory
-d, --disks #Working with disks
-n, --network #Working with networks
-la, --loadaverage #Displaying the load average on the system
-k, --kill #Sending signals to processes
-o, --output #Saving the results of script to disk"
With one parameters:
./script.sh -p
or
./script.sh --proc
The contents of the /proc directory should be displayed
With additional parameters:
]]./script.sh -p cpuinfo
or
./script.sh --proc cpuinfo
The contents of the file passed through the additional parameter should be displayed
A script without arguments is executed, but not with arguments. Can you tell me what could be the reason for the fact that when passing arguments to the script, the corresponding functions are not executed.
Maverick
(1 rep)
Sep 30, 2022, 12:24 PM
• Last activity: Sep 30, 2022, 05:23 PM
0
votes
1
answers
27
views
if condition always false despite the condition being true upon manual execution
I wish to search for a string `mongo` and not starting with comment i.e `#` in a file. homedir=`ls -d ~` echo "$homedir" if [[ `cat $homedir/2_need_softwares.txt | grep -v '^#' | grep -iq mongo` ]]; then echo "Installing mongodb" else echo "skipping mongo" fi Output: /root skipping mongo I'm on `cen...
I wish to search for a string
mongo
and not starting with comment i.e #
in a file.
homedir=ls -d ~
echo "$homedir"
if [[ cat $homedir/2_need_softwares.txt | grep -v '^#' | grep -iq mongo
]]; then
echo "Installing mongodb"
else
echo "skipping mongo"
fi
Output:
/root
skipping mongo
I'm on centos 9
$ uname -a
Linux DKERP 5.14.0-134.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Jul 21 12:57:06 UTC 2022 x86_64 x86_64 x86_64 GNU/Linux
As you see the if
statement is failing and hence the else
gets executed.
But when I run the if condition manually it shows success
$ cat /root/2_need_softwares.txt | grep -v '^#' | grep -iq mongo
$ echo $?
0
$ grep mongo /root/2_need_softwares.txt
mongo
Can you please suggest what is wrong with my if
condition?
I tried the below as well:
1. if [[ $(cat $homedir/2_need_softwares.txt | grep -v '^#' | grep -iq mongo) ]]; then
2. if [[ $("cat $homedir/2_need_softwares.txt | grep -v '^#' | grep -iq mongo") ]]; then
This is for bash
and POSIX
is preferred.
Ashar
(527 rep)
Sep 4, 2022, 08:30 PM
• Last activity: Sep 4, 2022, 08:55 PM
2
votes
3
answers
2515
views
Bash, use case statement to check if the word is in the array
I am writing a script which must accept a word from a limited predefined list as an argument. I also would like it to have completion. I'm storing list in a variable to avoid duplication between `complete` and `case`. So I've written this, completion does work, but `case` statement doesn't. Why? One...
I am writing a script which must accept a word from a limited predefined list as an argument. I also would like it to have completion. I'm storing list in a variable to avoid duplication between
complete
and case
. So I've written this, completion does work, but case
statement doesn't. Why? One can't just make case statement parameters out of variables?
declare -ar choices=('foo' 'bar' 'baz')
function do_work {
case "$1" in
"${choices[*]}")
echo 'yes!'
;;
*)
echo 'no!'
esac
}
complete -W "${choices[*]}" do_work
vatosarmat
(252 rep)
Sep 2, 2022, 06:20 AM
• Last activity: Sep 3, 2022, 06:14 AM
29
votes
7
answers
46138
views
How can I use a variable as a case condition?
I am trying to use a variable consisting of different strings separated with a `|` as a `case` statement test. For example: string="\"foo\"|\"bar\"" read choice case $choice in $string) echo "You chose $choice";; *) echo "Bad choice!";; esac I want to be able to type `foo` or `bar` and execute the f...
I am trying to use a variable consisting of different strings separated with a
|
as a case
statement test. For example:
string="\"foo\"|\"bar\""
read choice
case $choice in
$string)
echo "You chose $choice";;
*)
echo "Bad choice!";;
esac
I want to be able to type foo
or bar
and execute the first part of the case
statement. However, both foo
and bar
take me to the second:
$ foo.sh
foo
Bad choice!
$ foo.sh
bar
Bad choice!
Using "$string"
instead of $string
makes no difference. Neither does using string="foo|bar"
.
I know I can do it this way:
case $choice in
"foo"|"bar")
echo "You chose $choice";;
*)
echo "Bad choice!";;
esac
I can think of various workarounds but I would like to know if it's possible to use a variable as a case
condition in bash. Is it possible and, if so, how?
terdon
(251585 rep)
Oct 6, 2015, 12:35 PM
• Last activity: Aug 26, 2022, 06:01 PM
Showing page 1 of 20 total questions