Using tee with bash hangs with some scripts - linux

I have a simple script file startsql.sh to start mysql:
#!/bin/bash
#Script to Start MySQL
echo "Starting MySQL"
if sudo service mysqld start; then
echo "MySQL started successfully!"
else
echo "Error: Failure to start MySQL" 1>&2
exit 1
fi
I run it using:
bash startsql.sh |& tee -a scriptlogs.log
Though the service seems to start successfully, the command hangs after showing the messages on the command window. It works fine without hanging if I remove the tee. Interestingly I have a similar script to stop mysql and it works fine without issues. I checked and find no difference between the two scripts.
After searching a lot, I found that using the below works, but the side effect of this is that the tee process is still running in the background
bash startsql.sh > >( tee -a scriptlogs.log) 2>&1
Can someone please help me understand why does using tee hang on some occasions.

Will you teach me the version of bash?
If you use bash 3.2.57, the error occure like this.
$ bash ./startsql.sh |& tee -a output.txt
bash ./startsql.sh |& tee -a output.txt
bash: syntax error near unexpected token `&'

Related

command to redirect output to console and to a file at the same time works fine in bash. But how do i make it work in korn shell(ksh)

command to redirect output to console and to a file at the same time works fine in bash. But how do i make it work in korn shell(ksh).
All my scripts runs on korn shell so cant change them to bash for this particular command to work.
exec > >(tee -a $LOGFILE) 2>&1
In the code beneath I use the variable logfile, lowercase is better.
You can try something like
touch "${logfile}"
tail -f "${logfile}"&
tailpid=$!
trap 'kill -9 ${tailpid}' EXIT INT TERM
exec 1>"${logfile}" 2>&1
A not too unreasonable technique is to re-exec the shell with output to tee. That is, at the top of the script, do something like:
#!/bin/sh
test -z "$REXEC" && { REXEC=1 exec "$0" "$#" | tee -a $LOGFILE; exit; }

Checking if a node.js app has started properly using bash

I wrote a node.js application and have written a bash script to start it and verify if it's running. I have my script run npm start & first, then I have a check to see if the ports I want open are open using netstat. The check works fine when I run it after the script is run, but during the running of the script, the check fails because the server has not fully started before the check is run. My code is below:
echo "Starting the server..."
npm start & > /dev/null 2>&1
if [[ -z $(sudo netstat -tulpn | grep :$portNum | grep node) ]] ; then
echo -e "\tPort $portNum is not in use, something went wrong. Exiting."
else
echo -e "\tPort $portNum is in use!"
fi
Is there a good way to take the above script and change it so that the check doesn't occur until the server is fully started? I don't want to use sleep if I can help it.
You can use a wait call:
echo "Starting the server..."
npm start & > /dev/null 2>&1
wait
if [[ -z $(sudo netstat -tulpn | grep :$portNum | grep node) ]] ; then
echo -e "\tPort $portNum is not in use, something went wrong. Exiting."
else
echo -e "\tPort $portNum is in use!"
fi
The only limitation to this is that if npm daemonizes itself then it's no longer a child of the script so the wait command will have no effect (the reason for this is that a process daemonizes itself by terminating and spawning a new process that inherits its role).

Shell Scripting ssh execution of commands

I have no idea, how to execute this specific combined shell script command via ssh on a remote device.
#!/bin/bash
cmd=""
command="restart"
case "$command" in
restart)
cmd+="pkill -f fileA.py;"
cmd+="python3 -u fileA.py >> fileA.log &"
;;
*)
echo "Unknown command"
esac
cmd=$(ssh root#foobar $cmd)
The error that occurs is:
pkill -f fileA.py;python3 -u fileA.py >> fileA.log &
pkill: invalid user name: fileA.py
I know that the whole string is interpreted as one command, but that's not what I want to achive.
I appreciate any help.
Are you sure you pasted the right code? That pkill error messages comes from using the -u or
-U options. Please check that first.
Next, your lack of quotes is causing you problems. After the shell substitutes the variables, you have this:
cmd=$(ssh root#foobar pkill -f fileA.py;python3 -u fileA.py >> fileA.log &)
So you're killing the process on the remote system, and launching it on the local system.
I think you really need this:
case "$command" in
restart)
cmd="pkill -f fileA.py; nohup python3 -u fileA.py >> fileA.log & disown"
;;
*)
echo "Unknown command"
esac
cmd=$(ssh root#foobar bash -c "$cmd")
nohup and disown allow the backgrounded process to keep running after the shell exits.

bash command 'echo -n -e "\x87" > /dev/ttyAMA0' not working from shell script

I'm trying to controll my Roomba vacuum cleaner by a RaspberryPi. But still having some problems.
I need to send a special command to the serial interface to start the vacuum cleaner. If I do this in the Bash it works fine:
echo -n -e "\x87" > /dev/ttyAMA0
If I put this in my shell script it does not work any more:
#! /bin/bash
echo -n -e "\x87" > /dev/ttyAMA0
Any idea?
Have you made the script runnable? I.E. chmod +x script.sh. Also make sure you are running the script correctly ./script.sh. For more help see this website.

Bash: start remote python application through ssh and get its PID

I'm creating a little bash script to copy new files from a windows machine to a remote linux centos server (i run this script using the git-shell) then i want to restart the python application thats running in the server to use those new files.
The problem is that everytime i run this script i want to end the actual running process before i start it again, so i want to get the pid of the process i start and save it to a file in the remote host so i can read it from there the next time i run the program and kill it.
My code by now looks similar to this:
echo "Copying code files to server..."
# The destination folder has to exist in the server
scp -r ./python/ root#myserver:/root/
echo "Checking for running processes..."
if ssh root#myserver 'ls dmr.pid >/dev/null'; then
echo "PID file exists, reading file..."
PID=$(ssh root#myserver 'cat dmr.pid')
# Terminate the actual process
echo "Terminating the process with PID '$PID'..."
ssh root#myserver 'kill $PID'
else
echo "PID file doesn't exist, not known processes running"
fi
# Restart the server and get the PID
echo "Restarting the server..."
ssh root#myserver 'python /root/python/run_dev_server.py > /dev/null 2>&1 &'
SERV_PID=$(ssh root#myserver 'echo $!')
echo "Saving PID to file dmr.pid"
ssh root#myserver "echo '$SERV_PID' > \"dmr.pid\""
echo "Sucesfully finished!"
The important lines are:
ssh root#myserver 'python /root/python/run_dev_server.py > /dev/null 2>&1 &'
SERV_PID=$(ssh root#myserver 'echo $!')
the problem with this is that the script finishes but the file ends up empty as well as the $SERV_PID variable.
And if i dont redirect the outputs and just do something like this:
SERV_PID=$(ssh root#myserver 'python /root/python/run_dev_server.py & echo $!')
i get stuck after "Restarting the server" and never get the PID or the file that will contain it or even the end of the script.
But if i run this right in the console:
ssh root#myserver 'python /root/python/run_dev_server.py & echo $!'
i get a PID printed to the terminal.
Any advice on this would be really appreciated.
ssh root#myserver 'python /root/python/run_dev_server.py > /dev/null 2>&1 &'
SERV_PID=$(ssh root#myserver 'echo $!')
With the above code, you are running two ssh commands and the both create two different shells. The problem is echo $! gives the most recent background process' ID from the current shell which is none.
That is, when you ssh for the second time, it's new shell and there's no background process running in it and hence echo $! gives no output. This explains why your PID file is empty.
Instead what you can do is to lookup for all instances of your python script and kill them using killall command. Or similar idea using ps command.
Thanks to Kingslndian i solved it by making one single command that did the three steps i required, so with that avoided the problem of running in different shells:
ssh root#myserver 'python /root/python/run_dev_server.py > /dev/null 2>&1 & echo $! > "dmr.pid"'

Resources