I have an embedded console application created with Qt,C++. I use nanopi fire (FriendlyARM) for my device with Linux arch. I connect it's gpio as relay for turning on and off the lamps of my room. Also I wrote mobile app to connect the device with socket. When I run my program from putty ./SmartKeyC it runs and I can switch the lamps with my mobile app buttons and all of them are ok.
But when I put my program on start up for auto run, all of functions do their tasks with 2-3 seconds delay.
I used this link to create auto run app. this is my script:
#! /bin/sh
### BEGIN INIT INFO
# Provides: <your script name>
# Required-Start: $all
# Required-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Manage my cool stuff
### END INIT INFO
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/bin:/root
. /lib/init/vars.sh
. /lib/lsb/init-functions
. /root/
# If you need to source some other scripts, do it here
case "$1" in
start)
log_begin_msg "Starting my super cool service"
# do something
/root/SmartKeyC
log_end_msg $?
exit 0
;;
stop)
log_begin_msg "Stopping the coolest service ever unfortunately"
# do something to kill the service or cleanup or nothing
log_end_msg $?
exit 0
;;
*)
echo "Usage: /etc/init.d/<your script> {start|stop}"
exit 1
;;
esac
and after update rc I have:
root#NanoPi2-Fire:/etc# find -iname "*SmartKeyScript"
./init.d/SmartKeyScript
./rc0.d/K01SmartKeyScript
./rc1.d/K01SmartKeyScript
./rc2.d/S03SmartKeyScript
./rc3.d/S03SmartKeyScript
./rc4.d/S03SmartKeyScript
./rc5.d/S03SmartKeyScript
./rc6.d/K01SmartKeyScript
Where is the problem?
Why when I run my app in putty , everything works good , but when my app starts from auto run it has delay for each function calling?
I remove my script from rcX and put file in my rc.local like below:
Vi /etc/rc.local
#!/bin/sh -e
#
# rc.local
#
# This script is executed at the end of each multiuser runlevel.
# Make sure that the script will "exit 0" on success or any other
# value on error.
#
# In order to enable or disable this script just change the execution
# bits.
#
# By default this script does nothing.
/usr/local/bin/gen-friendlyelec-release
. /etc/friendlyelec-release
if [ ! -f /etc/firstuse ]; then
/bin/echo ${BOARD} > /etc/hostname
/bin/sed -i "s/\(127.0.1.1\s*\).*/\1${BOARD}/g" /etc/hosts
/bin/hostname ${BOARD}
/bin/echo "0" > /etc/firstuse
fi
. /usr/bin/setqt5env
/usr/bin/lcd2usb_print "CPU: {{CPU}}" "Mem: {{MEM}}" "IP: {{IP}}" "LoadAvg: {{LOADAVG}}" 2>&1 > /dev/null&
#/opt/QtE-Demo/run.sh&
/root/SmartKeyC & > /dev/tty0
exit 0
Related
I've written and compiled a daemon program in C which is meant to run in the background with root access. My program uses libcurl to make some occasional network calls. I've also written a simple init.d script to govern its startup and shutdown procedures. I would like this service to automatically start on boot, and based on what I've done I would expect it to already be doing this. However, I'm noticing an error in the logs relating to libcurl, and as a result the service is not being started automatically.
My program is located in /usr/bin/myprog and I have the following bash script located in /etc/init.d/myprog:
#!/bin/bash
### BEGIN INIT INFO
# Provides: myprog
# Required-Start: $remote_fs $network $syslog
# Required-Stop: $remote_fs $network $syslog
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: myprog
# Description: My Daemon Program
### END INIT INFO
. /lib/lsb/init-functions
SCRIPT=/usr/bin/myprog
PIDFILE=/var/run/myprog.pid
start() {
if [ -f $PIDFILE ]; then
echo "Service is already started"
return 2
else
$SCRIPT
$RETVAL="$?"
return "${RETVAL}"
fi
}
stop() {
if [ -f $PIDFILE ]; then
kill $(cat $PIDFILE)
rm -f $PIDFILE
return 0
else
echo "Service is not running"
return 2
fi
}
case "$1" in
start)
log_daemon_msg "Starting myprog" "myprog"
start
;;
stop)
log_daemon_msg "Stopping myprog" "myprog"
stop
;;
status)
status_of_proce "$SCRIPT" "myprog" && exit 0 || exit $?
;;
restart)
log_daemon_msg "Restarting myprog" "myprog"
stop
start
;;
*)
echo $"Usage: $0 {start|stop|status|restart}" >&2
exit 3
;;
esac
I then ran sudo update-rc.d myprog defaults and this created the following files:
/etc/rc0.d/K01myprog
/etc/rc1.d/K01myprog
/etc/rc2.d/K01myprog
/etc/rc3.d/S02myprog
/etc/rc4.d/S02myprog
/etc/rc5.d/S02myprog
/etc/rc6.d/K01myprog
And as far as I can tell, each of those 7 files are identical copies of the one I posted above. Based on the various tutorials and forums I've been reading, I would think this would be sufficient. However, my service does not appear to be auto-starting on boot. If I call sudo /etc/init.d/myprog start directly, then it starts up fine. But otherwise it does not appear to be launched.
I then noticed an error message in the logs which said "curl error: could not resolve host," even though the particular host it was referencing was definitely valid. So I think perhaps it's trying to launch my application before something that libcurl needs is ready, and is therefore failing to launch. Again, if I launch it manually it works fine. How can I fix this?
If DNS resolution is the point of failure then use the IP address instead. If you are unwilling to use the IP address, add the hostname and IP address to /etc/hosts.
on my raspberry pi (raspbian running) I would like to have the current desktop switched to desktop n#0 after 5 minutes of idle system (no mouse or keyboard action), through wmctrl -s 0 and xprintidle for idle time checking.
Please keep in mind I'm no expert...
I tried 2 different ways, none of them working and I was wondering which one of them is the best way to do have the job done:
bash script and crontab
I wrote a simple script which checks if xprintidle is greater than a previously set $IDLE_TIME, than it switches desktops (saved in /usr/local/bin/switchDesktop0OnIdle):
#!/bin/bash
# 5 minutes in ms
IDLE_TIME=$((5*60*1000))
# Sequence to execute when timeout triggers.
trigger_cmd() {
wmctrl -s 0
}
sleep_time=$IDLE_TIME
triggered=false
while sleep $(((sleep_time+999)/1000)); do
idle=$(xprintidle)
if [ $idle -ge $IDLE_TIME ]; then
if ! $triggered; then
trigger_cmd
triggered=true
sleep_time=$IDLE_TIME
fi
else
triggered=false
# Give 100 ms buffer to avoid frantic loops shortly before triggers.
sleep_time=$((IDLE_TIME-idle+100))
fi
done
script itself works.
Then I added it to crontab (crontab -e) for have it run every 6 minutes
*/6 * * * * * sudo /usr/local/bin/switchDesktop0OnIdle
not sure sudo is necessary or not.
Anyway It doesn't work: googling around I understood that crontab runs in its own environment with its own variables. Even though I don't remember how to access this environment (oops) I do remember that I get these 2 errors running the script in it (which correctly works in "normal" shell)
could not open display (is it important ?)
bla bla -ge error, unary operator expected or similar: basically xprintidle doesn't work in this environment a gives back an empty value
What am I missing ?
infinite-while bash script running as daemon
second method I tried to set up a script with an internal infinite-while checking if xprintidle is greater then 5 minutes. In this case desktop is switched (less elegant?). Saved also in /usr/local/bin/switchDesktop0OnIdle
#!/bin/bash
triggered=false
while :
do
if [ `xprintidle` -ge 300000 ]; then
if [ triggered == false ]
wmctrl -s 0
triggered = true
fi
else
triggered = false
fi
fi
done
again the script itself works.
I tried to create a daemon in /etc/init.d/switchDesktop0OnIdle (really not an expert here, modified an existing one)
#! /bin/sh
# /etc/init.d/switchDesktop0OnIdle
### BEGIN INIT INFO
# Provides: switchDesktop0OnIdle
# Required-Start: $all
# Required-Stop: $all
# Should-Start:
# Should-Stop:
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description:
# Description:
### END INIT INFO
DAEMON=/usr/local/bin/switchDesktop0OnIdle
NAME=switchDesktop0OnIdle
test -x $DAEMON || exit 0
case "$1" in
start)
echo -n "Starting daemon: "
start-stop-daemon --start --exec $DAEMON
echo "switchDesktop0OnIdle."
;;
stop)
echo -n "Shutting down daemon:"
start-stop-daemon --stop --oknodo --retry 30 --exec $DAEMON
echo "switchDesktop0OnIdle."
;;
restart)
echo -n "Restarting daemon: "
start-stop-daemon --stop --oknodo --retry 30 --exec $DAEMON
start-stop-daemon --start --exec $DAEMON
echo "switchDesktop0OnIdle."
;;
*)
echo "Usage: $0 {start|stop|restart}"
exit 1
esac
exit 0
I set it up
sudo update-rc.d switchDesktop0OnIdle defaults
and
sudo service switchDesktop0OnIdle start
(necessary?)
...and nothing happens...
also I don't find the process with ps -ef | grep switchDesktop0OnIdle but it seems running with sudo service switchDesktop0OnIdle status
can anyone please help?
thank you
Giuseppe
As you suspected, the issue is that when you run your scripts from init or from cron, they are not running within the GUI environment you want them to control. In principle, a Linux system can have multiple X environments running. When you are using one, there are environment variables that direct the executables you are using to the environment you are in.
There are two parts to the solution: your scripts have to know which environment they are acting on, and they have to have authorization to interact with that environment.
You almost certainly are using a DISPLAY value of ":0", so export DISPLAY=:0 at the beginning of your script will handle the first part of the problem. (It might be ":0.0", which is effectively equivalent).
Authorization is a bit more complex. X can be set up to do authorization in different ways, but the most common is to have a file .Xauthority in your home directory which contains a token that is checked by the X server. If you install a script in your own crontab, it will run under your own user id (you probabl shouldn't use sudo), so it will read the right .Xauthority file. If you run from the root crontab, or from an init script, it will run as the root user, so it will have access to everything but will still need to know where to take the token from. I think that adding export XAUTHORITY=/home/joe/.Xauthority to the script will work. (Assuming your user id is joe.)
So I am trying to write a basic script that runs a shutdown and copies some logs. To start with I made it simple so that it just prints some text into a file as it runs to help me understand a bit further. The problem is that it appears that the script is never called. Calling it manually runs as expected, but it never runs at shutdown.
#! /bin/sh
### BEGIN INIT INFO
# Provides: cpylogs
# Required-Start:
# Required-Stop:
# Should-Stop:
# Default-Start: 0 6
# Default-Stop: 0 6
# Short-Description:
# Description:
#
#
### END INIT INFO
FILE=/shutdown.txt
echo "called" > $FILE
do_stop (){
echo "in stop function" >> $FILE
}
case "$1" in
start|status)
echo "start" >> $FILE
exit 1
;;
restart|reload|force-reload)
echo "restart etc" >> $FILE
exit 1
;;
stop|"")
do_stop
echo "stop" >> $FILE
exit 1
;;
*)
echo "default" >> $FILE
exit 1
;;
esac
This is saved in /etc/init.d/ as cpylogs. Then I placed the links in /etc/rc0.d/ and /etc/rc6.d by calling sudo update-rd.d cpylogs defaults, which places the appropriate K01cpylogs in each. I have also tried doing the links manually with no luck their either. I have also tried changing the priority to K99 which still doesn't work. Any suggestions?
Further info, Running Debian 8.4, on a beaglebone
Update: I have changed it slightly # Default-Start: 2 3 5 so it runs at startup. It runs perfectly fine at startup, but still doesn't run at shutdown.
Probably better posted on superuser.com
possible solution here : unix.stackexchange.com
and here : https://www.centos.org/forums/viewtopic.php?t=14582
I'm working on a Raspberry Pi running Raspbian running a Node.js app and trying to get it to start when the Pi boots. I found a couple of examples but I can't seem to get it working. My current code is:
#! /bin/sh
# /etc/init.d/MyApp
### BEGIN INIT INFO
# Provides: MyApp.js
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Starts MyApp.js
# Description: Start / stop MyApp.js at boot / shutdown.
### END INIT INFO
# If you want a command to always run, put it here
# Carry out specific functions when asked to by the system
case "$1" in
start)
echo "Starting MyApp.js"
# run application you want to start
node /home/pi/app/MyApp/MyApp.js
;;
stop)
echo "Stopping MyApp.js"
# kill application you want to stop
killall MyApp.js
;;
*)
echo "Usage: /etc/init.d/MyApp {start|stop}"
exit 1
;;
esac
exit 0
I have this in the etc/init.d folder, ran chmod +x /etc/init.d/MyApp, I'm able to run it manually, then I run sudo update-rc.d MyApp defaults, reboot and the script never runs. I've looked at some different examples, made adjustments and still no luck.
I solved this problem by first checking where node.js was installed on RaspberryPi:
which node
This gave me :
/usr/local/bin/node
Open crontab config:
sudo crontab -e
Then in my crontab :
#reboot sudo /usr/local/bin/node <complete path to your .js app> &
Save, reboot, and problem solved !
Mohit is right, but just for clarification, you can use readlink to find the full path for your Node.js app as it will be needed later to add as a cron job.
readlink -f <<name of file >>
For instance readlink -f HAP-NodeJS/Core.js results in /home/pi/HAP-NodeJS/Core.js
You can also use which node to find the full path where node.js is installed
Next, create a new cron job using sudo crontab -e and add the following code at the very end:
#reboot sudo /usr/local/bin/node <<.js application path>> &
for instance, my code looks like this.
#reboot sudo /usr/local/bin/node /home/pi/HAP-NodeJS/Core.js &
Upon reboot (or start up) , your Node.js should run. Hope this clears things.
If you're using a prebuilt Pi release like 0.10.24, you may be experiencing a PATH issue.
You can either provide the full path to the node binary as part of the start command or make sure the PATH to the node binaries are set before /etc/init.d/MyApp is ran. I had the same issue and tried both with success. Also, the stop command as you have it may not be working.
#! /bin/sh
# /etc/init.d/test
### BEGIN INIT INFO
# Provides: test
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Example initscript
# Description: This file should be used to construct scripts to be
# placed in /etc/init.d.
### END INIT INFO
# Carry out specific functions when asked to by the system
case "$1" in
start)
echo "Starting test.js"
# run application you want to start
#node /home/pi/test.js > /home/pi/test.log
/home/pi/downloads/node-v0.10.24-linux-arm-pi/bin/node /home/pi/test.js >> /home/pi/test.log
;;
stop)
echo "Stopping test.js"
# kill application you want to stop
killall -9 node
# Not a great approach for running
# multiple node instances
;;
*)
echo "Usage: /etc/init.d/test {start|stop}"
exit 1
;;
esac
exit 0
If you'd like to do sudo node, you can add the PATH to Defaults secure_path using sudo visudo.
Also, I would recommend using something like forever to keep your process running after crashes and what not.
Good day,programmers. I have a problem. Please help.
I am creating a service, which must load automatically when Linux is being loaded. So,I copied the script into the directory /etc/rc.d/init.d or /etc/init.d/. But when I am preforming the command
chkconfig --add listOfProcesses
an error occurs:
service listOfProcesses doesn't support chkconfig
Here is the content of the script. I have found the first version in the Google and have used it as a pattern.
#!/bin/bash
# listOfProcesses Start the process which will show the list of processes
# chkconfig: 345 110 02
# description: This process shows current time and the list of processes
# processname: listOfProcesses
### BEGIN INIT INFO
# Provides:
# Required-Start:
# Required-Stop:
# Default-Start: 3 4 5
# Default-Stop: 0 1 2 6
# Short-Description: shows current time and the list of processes
# Description: This process shows current time and the list of processes
### END INIT INFO
# Source function library.
KIND="listOfProcesses"
start() {
echo -n $"Starting $KIND services: "
daemon /home/myscript
echo
}
stop() {
echo -n $"Shutting down $KIND services: "
killproc /home/myscript
echo
}
restart() {
echo -n $"Restarting $KIND services: "
killproc /home/myscript
daemon /home/myscript
echo
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
*)
echo $"Usage: $0 {start|stop|restart}"
exit 1
esac
exit $?
exit 0;
The second version was made from the cron script. I found the cron script,copied it, and changed it, so I used it as the pattern.
#!/bin/sh
#
# crond Start/Stop the cron clock daemon.
#
# chkconfig: 2345 90 60
# description: cron is a standard UNIX program that runs user-specified \
# programs at periodic scheduled times. vixie cron adds a \
# number of features to the basic UNIX cron, including better \
# security and more powerful configuration options.
### BEGIN INIT INFO
# Provides: crond crontab
# Required-Start: $local_fs $syslog
# Required-Stop: $local_fs $syslog
# Default-Start: 2345
# Default-Stop: 90
# Short-Description: run cron daemon
# Description: cron is a standard UNIX program that runs user-specified
# programs at periodic scheduled times. vixie cron adds a
# number of features to the basic UNIX cron, including better
# security and more powerful configuration options.
### END INIT INFO
rights=whoami;
root=root;
[ -f "$rights"=="$root" ] || {
echo "this programme requires root rights";
exit 1;
}
# Source function library.
. /etc/rc.d/init.d/functions
start() {
echo -n $"Starting $KIND services: ";
daemon showListOfProcesses;
}
stop() {
echo -n $"Shutting down $KIND services: ";
killproc showListOfProcesses;
}
restart() {
stop
start
}
reload() {
restart;
}
force_reload() {
# new configuration takes effect after restart
restart
}
case "$1" in
start)
start
;;
stop)
stop
;;
restart)
restart
;;
reload)
reload
;;
force-reload)
force_reload
;;
*)
echo $"Usage: $0 {start|stop|restart|reload|force-reload}"
exit 2
esac
exit $?
# Show the list of processes
function showListOfProcesses {
top > /dev/tty2;
}
But the situation hadn't changed. What is the problem? What is wrong in the script?
Look at all the scripts that chkconfig can turn on or off in /etc/rc.d/init.d, you'll notice that the top few comments are very important. See How-To manage services with chkconfig and service
#!/bin/sh
#
# crond Start/Stop the cron clock daemon.
#
# chkconfig: 2345 90 60
# description: cron is a standard UNIX program that runs user-specified \
# programs at periodic scheduled times. vixie cron adds a \
# number of features to the basic UNIX cron, including better \
# security and more powerful configuration options.
You have a script called listofprocesses but to chkconfig this script looks like crond due to the 3rd line and thus it does not find any script called listofprocesses
You'll also most certainly want to change chkconfig: 2345 90 60. Which says which run levels it should be on (in this case 2, 3, 4 and 5), what it's start order is (90) and what its kill order is (60).
You can check the service is correctly set up with chkconfig --list listofprocesses.
Just add the following line at the top:
# chkconfig: - 99 10
it should do the trick
Here is an excellent map of the elements that need to be in an init script, to implement what chkconfig and the init subsystem is doing, and what each element actually does:
http://www.tldp.org/HOWTO/HighQuality-Apps-HOWTO/boot.html
Looks like the max priority is 99, at least on CentOS 6.5, which is what I'm playing with right now.
I was also facing this issue and it was not able to call stop function during shutdown. found the solution after trying so many suggestions on net.
You need to add "touch /var/lock/subsys/" for start and rm -f /var/lock/subsys/" for stop functions in script. Stop may not work for first reboot as lock may be not available during shutdown but will start working from next reboot.
Enjoy....:)
Satya