Bash script - could someone proof read and explain why it is wrong - bash

Тhis is the first script I've ever written and I'm looking for some help. I can't find a script like the one I'm trying to write and its becoming a bother because I wish to create more/expand upon such a bash structure.
If some one has the time could they maybe proof read this for me. Could someone tell me what am I doing wrong and why?
#! /bin/bash
# script to turn the screen blue
echo -e '\033[1;32m'
echo "Minecraft Server LTG Bukkit 1.4.7"
echo "Minecraft Server LTG Bukkit 1.4.7"
echo -e '\033[31m' "[Start ] \033[1;32m LTG MineCraft Server"
echo -e '\033[31m' "[Stop ] \033[1;32m LTG MineCraft Server"
echo -e '\033[31m' "[Restart] \033[1;32m LTG MineCraft Server"
echo -e '\033[0m'
cho -e "Hello, \033[47m \033[30m"$USER" \033[0m Enter Command:"
echo "Command:"
read $COM1 start stop restart
if ["$COM1" = "start"]: then
echo "ran minecraft serv"
if [ "$(pgrep -g java -Xmx256M -Xms256M -jar /minecraft/minecraft_server.jar)" ] ; then
echo MineCraft Server Bukkit 1.4.7 L.T.G : Running
else
echo -e "\033[1;32m MineCraft Server Bukkit 1.4.7 L.T.G : \033[31m FAILED \033[0m"
fi
if ["$COM1" "stop"]: then
echo -e "\033[1;32m MineCraft Server Bukkit 1.4.7 L.T.G : Shutting Down \033[0m"
killall java
if (( "$(pgrep -g java -Xmx256M -Xms256M -jar /minecraft/minecraft_server.jar)" )) ; then
killall java
echo -e "\033[1;32m MineCraft Server Bukkit 1.4.7 L.T.G: is SHUTDOWN \033[0m"
fi
if [ "$COM1" "Restart" ] ; then
echo MineCraft Server Bukkit 1.4.7 L.T.G : Rebooting
exit 1
fi
fi
exit 0

