Check Teamspeak status via Shellscript (Ubuntu) - bash

I'm trying to write a shell script for Ubuntu, which checks the Teamspeak-server status and reacts to them.
This is my actual version:
a=$(sh /home/teamspeak3/ts3/teamspeak3-server_linux_amd64/ts3server_startscript.sh status)
echo "$a"
if [ "$a" -ne "Server is running"]
then
echo "..."
fi
exit 0
This is my actual output (and problem):
user1234#euve252903:~$ ./keepAlive.sh
Server is running
./keepAlive.sh: line 8: syntax error: unexpected end of file
(The text "Server is running" is the output from echo "$a").
I don't get the reason, why the syntax error appears...
I checked the file for MSDOS-ending signs.
Any ideas out there?

You're missing a space before the last bracket in your if statement
#!/bin/bash
a=$(sh /home/teamspeak3/ts3/teamspeak3-
server_linux_amd64/ts3server_startscript.sh status)
echo "$a"
if [ "$a" -ne "Server is running" ]; then
echo "..."
fi
exit 0
Also, I'd recommend adding a shebang and lastly, running the script in debug mode (bash -x) to find out what's wrong. If neither one of those work for you, try Shell Check, at least for syntax errors that is.

Related

trying to create my bash script

I am trying to create a simple bash script.
(just started working on bash scripting)
the script is simple. There is an issue with rsyslog service and from time to time dies.
I am trying to make a script to check if service is dead to restart it
till now I want to check if my conditions are ok but it seems I am getting an error. Can you advice me ?
Here is the script:
#!/bin/bash
a="dead"
b="running"
while i in $(/etc/init.d/rsyslog status | grep -o 'running\|dead');
do
if
[ "$a" == "$i" ];
then
echo "service rsyslog is dead "
if
[ "$b" == "$i" ];
then
echo "service rsyslog is running"
else
echo "nothing to do";
fi;
done
-------------
I am getting the following syntax error.
./rsyslogcheck.sh: line 17: syntax error near unexpected token done'
./rsyslogcheck.sh: line 17:done'
Thank you in advance!!
There are several problems here:
Invalid while loop syntax
Unnecessary loop: it seems you don't need a loop at all
Missing closing fi of an if that was opened
I suppose you're looking for something like this:
#!/bin/bash
status=$(/etc/init.d/rsyslog status | grep -o 'running\|dead')
case "$status" in
dead) echo "service rsyslog is dead";;
running) echo "service rsyslog is running";;
*) echo "nothing to do";;
esac

Unix utility which executes a command and tests its exit status

