process not starting completely, when called inside crontab - bash

I have a script( let us call it watcher) which checks for a particular process if it's not running the watcher will start the process through a script.
I run this watcher in crontab at every minute. Now the problem is that it's not working in crontab but working if I run the watcher directly from the command line.
suppose the watcher start a script file called serverA.
ServerA code
echo -n "Starting $NAME: "
# start network server
start-stop-daemon --start --background --make-pidfile \
--pidfile $net_server_pidfile --startas /bin/bash -- -c "exec $angel $net_server \
-c $conf_file --lora-eui $lora_eui --lora-hw-1 $lora_hw --lora-prod-1 $lora_id \
--lora-path $run_dir --db $conf_db \
--noconsole >> $net_server_log 2>&1"
sleep 2
# start packet forwarder
/usr/sbin/start-stop-daemon --chdir $run_dir/1 --start --background --make-pidfile \
--pidfile $pkt_fwd_pidfile --exec $angel -- $pkt_fwd
renice -n -20 -p $(pgrep lora-network-se)
renice -n -20 -p $(pgrep $(basename $pkt_fwd))
echo "OK"
Now if i run watcher from directly the serverA will echo output Starting something then after sometime it continues with OK at the end.
But in crontab logs i dont see the OK, because of which the service never completes and serverA never starts.
watcher.sh
else
echo "$(date) do something, no packet forwader runnig"
exec /etc/init.d/lora-network-server start
fi

I think that you need to check difference of run time environments based terminal or not.
Firstly Check the lora-network-server whether depend on shell environments, such as JAVA_HOME or PATH (e.g. can execute the binary without absolute path of binary).
If it has different setting, it make same shell environments.
For exmaple, how to diff between cron env and runtime env.
runtime
$ env | tee ./runtime.output
cron
$ crontab <<EOF
* * * * * /bin/env > /path/to/cron.output 2>&1
EOF
Above cron output will create after 1 minute, and remove the cront after test.
you can check the variables onto cron.output and runtime.output
I hope this will help you.

Cron runs with a mostly empty environment. Are you setting all necessary environment variables in your scripts?

Related

CMD does not run if used after ENTRYPOINT

I have the following docker file
FROM confluentinc/cp-kafka-connect:5.3.1
RUN apt-get update && apt-get -y install cron
ENV CONNECT_PLUGIN_PATH=/usr/share/java
# JDBC-MariaDB
RUN wget -nv -P /usr/share/java/kafka-connect-jdbc/ https://downloads.mariadb.com/Connectors/java/connector-java-2.4.4/mariadb-java-client-2.4.4.jar
# SNMP Source
RUN wget -nv -P /tmp/ https://github.com/name/kafka-connect-snmp/releases/download/0.0.1.11/kafka-connect-snmp-0.0.1.11.tar.gz
RUN mkdir /tmp/kafka-connect-snmp && tar -xf /tmp/kafka-connect-snmp-0.0.1.11.tar.gz -C /tmp/kafka-connect-snmp/
RUN mv /tmp/kafka-connect-snmp/usr/share/kafka-connect/kafka-connect-snmp /usr/share/java/
COPY plugins-config.sh /usr/share/kafka-connect-script/plugins-config.sh
RUN chmod +x /usr/share/kafka-connect-script/plugins-config.sh
ENTRYPOINT [ "./etc/confluent/docker/run" ]
CMD ["/usr/share/kafka-connect-script/plugins-config.sh"]
And the bash file as this
#!/bin/bash
#script to configure kafka connect with plugins
# export CONNECT_REST_ADVERTISED_HOST_NAME=localhost
# export CONNECT_REST_PORT=8083
url=http://$CONNECT_REST_ADVERTISED_HOST_NAME:$CONNECT_REST_PORT/connectors
curl_command="curl -s -o /dev/null -w %{http_code} $url"
sleep_second=5
sleep_second_counter=0
max_seconds_to_wait=60
echo "Waiting for Kafka Connect to start listening on localhost" >> log.log
echo "HOST: $CONNECT_REST_ADVERTISED_HOST_NAME , PORT: $CONNECT_REST_PORT" >> log.log
while [[ $(eval $curl_command) -eq 000 && $sleep_second_counter -lt $max_seconds_to_wait ]]
do
echo "In" >> log.log
echo -e $date " Kafka Connect listener HTTP state: " $(eval $curl_command) " (waiting for 200) $sleep_second_counter" >> log.log
echo "Going to sleep for $sleep_second seconds" >> log.log
sleep $sleep_second
echo "Finished sleeping" >> log.log
((sleep_second_counter+=$sleep_second))
echo "Finished counter" >> log.log
done
echo "Out" >> log.log
nc -vz $CONNECT_REST_ADVERTISED_HOST_NAME $CONNECT_REST_PORT
/bin/bash
Entry point gets called correctly but CMD does not get invoked.
I also try to understand the solution given here CMD doesn't run after ENTRYPOINT in Dockerfile
but I did not understand the solution.
If someone could explain a bit more what is wrong here.
What I am trying to accomplish
I am trying to have a single docker container image which will start the kafka-connect server (ENTRYPOINT) and then via bash file (CMD) I will configure the plugins. Requirement is that the same sequence of steps gets executed everytime the containers restarts.
CMD is run after ENTRYPOINT, like parameters after a function invokation, in the same command line.
In your case you want two different commands running sequentially. Then, you may add them to a startup_script.sh whose content is:
#!/bin/bash
./etc/confluent/docker/run & # run in background not to get stuck in here
/usr/share/kafka-connect-script/plugins-config.sh # apply configuration
sleep 100000000 # to avoid the startup script to exit since that would kill the container