Let's take two lines...there's enough there to keep us busy.
read $COM1 start stop restart
if ["$COM1" = "start"]: then
The first line reads into a variable whose name is stored in $COM1 (which is uninitialized, so in fact it is empty, so it doesn't do anything after all), plus the three variables start, stop, and restart. You either need:
read COM1 start stop restart
or you need to initialize COM1 before you use it.
The second line manages to run into a surprising number of issues.
The test command, aka [, is a command name, not a symbol. As such, it needs to be separated from its arguments. Note that there usually is a command /bin/[ or /usr/bin/[, though it is also a shell built-in these days.
Fortunately, since $COM1 is unset and empty, it already is separated, but more by accident than design.
Because of that, your [ command is executed with 3 arguments: =, ]: and then. This is not a valid invocation of [. The last argument should be ] on its own.
You should use a semi-colon to separate the ] from the then.
In aggregate, you should have written:
if [ "$COM1" = "start" ]
then
or you can add a semi-colon (which does not have to be separated from the ] by a space) and then the then:
if [ "$COM1" = "start" ]; then
Stylistically, you have the string 'Minecraft Server LTG Bukkit 1.4.7' repeated all over the place; don't! Use a variable to hold it.
Worry about your embedded cursor control sequences; different terminals have different sequences, so you're restricted to a single terminal type. Fixing that is harder; investigate the tput command.

alright so this is what i ended up with- it works but i want to know if there are ways of improving such a disaster
i really do appreciate the response :)
#! /bin/bash
# script to turn the screen blue
NAME=$(echo Minecraft Server LTG Bukkit 1.4.7)
echo -e '\033[1;32m'
echo "$NAME"
echo "$NAME"
N1=$(echo LTG MineCraft Server)
echo -e '\033[31m' "[Start ] \033[1;32m $N1"
echo -e '\033[31m' "[Stop ] \033[1;32m $N1"
echo -e '\033[31m' "[Restart] \033[1;32m $N1"
echo -e '\033[0m'
echo -e "Hello \033[47m \033[30m"$USER" \033[0m Enter Command:"
echo "Command:"
read test
#this is a test piece
echo "start = $test"
if [ $test == "start" ]; then
echo -e "\033[31m $NAME : Starting"
java -Xmx256M -Xms256M -jar /minecraft/minecraft_server.jar &>./minecraft.sh.rlog
if [ "$(pgrep -g java -Xmx256M -Xms256M -jar /minecraft/minecraft_server.jar)" ] ; then
echo -e "\033[31m $NAME : Running"
exit 1
else
echo -e "\033[1;32m $NAME : \033[31m FAILED \033[0m"
fi
fi
if [ $test == "stop" ]; then
echo -e "\033[1;32m $NAME : Shutting Down \033[0m"
killall java &> ./minecraft.sh.log
MINECRAFT=$(pgrep -g java -Xmx256M -Xms256M -jar /minecraft/minecraft_server.jar &>./minecraft.sh.log)
sleep 1
echo .
sleep 1
echo .
sleep 1
echo .
sleep 1
echo .
if [[ -z "$MINECRAFT" ]] ; then
killall java &> ./minecraft.sh.log
echo -e "\033[1;32m $NAME : IS SHUTDOWN \033[0m"
else
#should never bee seen
echo Something Went Wrong
fi
fi
if [ $test == "restart" ] ; then
echo -e "\033[31m $NAME : Rebooting \033[0m"
kill java &>minecraft.sh.log
sleep 1
echo .
sleep 1
echo .
if [[ -z "$MINECAFT" ]]; then
echo -e "\033[1;32m $NAME : IS SHUTDOWN \033[0m"
sleep 1
echo .
fi
echo -e "\033[31m $NAME : Starting \033[0m"
sleep 1
echo .
java -Xmx256M -Xms256M -jar /minecraft/minecraft_server.jar &> ./minecraft.sh.rlog
else
if [ $test == "exit" ] ; then
exit 0
fi
exit 1
fi

Related

Command not found in elif comparison > bash

For some reason commands are not running after the first if statement.
"/usr/local//backup.sh: sleep: not found" for example..
The first if statement goes like:
if [ "$command" == "start -c" ]; then
echo -e "${ORANGE}Starting website backup...${E}"
sleep 1
DT=`date +%Y-%m-%d`
echo -e "${ORANGE}Started backup at $DT ${E}"
sleep 1
tar -zcvf web-$DT.tar.gz /usr/local/www/nginx
echo -e "${ORANGE}Compatced files, moving to backup directory${E}"
sleep 1
mv web-$DT.tar.gz $PATH/web-$DT.tar.gz
echo -e "${CYAN}Moved to backups ($PATH/web-$DT.tar.gz)\nDo you want to upload to ftp?${E}\n${CYAN} 'y' or 'n'?${E}"
read answer
if [ "$answer" == "y" ]; then
echo -e "${ORANGE}Uploading to ftp server...${E}"
sleep 1
if ftp -in -u ftp://$USER:$PASS#$HOST/Backups/f $PATH/web-$DT.tar.gz; then
echo -e "${GREEN}Uploaded! Bye!${E}"
else
echo -e "${ORANGE}Couldn't upload with ftp command, trying with curl...${E}"
sleep 1
curl -T "$PATH/web-$DT.tar.gz" -u $USER:$PASS ftp://$HOST/Backups/f/
echo -e "${GREEN}Uploaded! Bye!${E}"
fi
else
echo -e "${GREEN}Bye!${E}"
fi
Everything works fine inside this statement, however, after the elif compassion it just doesn't.
Here's the problematic code:
elif [ "$command" == "start -d" ]; then
echo -e "${ORANGE}Starting database backup...${E}"
sleep 1
DT=`date +%Y-%m-%d`
echo -e "${ORANGE}Started backup at $DT ${E}"
sleep 1
umask 177
echo -e "${ORANGE}Dumping database 'account'\n${E}"
mysqldump --user=$DBUSER --password=$DBPASS --host=$HOST account > $PATH/account-$DT.sql
sleep 1
echo -e "${ORANGE}Dumping database 'game'\n${E}"
mysqldump --user=$DBUSER --password=$DBPASS --host=$HOST game > $PATH/game-$DT.sql
sleep 1
echo -e "${ORANGE}Dumping database 'forum'\n${E}"
mysqldump --user=$DBUSER --password=$DBPASS --host=$HOST forum > $PATH/forum-$DT.sql
sleep 1
echo -e "${CYAN}Moved to backups ($PATH/<database-date>.sql)\nDo you want to upload to ftp?${E}\n${CYAN} 'y' or 'n'?${E}"
read answer
if [ "$answer" == "y" ]; then
echo -e "${ORANGE}Uploading to ftp server...${E}"
sleep 1
curl -T "$PATH/account-$DT.sql" -u $USER:$PASS ftp://$HOST/Backups/f/Databases/
curl -T "$PATH/game-$DT.sql" -u $USER:$PASS ftp://$HOST/Backups/f/Databases/
curl -T "$PATH/forum-$DT.sql" -u $USER:$PASS ftp://$HOST/Backups/f/Databases/
sleep 1
echo -e "${GREEN}Uploaded! Bye!${E}"
else
echo -e "${GREEN}Bye!${E}"
fi
and then I just ended it..
else
echo -e "${RED}Sorry! Not found${E}"
fi
As you can see there's spaces in the if statements and all of that, so what's wrong with this??
I've the #!/bin/bash up top as well, all the variables exist too.
You seem to have overwritten the value of the PATH variable at some point in your code. The shell needs that variable in order to know where to find programs like sleep (Hence the "not found" error). Name your path variable something else.

Running Cassandra as a service on OpenSuse

I am trying to run Cassandra as a service on OpenSuse (Leap 42.1).
I have tried installing with apache-cassandra-2.1.11-bin.tar.gz and then copying /etc/init.d/cassandra from https://gist.github.com/sgomezvillamor/5458309. However, the startup script is not designed for OpenSuse, as the system.log says:
/etc/init.d/cassandra: line 30: daemon: command not found.
The problem would not exist if there would be an installer that would create the scripts correctly, similarly as there are for some other OSs. Searching for an installation package, I found http://www.datastax.com/dev/blog/announcing-rpms-cassandra and tried to look for an rpm in rpm.riptano.com but I cannot figure out which one would work in OpenSuse.
Which of those packages would work for OpenSuse? Or, how should I modify the startup script for Suse-fying it?
I would check these instructions which are for Cassandra 2.1: Installing DataStax Community 2.1 on RHEL-based systems.
I'm not sure whether that will get you 100% there on an OpenSUSE system, but should get you very close.
I got it to work with /etc/init.d/cassandra file:
#!/bin/bash
#
# /etc/init.d/cassandra
#
# Startup script for Cassandra
#
# chkconfig: 2345 20 80
# description: Starts and stops Cassandra
#. /etc/rc.d/init.d/functions
export CASSANDRA_HOME=/opt/apache-cassandra-2.1.11
export CASSANDRA_CONF=$CASSANDRA_HOME/conf
export CASSANDRA_INCLUDE=$CASSANDRA_HOME/bin/cassandra.in.sh
#export CASSANDRA_OWNR=cassandra
export CASSANDRA_OWNR=root
#NAME="cassandra"
NAME="root"
log_file=/srv/cassandra/log/cassandra.log
pid_file=/var/run/cassandra/cassandra.pid
lock_file=/var/lock/subsys/$NAME
CASSANDRA_PROG=/opt/apache-cassandra-2.1.11/bin/cassandra
# The first existing directory is used for JAVA_HOME if needed.
JVM_SEARCH_DIRS="/usr/lib/jvm/jre /usr/lib/jvm/jre-1.7.* /usr/lib/jvm/java-1.7.*/jre"
# Read configuration variable file if it is present
[ -r /etc/default/$NAME ] && . /etc/default/$NAME
# If JAVA_HOME has not been set, try to determine it.
if [ -z "$JAVA_HOME" ]; then
# If java is in PATH, use a JAVA_HOME that corresponds to that. This is
# both consistent with how the upstream startup script works, and with
# the use of alternatives to set a system JVM (as is done on Debian and
# Red Hat derivatives).
java="`/usr/bin/which java 2>/dev/null`"
if [ -n "$java" ]; then
java=`readlink --canonicalize "$java"`
JAVA_HOME=`dirname "\`dirname \$java\`"`
else
# No JAVA_HOME set and no java found in PATH; search for a JVM.
for jdir in $JVM_SEARCH_DIRS; do
if [ -x "$jdir/bin/java" ]; then
JAVA_HOME="$jdir"
break
fi
done
# if JAVA_HOME is still empty here, punt.
fi
fi
JAVA="$JAVA_HOME/bin/java"
export JAVA_HOME JAVA
case "$1" in
start)
# Cassandra startup
echo -n "Starting Cassandra: "
su $CASSANDRA_OWNR -c "$CASSANDRA_PROG -p $pid_file" > $log_file 2>&1
retval=$?
[ $retval -eq 0 ] && touch $lock_file
echo "OK"
;;
stop)
# Cassandra shutdown
echo -n "Shutdown Cassandra: "
su $CASSANDRA_OWNR -c "kill `cat $pid_file`"
retval=$?
[ $retval -eq 0 ] && rm -f $lock_file
for t in `seq 40`; do $0 status > /dev/null 2>&1 && sleep 0.5 || break; done
# Adding a sleep here to give jmx time to wind down (CASSANDRA-4483). Not ideal...
# Adam Holmberg suggests this, but that would break if the jmx port is changed
# for t in `seq 40`; do netstat -tnlp | grep "0.0.0.0:7199" > /dev/null 2>&1 && sleep 0.1 || break; done
sleep 5
STATUS=`$0 status`
if [[ $STATUS == "$NAME is stopped" ]]; then
echo "OK"
else
echo "ERROR: could not stop $NAME: $STATUS"
exit 1
fi
;;
reload|restart)
$0 stop
$0 start
;;
status)
status -p $pid_file cassandra
exit $?
;;
*)
echo "Usage: `basename $0` start|stop|status|restart|reload"
exit 1
esac
exit 0