I am writing automated tests for the Gasoline, an OCaml library implementing application templates. Applications are expected to fail with a prescribed exit code in certain circumstances, like exit code 64 EXIT_USAGE when the application is called with an ill-formed command line:
% ./punishment.byte -x
punishment.byte: illegal option -- x
Usage: punishment.byte [-n number] [-p paragraph] [-c configfile]
Exit 64
Is there a standard Unix utility that can be used to run the subcommand ./punishment.byte -x and exit with status code 0 if the subcommand exited with status code 64? Something like
% expect_status 64 ./punishment.byte -x
punishment.byte: illegal option -- x
Usage: punishment.byte [-n number] [-p paragraph] [-c configfile]
Exit 0
As I am using a Makefile to orchestrate the tests, a legible statement such as expect_status 64 ./punishment.byte -x would be nice to have.
Notes
The Exit line in console interaction examples is informative and not part of the output.
I am well aware that I can write such a tool and how to do it, I just want to be sure there is no standard command doing that already.
The answer to your question is no. There is no standard utility on *nix systems for running a command and testing its exit code against a specific value. Probably because it's trivial to write one yourself.
I'm guessing from the % in your code that you're using zsh. If you're actually using csh (or tcsh), then things work differently.
That said, you can easily write a shell function to do this:
expect_status() {
local expected=$1
shift
"$#"
(( $? == expected ))
}
But that will run the command inside your current shell environment, which may have side effects you don't want. It would probably be better realized as a script - just save it somewhere in your $PATH with the filename expect_status and give it read and execute permission:
#!/bin/bash
expected=$1
shift
"$#"
(( $? == expected ))
Or, eschewing bashisms:
#!/bin/sh
expected=$1
shift
${1+"$#"}
[ $? -eq $expected ]
As suggested, you can check exit code of last command execution by referencing shell variable "$?".
$ ls -bogusOption
ls: invalid option -- 'O'
Try 'ls --help' for more information.
$ echo $?
2
shell can be used as utility to test exit code. say,
$ cat test.sh
#!/usr/bin/env bash
echo "executing bogus option"
ls -bogusOption
if [ "$?" -eq "0" ]; then
echo "command succeeded."
else
echo "command failed"
fi
$ bash -xv ./test.sh
#!/usr/bin/env bash
echo "executing bogus option"
+ echo 'executing bogus option'
executing bogus option
ls -bogusOption
+ ls -bogusOption
ls: invalid option -- 'O'
Try 'ls --help' for more information.
if [ "$?" -eq "0" ]; then
echo "command succeeded."
else
echo "command failed"
fi
+ '[' 2 -eq 0 ']'
+ echo 'command failed'
command failed
Well, in a sense, there is a standard utility: the shell itself:
command1 && command2
The above will only execute command2 if the exit code of command1 is 0. Alternatively, this:
command1 || command2
will only run command2 if the exit code of command1 was not 0.
To check for a specific exit status, you would use $? as described in the other answers:
command; [ "$?" -eq 64 ] && command2
So, the functionality you're looking for is essentially built directly into the shell and, therefore, you won't find a utility designed to do this.

Want to echo good error message in case of linux command failed