Can't run a shell script every 24 hours

I have written a shell script that runs some commands. I have added a logic to run this script once every 24 hours. But it runs once and then doesn't run.
The script is as below:
#!/bin/bash
while true; do
cd /home/ubuntu/;
DATE=`date '+%Y-%m-%d'`;
aws s3 cp --recursive "/home/ubuntu/" s3://bucket_name/$DATE/;
rm -r -f ./*;
# sleep 24 hours
sleep $((24 * 60 * 60))
done
Why does it not run once every 24 hours ? I do not get any errors when the script runs. The copy takes about 10 mins.
The good practice is to protect your script againt multirunning.
In this case, you can be sure that only 1 instance is running.
#!/bin/bash
LOCKFILE=/tmp/block_file
if ( set -o noclobber; echo "$$" > "$LOCKFILE") 2> /dev/null;
then
trap 'rm -f "$LOCKFILE"; exit $?' INT TERM EXIT
while true; do
cd /home/ubuntu/;
DATE=`date '+%Y-%m-%d'`;
aws s3 cp --recursive "/home/ubuntu/" s3://bucket_name/$DATE/;
rm -r -f ./*;
# sleep 24 hours
sleep $((24 * 60 * 60))
done
rm -f "$LOCKFILE"
trap - INT TERM EXIT
else
echo "Warning. Script is already running!"
echo "Block by PID $(cat $LOCKFILE) ."
exit
fi
You can run a script immune to hangups.
nohup is a UNIX utility that runs the specified command ignoring communication loss signals (SIGHUP). Thus, the script will continue to work in the background even after the user logs out.
nohup ./yourscript.sh
The created file /tmp/block_file will safe runned script against multirunning. To complete it press ctrl+c or run kill -11 pidofyourscript in terminal, in this way /tmp/block_file will be deleted.
The output of script puts on file nohup.out.
To run in background (preferred way):
nohup ./yourscript.sh &
Your script is probably killed due to inactivity, or when you exit the shell. The proper way to do this is use cron, as #Christian.K mentioned. See https://help.ubuntu.com/community/CronHowto

Script stuck during read line when script is executed remotely

I want to have one script which starts a services in another server.
I have tested that the script works as expected in the server where the server is going to run.
This is the code which starts the service and monitors the log until it is in the startup process:
pkill -f "$1"
nohup java -jar -Dspring.profiles.active=$PROFILE $1 &
tail -n 0 -f nohup.out | while read LOGLINE
do
echo $LOGLINE
[[ "${LOGLINE}" == *"$L_LOG_STRING"* ]] && pkill -P $$ tail
done
This works fine as long as I execute that from that machine.
Now I want to call that script from another server:
#!/usr/bin/env bash
DESTINATION_SERVER=$1
ssh root#$DESTINATION_SERVER /bin/bash << EOF
echo "Restarting first service..."
/usr/local/starter.sh -s parameter
echo "Restarting second service..."
/usr/local/starter.sh -s parameter2
EOF
Well, everytime I try that the script of the remote server gets stuck in the "while READ" loop. But as I said, when I execute it locally from the server works fine, and in my "not simplified script" I´m not using any system variable or similar.
Update: I just tried to simplify the code even more with the following lines in the first scenario:
pkill -f "$1"
nohup java -jar -Dspring.profiles.active=$PROFILE $1 &
tail -n 0 -f nohup.out | sed "/$L_LOG_STRING/ q"
I'd say the problem is some how in the "|" through ssh, but I still can find why.
it seems that the problem comes from not having an interactive console when you execute the ssh command, therefore the nohup command behaves strangly.
I could solve it in two ways, outputing the code to the file explicitly:
"nohup java -jar -Dspring.profiles.active=test &1 >> nohup.out &"
instead of:
"nohup java -jar -Dspring.profiles.active=test &1&"
Or changing the way I access via ssh adding the tt option (just one did not work):
ssh -tt root#$DESTINATION_SERVER /bin/bash << EOF
But this last solution could lead to other problems with some character, so unless someone suggests another solution that is my patch which makes it work.

OSX bash script does not run from cron

I have a bash script, that runs just fine from the command line. After adding it to the root users crontab (sudo crontab -e), I find it does not run. Here is the cron task:
0,15,30,45 * * * * /Users/lorenzot/Documents/scripts/restart-net.sh
Here is the script:
#!/bin/bash
echo "Net script" | logger -s >> /Library/Logs/netlog.log
# Ping twice just to be sure
/sbin/ping -c 2 8.8.8.8
/sbin/ping -c 2 8.8.8.8
if [ $? -ge 1 ]; then
echo "Network down :("
ifconfig en1 down
ifconfig en1 up
exit 1
else
echo "Network up! :)"
exit 0
fi
The script is owned by root and of course, it is executable (766) and it does exist at the correct path.
I'm not seeing an entry in the log file, but I'm not sure if this is the correct way of writing to a log file. I've tried a few different variations including:
syslog -s -k Facility com.apple.console \
Level Error \
Sender restartscript \
Message "Restart network script run"
But nothing is written to any log. Nevertheless, I would expect to see a log entry for the cron task having executed.
Any ideas?
Thanks
'logger -s` sends a copy of the message to stderr, not stdout. Also, you can pass the message as an argument, rather than via stdin. Try this:
logger -s "Net script" 2>> /Library/Logs/netlog.log

Simple daemon process in Ubuntu

I want to start a simple daemon process in Ubuntu, which will write the current time to log file every 5 seconds.
start-stop-daemon --start --user root --make-pidfile --pidfile /home/manjesh/test.pid --exec /home/manjesh/simplescript.sh
simplescript.sh
#!/bin/bash
echo $(date)" SNMP Monitoring and Log aggregator service " >> /home/manjesh/log.txt
while true
do
echo $(date) >> /home/dcae/snmp-service/log
sleep 5
done
When I execute the command it says "No such file or directory even if the file do exist"
Any help will be appreciated. Thanks.
The way I would do this is to use a cron job that triggers every minute and calls a script that writes the time every 5 seconds, like this:
Cron:
* * * * * /usr/local/bin/script >/dev/null 2>&1
Script:
#!/bin/bash
mkdir -p /home/dcae/snmp-service/
i="0"
while [ $i -lt 12 ]
do
echo $(date) >> /home/dcae/snmp-service/log
i=$[$i+1]
sleep 5
done
The problem was I had created a file in Windows and moved to Ubuntu, and there was a formatting problem
-bash: ./my_script: /bin/bash^M: bad interpreter: No such file or directory

Resources