How to set exit codes for "status" command in init script for Tomcat6

I'm installing Tomcat6 and using the following for /etc/init.d/tomcat6:
#!/bin/bash
# description: Tomcat6 service
# processname: java
# chkconfig: - 99 1
## Note: CATALINA_HOME and CATALINA_PID are set elsewhere.##
# Source function library.
. /etc/init.d/functions
# Source sysconfig for tomcat6
if [ -f /etc/sysconfig/tomcat6 ]; then
. /etc/sysconfig/tomcat6
fi
[ -d "$CATALINA_HOME" ] || { echo "Tomcat requires $CATALINA_HOME."; exit 1; }
case $1 in
start|stop|run)
if su $TOMCAT_USER bash -c "cd $CATALINA_HOME/logs; $CATALINA_HOME/bin/catalina.sh $1"; then
echo -n "Tomcat $1 successful"
[ $1 == "stop" ] && rm -f $CATALINA_PID
else
echo -n "Error in Tomcat $1: $?"
fi
;;
restart)
$0 start
$0 stop
;;
status)
if [ -f "$CATALINA_PID" ]; then
read kpid < "$CATALINA_PID"
if ps --pid $kpid 2>&1 1>/dev/null; then
echo "$0 is already running at ${kpid}"
else
echo "$CATALINA_PID found, but $kpid is not running"
fi
unset kpid
else
echo "$0 is stopped"
fi
;;
esac
exit 0
The problem, as noted in this related ticket, is that Chef checks the "status" of a service and will not start it if the "status" command returns an exit code of "0". Which it always does because the script itself completes successfully, regardless of whether the service is running or not.
I need to adapt my init script to return an exit code of 3 if the service is not running, per the guidelines for Init scripts posted here:
0 program is running or service is OK
1 program is dead and /var/run pid file exists
2 program is dead and /var/lock lock file exists
3 program is not running
4 program or service status is unknown
5-99 reserved for future LSB use
100-149 reserved for distribution use
150-199 reserved for application use
200-254 reserved
I modified my initial script to:
#!/bin/bash
# description: Tomcat6 service
# processname: java
# chkconfig: - 99 1
# Source function library.
. /etc/init.d/functions
# Source sysconfig for tomcat6
if [ -f /etc/sysconfig/tomcat6 ]; then
. /etc/sysconfig/tomcat6
fi
[ -d "$CATALINA_HOME" ] || { echo "Tomcat requires $CATALINA_HOME."; exit 1; }
exit_var=0
case $1 in
start|stop|run)
if su $TOMCAT_USER bash -c "cd $CATALINA_HOME/logs; $CATALINA_HOME/bin/catalina.sh $1"; then
echo -n "Tomcat $1 successful"
[ $1 == "stop" ] && rm -f $CATALINA_PID
else
echo -n "Error in Tomcat $1: $?"
exit_var=1
fi
;;
restart)
$0 start
$0 stop
;;
status)
if [ -f "$CATALINA_PID" ]; then
read kpid < "$CATALINA_PID"
if ps --pid $kpid 2>&1 1>/dev/null; then
echo "$0 is already running at ${kpid}"
exit_var=0
else
echo "$CATALINA_PID found, but $kpid is not running"
exit_var=4
fi
unset kpid
else
echo "$0 is stopped"
exit_var=3 # Fixes issue with Chef not starting a stopped service.
fi
;;
esac
exit $exit_var
But those aren't ACTUALLY changing the exit codes for the script. How can I set different exit codes for different case scenarios?
Version Info:
OS: CentOS 6.5
Chef: 10.20
Tomcat: 6.0.39
You have the right idea, but you have exit_var=3 in the wrong place. I have placed it below to equal 3 for the status when it is already running:
status)
if [ -f "$CATALINA_PID" ]; then
read kpid < "$CATALINA_PID"
if ps --pid $kpid 2>&1 1>/dev/null; then
echo "$0 is already running at ${kpid}"
## Fixes issue with Chef not starting a stopped service.
exit_var=3 ## this is the condition of already running
else
echo "$CATALINA_PID found, but $kpid is not running"
exit_var=4
fi
unset kpid
else
echo "$0 is stopped"
exit_var=5 # (renumbered 5 set as you desire)
fi
;;
esac
exit $exit_var

