How to run script as a Init Script ? why it cant reboot anymore

I have a script (kicks from WiFi low level clients) in infinity loop with sleep 5

#!/bin/ash
thr=-67
bantime=2000
while :
do
sleep 5
maclist=$(iw wlan0 station dump | grep Station | awk '{ print $2 }')
for mac in $maclist
	do		rssi=$(iw wlan0 station get $mac | grep "signal avg" | awk '{ print $3 }')
			if [ $rssi -lt $thr ]
				then
					ubus call hostapd.wlan0 del_client "{'addr':'$mac', 'reason':5, 'deauth':true, 'ban_time':$bantime}"		
					logger -p notice -t MY-KICK "DEVICE $mac KICKED WITH SIGANL $rssi dB !!!! "
						fi	
	done
done

I put it to /root/mykika.sh
it works if i put it in rc.local but cant reboot

# Put your custom commands here that should be executed once
# the system init finished. By default this file does nothing.
/root/mykika.sh
exit 0

all seams work but i need it to work as a service
so i read Init Scripts
then i made a file in /etc/init.d/mykika with :

#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org

START=99
STOP=1

start() {        
       /bin/ash /root/mykika.sh
       
}                 
 
stop () {
killall S99mykika
}

shutdown() {
	killall S99mykika
}

also i create simlink in /etc/rc.d/S99mykika to /etc/init.d/mykika
and i create simlink in /etc/rc.d/K1mykika to /etc/init.d/mykika

and it cant reboot untill i kill the procces

what did i wrong

I don't know a lot about it but the init.d script isn't the actual program, it registers your program with the procd service. In particular killall S99mykika makes no sense since the init.d script itself only runs once at bootup then exits. procd will take care of startup and stop and respawning if the service crashes.

For a reasonably simple example, install gpsd (a daemon which reads data from a GPS receiver and makes it available on a TCP port) and examine /etc/init.d/gpsd.

And thanks for posting your kick low signal script-- I've made a few attempts to implement the concept as it seems to really help in a festival situation.

2 Likes

well i changed it to

#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org

START=99

start(){
/bin/ash /root/mykika.sh
}

but still while the script in proccess i cant reboot (reboot command simply dont reboot)

in top this pcess look like this

1996     1 root     S     1476   3%   0% {S99mykika} /bin/sh /etc/rc.common /etc/rc.d/S99mykika boot

i use 23.05.0 rc2

How about this... get rid of the S99 in the stop/shutdown.

#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org

START=99
STOP=1

start() {        
       /bin/ash /root/mykika.sh
}                 
 
stop () {
	killall mykika
}

shutdown() {
	killall mykika
}
1 Like

Try to add an & after the command so it runs in the background.

3 Likes

If I take the gpsd init script and cut out the stuff related to configuring gpsd, it would be this:

#!/bin/sh /etc/rc.common
# Copyright (C) 2009-2011 OpenWrt.org
START=50

USE_PROCD=1
PROG=/usr/sbin/gpsd
NAME=gpsd

gpsd_instance()
{

	procd_open_instance

	procd_set_param respawn

	procd_close_instance
}

start_service()
{
	gpsd_instance
}

and that's it. Note that the script does not even launch the program directly, that is taken care of by procd_open_instance and procd_close_instance. In between the two you can do several things to customize the run, here the only one that I kept is to set the "respawn" flag so if the service crashes, it will restart. And for a service such as this which can be simply killed in order to stop it, the built-in "stop" code is sufficient without adding a custom "stop" routine.

If you set the execute permission on the script it can run directly, there is no need for /sbin/ash /path/to/script, just use /path/to/script as PROG in the file above.

An & sign is unnecessary as each service is launched to the background by procd.

1 Like

Note that as the wifi interfaces are brought down during preparation to reboot, the iw station dump at the heart of mykika is going to exit with an error due to non-existant interface. It's not clear offhand if that will be gracefully handled.

1 Like

so mykika supposed to be stopped first ? (before wifi is down)

ichange my mykika to

#!/bin/sh /etc/rc.common
# Copyright (C) 2009-2011 OpenWrt.org
START=99

USE_PROCD=1
PROG=/root/mykika.sh
NAME=mykika

mykika_instance()
{

	procd_open_instance

	procd_set_param respawn

	procd_close_instance
}

start_service()
{
	mykika_instance
}

and it seems didnt start
i realy dont understand these functions
also my script is not a programm or it doesnt matter ?

Your script will be a program if the file has execute permission (chmod +x) since it has the special first line that starts the ash shell processor.

