Community
cancel
Showing results for 
Search instead for 
Did you mean: 
aedwa2
New Contributor III
3,777 Views

How do I run a script on startup on Edison?

I have two things I need to do on power up. One is to set up Bluetooth. The other is to launch my program. This is a headless machine and it just runs its task continuously until the power is removed.

I thought that /etc/rc.local if set executable would execute. Much of the documentation I find does not work as many normal commands are not on Edison.

This is the rc.local script I tried:

# !/bin/bash

/usr/bin/rfkill unblock bluetooth

I set permissions to 755

The reason I thought this would work is this file in /lib/systemd/system/rc-local.service

# systemd-rc-local-generator if /etc/rc.local is executable.

[Unit]

Description=/etc/rc.local Compatibility

ConditionFileIsExecutable=/etc/rc.local

After=network.target

[Service]

Type=forking

ExecStart=/etc/rc.local start

TimeoutSec=0

RemainAfterExit=yes

SysVStartPriority=99

I have no idea regarding the second task of starting a program that never exits.

52 Replies
Carlos_M_Intel
Employee
235 Views

Hi allene;

Have you tried with this http://stephaniemoyerman.com/?p=41 link, I think it will be helpful, let me know if works using that procedure.

Regards;

CMata

PMart13
Valued Contributor II
235 Views

allene,

I am not sure if your script needs to have the extension of .sh to be picked up by the rc daemon

you would also need to put your script.sh in the /etc/init,d directory which is not existent on a factory yocto image

after you set script.sh to an executable with chmod +x /etc/init.d/script.sh then you need to update the rc daemon using

update-rc.d script.sh defaults

aedwa2
New Contributor III
235 Views

That worked, thank you. To run the program, like the python script simple-agent, I just added the & character to run it in the background. That allowed my program to run after it.

I now have a system that will boot up and run and that I can Bluetooth pair from the phone without interaction on the Edison.

aedwa2
New Contributor III
235 Views

The script runs so that is nice, but it runs before Bluetooth is started so the script doesn't work. I need a place for my start up script that runs last, after Bluetooth is started.

Matthias_H_Intel
Employee
235 Views

allene wrote:

The script runs so that is nice, but it runs before Bluetooth is started so the script doesn't work. I need a place for my start up script that runs last, after Bluetooth is started.

make it dependend on "bluetooth.service"?

aedwa2
New Contributor III
235 Views

>make it dependent on "bluetooth.service"?

Can you please explain how to do that? I can only find examples using a commands that are not on Edison like service or status.

PMart13
Valued Contributor II
235 Views

Edison uses systemd or connman to execute the startup

In a systemd style configuration file you can state conditions such as After=bluetooth.service in your myservice.service

a lot of the .service files are found in the /lib/systemd and directory and subdirectories.

.service files are loaded / unloaded with systemctl start/stop myservice.service

you can have them persist or not persist with systemctl enable/disable myservice.service

to check any errors or status systemctl status myservice.service.

aedwa2
New Contributor III
235 Views

The initial answers above directed me to create a startup script in /etc/init.d, which I did. You are suggesting with the After=bluetooth. That doesn't look like a shell command but rather a statement in another way of doing this. Perhaps it would help to show my script, the one that runs but errors out. 'Would that method be appropriate for my task? Am I missing that it is different than what was suggested in the first two replies? The point is, my script works just fine if I run it manually. Just doesn't run in init.c

# !/bin/sh

/usr/sbin/rfkill unblock bluetooth

/usr/bin/hciconfig hci0 up

/usr/bin/hciconfig hci0 piscan

/home/root/simpleAgent/simple-agent &

/usr/bin/hciconfig hic0 sspmode 0

/home/root/nmea_thread

The final line is my program.

PMart13
Valued Contributor II
235 Views

allene,,

I think when mhahn was saying setting your dependencies so that it loads after your Bluetooth he was referring to service files.

If the timing of your script.sh is not loading in the sequence you need, you may have to change to .service files to have your script.sh to load after your conditions (bluetooth)

To have this myd.service example persist run systemctl enable myd.service

