Case statement not working in my shell script - linux

I'm trying to write a shell script for Mac OSX Mountain Lion (10.8.2). However, no matter what I try, I can't get the switch statement to work. He is a very simplified version of the script:
#!/bin/bash
while getopts "ei" opt; do
case $opt in
e)
echo "Got option e"
;;
i)
echo "Got option i"
;;
\?)
echo "Invalid option: -$opt"
;;
esac
done
No matter what I try, I don't get any output. Any ideas? I've done scripts like this in the past.

You might be passing the options incorrectly don't forget the -
script.sh -e
Note you should also exit after an invalid option:
\?)
echo "Invalid option: -$opt"
exit 1
;;

Try replacing
\?)
echo "Invalid option: -$opt"
;;
with:
*)
echo "Invalid option: -$opt"
;;

Related

Nested Case statement in shell script | Getting Syntax error

I am trying to run below shell script but i am getting syntax error.
script.sh env1 ManagedSvr1
line 29: warning: here-document at line 6 delimited by end-of-file (wanted `EOF')
line 30: syntax error: unexpected end of file
#!/bin/bash
case "$1" in "env1")
ssh weblogic#hostname1 << EOF
case "$server" in
"ManagedSvr1")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr1/logs/ManagedSvr1.log
;;
"ManagedSvr2")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr2.log
;;
esac
;;
"env2")
ssh weblogic#hostname2 << EOF
case "$server" in
"ManagedSvr1")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr1/logs/ManagedSvr1.log
;;
"ManagedSvr2")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr2.log
;;
esac
;;
esac
Your Here Docs specify EOF to end them (<< EOF) but you never have an EOF to end them. Note that EOF doesn't mean End of File, it means the string 'EOF'. https://en.wikipedia.org/wiki/Here_document has examples.
I'm not sure what you're hoping to accomplish, but it looks to me that you need to specify which file to tail. Are you hoping to pass the inner case into the remote shell on the server you're sshing into? It would simplify your code to set your filename and servername first and then ssh and execute the command. Actually, I don't see much purpose in your inner case statements anyway. Instead of wrapping everything in the 'env' case, you could just set the hostname to a variable. And then the "servername" can just be interpolated into the filesystem path. something like this seems like a simple approach:
#!/bin/bash
case "$1" in
env1)
hostname="hostname1"
;;
env2)
hostname="hostname2"
;;
esac
echo ssh weblogic#$hostname tailf /app/Oracle/Middleware/domains/dq/servers/$servername/logs/$servername.log
Seems to work simply and straight forward:
servername=ManagedSvr1 ./t.sh env1
ssh weblogic#hostname1 tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr1/logs/ManagedSvr1.log
Take out the "echo" to actually execute the ssh.
You actually don't need "HERE" docs, per say, you're using one case statement which is taking standard input to your SSH command. take single quotes as input to ssh This lets you do multiline input in peace. Quoting your "EOF" and terminating it, is also acceptable usage.
#!/bin/bash
case "$1" in
"env1")
ssh -tt weblogic#hostname1 <<< '
case "$server" in
"ManagedSvr1")
cat /var/log/syslog
;;
"ManagedSvr2")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr2.log
;;
esac '
;;
"env2")
ssh -tt weblogic#hostname2 <<< '
case "$server" in
"ManagedSvr1")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr1/logs/ManagedSvr1.log
;;
"ManagedSvr2")
tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr2.log
;;
esac '
;;
esac
This would be an easier way to manage the script. Especially as you're not utilising remote user change: Lets you set all your variables locally, and then just connect and execute the single command.
#!/bin/bash
server="$2"
case "$1" in
"env1")
hostname="hostname1"
case "$server" in
"ManagedSvr1")
remote_command=$(tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr1.log)
;;
"ManagedSvr2")
remote_command=$(tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr2.log)
;;
esac
;;
"env2")
hostname="hostname2"
case "$server" in
"ManagedSvr1")
remote_command=$(tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr1/logs/ManagedSvr1.log)
;;
"ManagedSvr2")
remote_command=$(tailf /app/Oracle/Middleware/domains/dq/servers/ManagedSvr2/logs/ManagedSvr2.log)
;;
esac
;;
*)
exit 1
;;
esac
if [[ $? == 0 ]]
then ssh weblogic#$hostname $remote_command
fi

Combining multiple options into one single option (Getopts)

Due to my lack of thorough understanding using getopts, the title is definitely vague :0. I am currently writing a bash script and I would like to add an option that outputs the other options within the case statement in getopts. For the sake of scaling, I have shortened the program.
#!/bin/bash
while getopts :abc opt
do
case $opt in
a)
echo "Hello"
;;
b)
echo "Goodbye"
c)
:ab #****I WANT -c TO OUTPUT THE RESULTS OF a and b************
;;
esac
done
As you can see in option c, I would like this particular option (-c) to put out both the results of -a and -b. Is there a way to go about this by simply making c call on option a and b?
you can introduce functions to reduce duplications, something like this:
#!/bin/bash
do_a() {
echo "Hello"
}
do_b() {
echo "Goodbye"
}
while getopts :abc opt
do
case $opt in
a)
do_a
;;
b)
do_b
;;
c)
do_a
do_b
;;
esac
done
If you are using a recent version of Bash, instead of terminating case clauses with ;; you could use bash specific ;;& with multiple patterns:
#!/bin/bash
while getopts :abc opt
do
case $opt in
a|c)
echo "Hello"
;;&
b|c)
echo "Goodbye"
;;&
esac
done
And:
$ bash script.bash -a
Hello
$ bash script.bash -c
Hello
Goodbye
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.

unrecognized service for my init.d

here is my full code, I just use following code:
case "$1" in
st)
echo 450 > /sys/class/backlight/intel_backlight
;;
stop)
echo
;;
rst)
echo; echo 450 > /sys/class/backlight/intel_backlight
;;
*)
echo "Usage: $0 {st|stop|rst}"
exit 1
;;
esac
why it raise this error
the reason is my init.d file has not "x" permission, so I need first chmod 755 /etc/init.d/brightness before running it
You may want to consider base your init script on the skeleton which live in /etc/init.d. Your script is probably inpcomplete.

switches for shell script

what is the best way to implement switches [ex: -m] for shell scripts?
I can do it via the switch case statement. But i am curious to know is there any other standard way to get all the arguments into a variable via a switch.
Ex:
-m A1 A2 -c c1 c2
So that,
M[] can take -m
and C[] can all take -c
The best known way is to use getopts, see http://wiki.bash-hackers.org/howto/getopts_tutorial
An example :
#!/bin/bash
while getopts ":a" opt; do
case $opt in
a)
echo "-a was triggered!" >&2
;;
\?)
echo "Invalid option: -$OPTARG" >&2
;;
esac
done

GETOPTS passing option to create find function

Im trying desperately finding the solution for my Getopts
For example
#!/bin/bash
while getopts ":a:b:" opt; do
case $opt in
a) find / $OPTARG >&2 ;;
b) 2>/dev/null >&2 ;;
\?)
echo "Invalid option: -$OPTARG" >&2
exit 1
;;
esac
and then as output example
./somefile.sh -a *txt -b
or
./somefile.sh -b -a *txt
but then i want to make sure i can upgrade it further, for examples find only sh files, or
something else.
Its not easy to find, but i hope someone could help me.

Resources