Programmatically shut down or sleep sandboxed application Mac

I am trying to make an application for the Mac App Store that will shut down/sleep the Mac after a user-set time. I have tried to use AppleScript, but that won't work if I am going to use it in Sandbox mode, I have tried to Google for a solution, but I cant seem to figure it out.
Hope someone can give me a hint or link to relevant documentation.
edit: made it more precise to what I desire to accomplish.
There is no way to do this. You may try to get a temporary-exception to run "shutdown" or "halt" thru BSD-layer but I doubt that such an app will pass the App Store review as these are tasks that require superuser / admin rights.
I wrote a script once. But I don't know whether it still works. Maybe it gives you at least a clue. Sleep still works - shutdown maybe causes problems if programs are blocking the shutdown.
(Not the prettiest code but it worked for me.)
#/bin/sh
#v1.0.0
#by Sapphire
echo "-----------------------------------------------------"
echo "* Sleep Timer *"
echo "-----------------------------------------------------"
echo "Please enter option: Sleep '1' or shutdown '0'"
echo -n "Option: "
read option
while :
do
if [ $option -eq 1 -o $option -eq 0 ]
then
break
fi
echo "<<ERROR: Only number: 1 or 0 allowed...>>"
echo "Please rnter option: Sleep '1' or shutdown '0'"
echo -n "Option: "
read option
done
echo "Please enter countdown (min):"
echo -n "Minutes: "
read shutDown
while :
do
if [ $shutDown -gt 0 -a $var -eq $var 2> /dev/null ]
then
break
fi
echo "<<ERROR: Positive number expected...>>"
echo "Please enter countdown (min):"
echo -n "Minutes: "
read shutDown
done
echo "*****************************************************"
echo "Counter has been started"
echo "'/!\ Kill countdown with CTRL-C /!\'"
echo -n "Envoking command in: "
date +"%H:%M %Z"
echo "*****************************************************"
if [ $option -eq 0 ]
then
echo "Shutdown in: "
fi
if [ $option -eq 1 ]
then
echo "Sleep in: "
fi
echo -e "\n *------------------------------* "
barCounter=0;
counter=0
((timeBarSize=$shutDown * 2))
bar="||||||||||||||||||||||||||||||"
barEmpty=" "
((flag=0))
for ((i=shutDown*60;i>=0;i--));
do
if ((counter >= timeBarSize ))
then
((counter=0))
((barCounter=$barCounter + 1))
fi
((counter=$counter + 1))
((timehh=$i/3600))
((timemm=$i/60 - timehh*60))
((timess=$i - timemm*60 - timehh*3600))
if (( flag == 1 ))
then
echo $(tput cuu1)$(tput el)$(tput cuu1)$(tput el)$(tput cuu1)$(tput el)$(tput cuu1)$(tput el)$(tput cuu1)
fi
((flag=1))
echo -e " | $timehh:$timemm:$timess |"
echo -e "\r *------------------------------* "
echo -e "\r *${bar:0:$barCounter}${barEmpty:$barCounter:30}* "
echo -e "\r *------------------------------* "
sleep 1;
done
if [ $option -eq 1 ]
then
echo "Going to sleep..."
sleep 1
osascript -e 'tell application "System Events" to sleep'
elif [ $option -eq 0 ];
then
echo "Shutting down..."
sleep 1
osascript -e 'tell application "System Events" to shut down'
else
echo "No valid command found... doing nothing!"
fi
I also had to add this in my '/etc/sudoers' file (CAUTION, if you don't know how to handle this file! -> google):
# Custom privilege
myUser ALL=NOPASSWD: /Users/myUser/Documents/sleepTimer.sh

My shell script for starting NGiNX is not working

I found this small shell script in a book... NGiNX works it just this script that just does not work. Because every time I do /etc/init.d/nginx start (that is where the file is) it sends me this message: Usage: /etc/init.d/nginx {start|stop|restart|reload}
For testing purposes I added a echo "$1" and it sends me -e when I do: /etc/init.d/nginx start Or anything else...
I am using Ubuntu 12.04.
#! /bin/sh
# Author: Ryan Norbauer http://norbauerinc.com
# Modified: Geoffrey Grosenbach http://topfunky.com
# Modified: Clement NEDELCU
# Reproduced with express authorization from its contributors
set –e
PATH=/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin
DESC="nginx daemon"
NAME=nginx
DAEMON=/usr/local/nginx/sbin/$NAME
SCRIPTNAME=/etc/init.d/$NAME
# If the daemon file is not found, terminate the script.
test -x $DAEMON || exit 0
echo "0"
d_start() {
$DAEMON || echo -n " already running"
}
d_stop() {
$DAEMON –s quit || echo -n " not running"
}
d_reload() {
$DAEMON –s reload || echo -n " could not reload"
}
echo "$1"
case "$1" in
start)
echo -n "Starting $DESC: $NAME"
d_start
echo "."
;;
stop)
echo -n "Stopping $DESC: $NAME"
d_stop
echo "."
;;
reload)
echo -n "Reloading $DESC configuration..."
d_reload
echo "reloaded."
;;
restart)
echo -n "Restarting $DESC: $NAME"
d_stop
# Sleep for two seconds before starting again, this should give the
# Nginx daemon some time to perform a graceful stop.
sleep 2
d_start
echo "."
;;
*)
echo "Usage: $SCRIPTNAME {start|stop|restart|reload}" >&2
exit 3
;;
esac
exit 0
set –e is setting the list of arguments to the script to –e. Remove that line and the script will work.
Edit: The script posted contains set –e (that is EN DASH + e) as opposed to set -e (ASCII hyphen/minus sign + e). This caused sh to override the first argument passed with –e instead of setting the -e option in the shell. Replacing – with - should fix the problem.

Resources