Name your script /home/root/myd.sh

an example of a service file (your previous question how to set it) placed in /lib/systemd/system/myd.service

--- myd.service---

[Unit]

 

Description=My Daemon

 

After=bluetooth.target

 

Before=systemd-user-sessions.service

[Service]

 

Type=simple

 

RemainAfterExit=true

 

ExecStart=/home/root/myd.sh

 

Environment="HOME=/home/root"

 

WorkingDirectory=/home/root/

[Install]

 

WantedBy=multi-user.target

----myd.service ---

Yocto doesn't actually use the init.d start up sequence, if you are using ubilinux - my answer might not apply.

It might not be the most favorite answer, getting scripts to start in a multi-tasking os can be tricky

aedwa2
New Contributor III
235 Views

I am using stock Edison image. I had to create the init.d directory and execute the "update-rc.d myscript.sh defaults". It is all set up correctly and runs, just too early. I put a delay in my script and that works, just seems like there should be a cleaner way. I am apprehensive about running this series of commands as a service and your saying it can be tricky is not encouraging.

 

It would be nice if the script I have could have a conditional wait what checks the loading of the bluetooth service.

 

 

PMart13
Valued Contributor II
235 Views

allene Acknowledged.

I am not sure what your understanding is so far in this process. The rc-local.service that you have pointed out at the beginning of the thread will run commands that are in the /etc/rc-local directories ( I believe there are several rc.d 0 through 7 that are created, though I may be off a bit)

And then, they will only run if the have the execute permission set (a textfile will not run). So how do non existent files end up in the rc-local directory?

When you create a script in the /etc/init.d directory and chmod +x your_script.sh, you would run the update-rc your_script.sh defaults, which then places a link to your script it the various run-levels directories for rc-local (I can not recall just off the top of my head). At that point that rc-local now has a link to your script for the default run-levels, as you enter run-level 5, the rc-local.service will now call your_script.sh

Until the update-rc is called, you are right - the file doesn't exist. Afterwards - it does.

My suggestion for another service file (since your script is actually being called indirectly by rc-local) might allow you to put your Bluetooth commands in one, and put your program in another, thus maybe being able to have your program state after=rc-local ... or what not.

aedwa2
New Contributor III
235 Views

I understood all that and set it up as you said. Here is a post I made to Stack overflow that explains more of what I did. Just to be clear, the scrip works perfectly manually and runs on boot after it is set up. It just generates errors and does not work. It runs but doesn't do what it should. Specifically, hci0 is not found because it has not been started.

================================================

I have a script that initializes my bluetooth setup on an Intel Edison. It allows pairing and connecting to this headless machine running Yocto Poky Linux. It was suggested that I put the startup script in /etc/init.d and run update-rc.d myscript.sh defaults. The script ran but it didn't work (generated boot errors saying bluetooth device not found) because Bluetooth had not started yet. I did some reasearch and after removing my links I did update-rc.d myscript.sh defaults 99 which was claimed to run the script last but it did't make any differrence -- it still ran in the same place in the boot sequence. I verified that the links had S99 on them so it seemed like they were set up correctly. There is another post on SO asking a similar question but that was a Ubuntu system where mine is Poky Linux. That solution suggested putting the startup script in a directory that does not exist on my system. There were other suggestions, putting it in rc.local, which I did and got the same result, it runs before Bluetooth is initialized.

Here is my script. My program is called nmea_thread and is run last. Everything else is initializing Bluetooth.

# !/bin/sh /usr/sbin/rfkill unblock bluetooth

/usr/bin/hciconfig hci0 up

/usr/bin/hciconfig hci0 piscan

/usr/bin/hciconfig hic0 sspmode 0

/home/root/simpleAgent/simple-agent &

/home/root/nmea_thread

PMart13
Valued Contributor II
235 Views

I am not a Bluetooth expert, but we will work this out. hci0 and simple-agent is the Bluetooth setup and pairing and nmea_thread is your program.

You have it at S99 - the last possible one to load from rc-local.service when sorted.