I am trying to write a function in bash so that when any command fails, It will print a nice error message, I tried this
#!/bin/bash
msg()
{
if echo $? > 0 ; then
echo "==> Something wrong happened. Please see /var/log/install.log"
else
echo "==> Done"
fi
}
But when I tried to use them in this way:
#!/bin/bash
msg()
{
if echo $? > 0 ; then
echo "==> Something wrong happened. Please see /var/log/install.log"
else
echo "==> Done"
fi
}
mkdir vcvcxvcxv
msg
Then I ran this on terminal
$ bash check
mkdir: vcvcxvcxv: File exists
==> Something wrong happened, Please see /var/log/install.log
I got same output whatever. But I suppose to get the "Done" message when my command succeeds. Is there any help in this regard?
This:
if echo $? > 0
does not do anything you want it to.
if [ $? -ne 0 ]
Although you got your immediate problem fixed already, your code isn't very idiomatic, and violates some fundamental shell scripting principles.
Errors should produce an error status
Error messages should go to standard error
Don't be needlessly verbose
So the simplest fix is really
mkdir vcvcxvcxv || exit
since mkdir already produces an error message on stderr, and exit will propagate the value of $? to the calling process.
Incidentally, you can get much the same effect with set -e but it is slightly cumbersome to use for the newcomer.
If you want the "helpful" error message, perhaps this;
death () {
rc=$?
echo "$0: see /var/log/install.log" >&2
exit $rc
}
mkdir vcvcxvcxv || death
echo "$0: done." >&2
would be closer to what you really need. Notice how the status messages are redirected to standard error (and each has the name of the script, so you can see what's causing the failure when you have scripts calling scripts calling scripts, etc) and the exit status is naturally propagated to the caller, and the entire script aborted, in the case of a fatal error. Also, the flow of the main script becomes more natural as it grows;
something || death
additional thing || death
final thing || death
echo "$0: done." >&2
(Of course, if failure means death always, you actually want set -e.)

condition in shell script

I have the following shell script :
#!/bin/sh
output=`./process_test.sh status_pid | grep "NOT STARTED: process_1" --line-buffered`
if[[ -z ${output} ]]
then
echo "process is not running"
else
echo "process is running"
fi
where ./process_test.sh status_pid is my utility for finding whether a process is running or not .e.g. if process_1 is not running it will give: NOT STARTED: process_1. Further
this utility is perfect and does not have any issue. I suspect the issue is with if syntax
on running this script I get the following output:
./test.sh: line 18: if[[ -z NOT: command not found
./test.sh: line 19: syntax error near unexpected token `then'
./test.sh: line 19: `then'
Can you help to resolve this issue?
You must use spaces to separate keywords such as if from the arguments or commands such as [[.
#!/bin/sh
output=$(./process_test.sh status_pid | grep -e "NOT STARTED: process_1" --line-buffered)
if [[ -z ${output} ]]
then
echo "process is not running"
else
echo "process is running"
fi
You should write it like
if [[ -z ${output} ]]
then
...
So you had missed a .
It would be a lot cleaner to write this:
#!/bin/sh
if ! ./process_test.sh status_pid |
grep "NOT STARTED: process_1" > /dev/null; then
echo "process is not running"
else
echo "process is running"
fi
Note that the --line-buffering argument is irrelevant, since
the pipe is not going to finish until after all of the input
is read. (Well, it's not totally irrelevant--it will make the
script run negligibly slower.)
Also note that '[[' is not standard. According to the shell language specification, it
"may be recognized as ( a ) reserved (word) on some implementations ..., causing unspecified results". In other words, it is what is commonly known as a "bashism" (although it is valid in shells other than bash), and if you use it you must not use #!/bin/sh as your interpreter, but should specify #!/bin/bash.

Problem with pidof in Bash script

I've written a script for me to start and stop my Perforce server. To shutdown the server I use the kill -SIGTERM command with the PID of the server daemon. It works as it should but there are some discrepancies in my script concerning the output behavior.
The script looks as follows:
#!/bin/sh -e
export P4JOURNAL=/var/log/perforce/journal
export P4LOG=/var/log/perforce/p4err
export P4ROOT=/var/local/perforce_depot
export P4PORT=1666
PATH="/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin"
. /lib/lsb/init-functions
p4start="p4d -d"
p4stop="p4 admin stop"
p4user=perforce
case "$1" in
start)
log_action_begin_msg "Starting Perforce Server"
daemon -u $p4user -- $p4start;
echo "\n"
;;
stop)
echo "BLABLA"
echo "$(pidof /usr/local/bin/p4d)"
#daemon -u $p4user -- $p4stop;
p4dPid="$(pidof /usr/local/bin/p4d)"
echo $p4dPid
if [ -z "$(pidof /usr/local/bin/p4d)" ]; then
echo "ERROR: No Perforce Server running!"
else
echo "SUCCESS: Found Perforce Server running!\n\t"
echo "Shutting down Perforce Server..."
kill -15 $p4dPid;
fi
echo "\n"
;;
restart)
stop
start
;;
*)
echo "Usage: /etc/init.d/perforce (start|stop|restart)"
exit 1
;;
esac
exit 0
When p4d is running the stop block works as intended, but when there is no p4d running the script with stop only outputs BLABLA and an empty new line because of the echo "$(pidof /usr/local/bin/p4d)". The error message stating that no server is running is never printed. What am I doing wrong here?
PS: The part if [ -z "$(pidof /usr/local/bin/p4d)" ]; then has been changed from if [ -z "$p4dPid" ]; then for debug reasons.
EDIT: I narrowed down the problem. If I don't use the p4dPid variable and comment out the lines p4dPid="$(pidof /usr/local/bin/p4d)" and echo $p4dPid the if block is processed and the error messages is printed. Still I don't unterstand what is causing this behavior.
EDIT 2: Problem solved!
The -e in #!/bin/sh -e was causing the shell to exit the script after any statement returning a non-zero return value.
When your service is not running, the command
echo "$(pidof /usr/local/bin/p4d)"
is processed as
echo ""
because pidof did not return any string. So the command outputs an empty line.
If you do not want this empty line, then just remove this statement, after all you print an error message when the process is not running.
Problem solved!
The -e in #!/bin/sh -e was causing the shell to exit after any statement returning a non-zero return value.

Resources