Not necessarily but it needs to be tested that it's not going to have an infinite loop or something bad if run while wlan0 does not exist.

1 Like

So now i took advise from all of you and make file like this

#!/bin/sh /etc/rc.common
# Example script
# Copyright (C) 2007 OpenWrt.org

START=99
STOP=1

start() {        
       /bin/ash /root/mykika.sh &
}                 
 
stop () {
	killall mykika
}

shutdown() {
	killall mykika
}

and now mykika.sh working also i can reboot but when i try to stop mykika process


root@AP3:~# /etc/init.d/mykika stop
Terminated
root@AP3:~#

but it doesnt stop

How do you know it hasn't stopped? let's see what is happening (starting from a running state) -- provide all the output you see in this process:

ps | grep mykika
/etc/init.d/mykika stop
ps | grep mykika
1 Like
root@AP3:~# ps | grep mykika
 2006 root      1372 S    /bin/ash /root/mykika.sh
 2254 root      1372 S    grep mykika
root@AP3:~# /etc/init.d/mykika stop
Terminated
root@AP3:~# ps | grep mykika
 2006 root      1372 S    /bin/ash /root/mykika.sh
 2315 root      1372 S    grep mykika
root@AP3:~#

so it doesnt stop?
but notice i added & in start function

start() {        
       /bin/ash /root/mykika.sh &
}         

but where is killall anyway maybe i have to wright full path to it

in top process look like this

 2006     1 root     S     1372   2%   0% /bin/ash /root/mykika.sh

and if i remove & in start function reboot wont work anymore

and in top it looks like this

1996     1 root     S     1476   3%   0% {S99mykika} /bin/sh /etc/rc.common /etc/rc.d/S99mykika boot

also

root@AP3:~# killall mykika
killall: mykika: no process killed

kill -9 1996 works but it is by PID but PID always diffrent

Does it end up respawning, or does this kill it until it is expected to be launched again (i.e. manually or via the boot sequence)?

1 Like

i was waiting 1 minute no rewspawn then i did /etc/init.d/mykika start and it started
and ofcose PID is diffrent after manual start

idk if it helps this is my full top now