If you remove nmea_thread from your script it the /etc/init.d directory - the remainder of Bluetooth would boot, setting up and paring your Bluetooth (provided there are no delays).

I would maybe try taking the above .service example and modifying to:

[Unit]

Description=NMEA

After=rc-local.service

Before=systemd-user-sessions.service

[Service]

 

Type=simple

 

RemainAfterExit=true

 

ExecStart=/home/root/nmea_thread

 

Environment="HOME=/home/root"

 

WorkingDirectory=/home/root/

[Install]

 

WantedBy=multi-user.target

place the ./service example file in /lib/systemd/system/nmea.service and run the command systemctl enable nmea.service.

On reboot it would then be called after all your bluetooth setup in the script inside /etc/init.d and before users need to login. -- Headless.

check journalctl for any errors and systemctl status nmea

If someone else that is using bluetooth can confirm the usage of systemctl enable bluetooth, some of the commands being tried may be being duplicated or conflicting.

aedwa2
New Contributor III
235 Views

This looks promissing but just to be clear, setting to S99 didn't do anything. It still ran in about the same place although I can't say that precisely. More like, about 1/3 of the way up regardless of S20 or S99. Also you are saying After=rc-local.service. Does that put it after Bluetooth?

PMart13
Valued Contributor II
235 Views

And just be clear, S20 or S99 doesn't show a difference as you only have 1 or so scripts in your /etc/init.d directory - if you had 50 or so you'd see how the number sets an launch order for them.

in that nmea.service above, the line stating After-rc-local.service requests systemd to launch your nmea sometime after rc-local.service (the part that launches /etc/init.d) is launched.

The final part was I was asking for others that have Bluetooth running on their systems to comment if there maybe a systemctl bluetooth.service that already accomplishes some of.

aedwa2
New Contributor III
235 Views

OK , good. Hope to hear from someone.

Matthias_H_Intel
Employee
235 Views

As pointed out: the bootup process is controlled by systemd rather than the older sysV init. I strongly recommend to use a systemd service file which has its dependency set on bluetooth.service as indicated earlier. Moreover: using connman (systemctl enable connman && systemctl start connman) and switching bluetooth on there (connmanctl enable bluetooth) should make Bluetooth persistent so you shouldn't have to call rfkill at all.

aedwa2
New Contributor III
235 Views

Connmanctl is not on the system. Are you sure that the rest of the stuff you are talking about it on Edison? Specifically that bluetooth.service will work without the service command being on the system. This sure seems like a difficult way to do what should be a simple task: run a script last.

Matthias_H_Intel
Employee
235 Views

if you use the standard Yocto connmanctl is on the system - at least after enabling connman

aedwa2
New Contributor III
104 Views

I have the standard Edison image. Nothing extra installed. I have flashed it several times to get rid of the log memory bug so I am quite sure nothing else is loaded.

In trying to find how to enable connman by reading the man page, it referred to another command that is loaded. I notice that this command "systemctl is-enabled bluetooth" will return "enabled" when bluetooth is running. So I tried to use that to modify my script and it sort of works.

# !/bin/sh

while(systemctl is-enabled bluetooth != 'enabled')

do

sleep 1

done

/usr/sbin/rfkill unblock bluetooth

/usr/bin/hciconfig hci0 up

/usr/bin/hciconfig hci0 piscan

/home/root/simpleAgent/simple-agent &

sleep 2

/usr/bin/hciconfig hci0 sspmode 0

/home/root/nmea3 > /home/root/file

I say sort of because I am a little miffed as to why the sleep 2 was necessary and it is troubling that perhaps it won't work some time. With just sleep 1 there the sspmode 0 command did not work. It did not error the script, but sspmode was enabled when I exited.

The other troubling thing is that the boot process "Failed to start Hostname Service" The only problem I am seeing with that is slow logins over WiFi but that could be something else.

And forgive me if my questions are dumb. I ran a Linux web server at home for many years but that was on Red Hat 4 and the MythTV Linux server I built was on Ubuntu 8.04 so what little I used to know is just a distant memory and is coming back slowly.

Reply