Mem: 31896K used, 25272K free, 60K shrd, 0K buff, 12596K cached
CPU:   1% usr   1% sys   0% nic  95% idle   0% io   0% irq   1% sirq
Load average: 0.06 0.21 0.14 1/55 2781
  PID  PPID USER     STAT   VSZ %VSZ %CPU COMMAND
  980   976 network  S     2780   5%   1% /usr/sbin/hostapd -s -g /var/run/hostapd/global
 1610     1 root     S     3256   6%   1% /usr/sbin/dawn
  282     2 root     IW       0   0%   1% [kworker/0:5-eve]
 2641  1862 root     R     1384   2%   0% top
 1579   925 root     S     1288   2%   0% /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p 22 -K 300 -T 3 -2 9
 1523  1507 root     S     1848   3%   0% /usr/sbin/umdns
 2478     1 root     S     1372   2%   0% /bin/ash /root/mykika.sh
  860     1 root     S     3664   6%   0% /sbin/rpcd -s /var/run/ubus/ubus.sock -t 30
 1969     1 root     S     2908   5%   0% {ntpd} /sbin/ujail -t 5 -n ntpd -U ntp -G ntp -C /etc/capabilities/ntpd.json -c -u -r /bin/ubus -r /usr/bin/env -r /usr/bin/jshn -r /usr/sbin/ntpd-hotplug -r /usr/share/libubox/jshn.
  977     1 root     S     2908   5%   0% {wpa_supplicant} /sbin/ujail -t 5 -n wpa_supplicant -U network -G network -C /etc/capabilities/wpad.json -c -- /usr/sbin/wpa_supplicant -n -s -g /var/run/wpa_supplicant/global
 1507     1 root     S     2908   5%   0% {umdns} /sbin/ujail -t 5 -n umdns -S /etc/seccomp/umdns.json -u -l -- /usr/sbin/umdns
  976     1 root     S     2908   5%   0% {hostapd} /sbin/ujail -t 5 -n hostapd -U network -G network -C /etc/capabilities/wpad.json -c -- /usr/sbin/hostapd -s -g /var/run/hostapd/global
 1272     1 root     S     2848   5%   0% /usr/sbin/uhttpd -f -h /www -r AP3 -x /cgi-bin -u /ubus -t 60 -T 30 -k 20 -A 1 -n 3 -N 100 -R -p 0.0.0.0:80 -p [::]:80 -C /etc/uhttpd.crt -K /etc/uhttpd.key -s 0.0.0.0:443 -s [::]:44
  990   977 network  S     2708   5%   0% /usr/sbin/wpa_supplicant -n -s -g /var/run/wpa_supplicant/global
 1041     1 root     S     2076   4%   0% /sbin/netifd
    1     0 root     S     1964   3%   0% /sbin/procd
 1154     1 root     S     1740   3%   0% /usr/sbin/odhcpd
  472     1 ubus     S     1500   3%   0% /sbin/ubusd
  806     1 logd     S     1480   3%   0% /sbin/logd -S 64
 1862  1579 root     S     1376   2%   0% -ash
 2081  2079 root     S     1372   2%   0% -ash
 2021  1969 ntp      S     1372   2%   0% /usr/sbin/ntpd -n -N -S /usr/sbin/ntpd-hotplug -p 0.openwrt.pool.ntp.org -p 1.openwrt.pool.ntp.org -p 2.openwrt.pool.ntp.org -p 3.openwrt.pool.ntp.org
 2781  2478 root     S     1372   2%   0% sleep 5
 2079   925 root     S     1288   2%   0% /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p 22 -K 300 -T 3 -2 9
  925     1 root     S     1268   2%   0% /usr/sbin/dropbear -F -P /var/run/dropbear.1.pid -p 22 -K 300 -T 3
  508     1 root     S     1200   2%   0% /sbin/urngd
  473     1 root     S     1056   2%   0% /sbin/askfirst /usr/libexec/login.sh
  295     2 root     IW<      0   0%   0% [kworker/0:1H-kb]
  411     2 root     SWN      0   0%   0% [jffs2_gcd_mtd5]
   10     2 root     SW       0   0%   0% [ksoftirqd/0]
   73     2 root     IW       0   0%   0% [kworker/u2:2-ev]
   72     2 root     SW       0   0%   0% [spi0]
  195     2 root     IW       0   0%   0% [kworker/u2:3-ph]
   25     2 root     SW       0   0%   0% [watchdogd]
   16     2 root     SW       0   0%   0% [kcompactd0]
    2     0 root     SW       0   0%   0% [kthreadd]
  281     2 root     IW       0   0%   0% [kworker/0:4-eve]
  598     2 root     IW<      0   0%   0% [cfg80211]
  306     2 root     SW       0   0%   0% [irq/17-keys]
  905     2 root     IW<      0   0%   0% [kworker/0:2H]
  283     2 root     IW<      0   0%   0% [ipv6_addrconf]
   34     2 root     IW<      0   0%   0% [kthrotld]
  273     2 root     IW<      0   0%   0% [mld]
  284     2 root     IW<      0   0%   0% [kstrp]
   24     2 root     IW<      0   0%   0% [blkcg_punt_bio]
   15     2 root     IW<      0   0%   0% [writeback]
   23     2 root     IW<      0   0%   0% [kblockd]
    9     2 root     SW       0   0%   0% [rcu_tasks_trace]
   11     2 root     IW<      0   0%   0% [inet_frag_wq]
    4     2 root     IW<      0   0%   0% [netns]
    3     2 root     IW<      0   0%   0% [slub_flushwq]
    8     2 root     IW<      0   0%   0% [mm_percpu_wq]
   12     2 root     SW       0   0%   0% [oom_reaper]
   26     2 root     SW       0   0%   0% [kswapd0]
^C860     2 root     SW       0   0%   0% [hwrng]
root@AP3:~#

also dont know how to make spoiler to hide big code

the manual restart and new PID all makes sense. I'm not sure why it won't kill with killall, though.

I suspect it is having trouble with the while loop, but I'm not sure why that would be the case as it should break out of the loop. But I just ran a simple test and the while is absolutely the issue. Let me think about this a bit more...

1 Like

idk maybe the problem is that it is not relise it 23.05.0 rc2
i will try to run all this on OpenWrt 22.03.5 r20134-5f15225c1e now

Ok... so I have a potential solution, but it is brute force and might cause other issues...

It is running as process "ash"

ps | grep test
18240 root      1308 S    ash ./test.sh
18243 root      1308 S    grep test

so killall ash will terminate the process.

Maybe you could find the specific process by parsing the output of ps for the ash process that corresponds with your script, then kill that with kill -9 < process ID >

The test I just ran was with 22.03.5

1 Like

Try this in your stop and shutdown sections:

kill -9 $(ps | grep mykika | grep ash | awk '{print $1;}')

1 Like

Yes of course. When run this way:

mykika is just a blob of text that gets passed to ash. It won't be named as a process.

Make the script an executable file and execute it directly. Also it's customary to leave .sh off the name.

1 Like