31

I'm working with ROS, which has been installed on my Ubuntu correctly.

To run the ROS, we have to first source /opt/ros/kinetic/setup.bash then execute roscore. If I execute roscore without source setup.bash, the command roscore can't be found.

Now, I want to execute the ROS while the system starts up.

I've read this link: https://askubuntu.com/questions/814/how-to-run-scripts-on-start-up

It seems that I only need to create a custom service file and put it into /etc/systemd/system/. But still I'm not sure what to do because I need to source setup.bash to setup some necessary environmental variables before executing roscore.

Is it possible to set environmental variables in the service file? For my need, I have to set these environmental variables not only for the execution of roscore but also for the whole system.

I have another idea, which is that I set these environmental variables in /etc/profile and write a service file only for the command roscore, will it work?

2 Answers 2

54

Normally systemd services have only a limited set of environment variables, and things in /etc/profile, /etc/profile.d and bashrc-related files are not set.

To add environment variables for a systemd service you have different possibilities.

The examples as follows assume that roscore is at /opt/ros/kinetic/bin/roscore, since systemd services must have the binary or script configured with a full path.


One possibility is to use the Environment option in your systemd service and a simple systemd service would be as follows.

[root@localhost ~]# cat /etc/systemd/system/ros.service
[Unit]
Description=ROS Kinetic
After=sshd.service

[Service]
Type=simple
Environment="One=1" "Three=3"
Environment="Two=2"
Environment="Four=4"
ExecStart=/opt/ros/kinetic/bin/roscore

[Install]
WantedBy=multi-user.target

You also can put all the environment variables into a file that can be read with the EnvironmentFile option in the systemd service.

[root@localhost ~]# cat /etc/systemd/system/ros.env
One=1
Three=3
Two=2
Four=4


[root@localhost ~]# cat /etc/systemd/system/ros.service
[Unit]
Description=ROS Kinetic
After=sshd.service

[Service]
Type=simple
EnvironmentFile=/etc/systemd/systemd/ros.env
ExecStart=/opt/ros/kinetic/bin/roscore

[Install]
WantedBy=multi-user.target

Another option would be to make a wrapper script for your ros binary and call that wrapper script from the systemd service. The script needs to be executable.  To ensure that, run

chmod 755 /opt/ros/kinetic/bin/roscore.startup

after creating that file.

[root@localhost ~]# cat /opt/ros/kinetic/bin/roscore.startup
#!/bin/bash

source /opt/ros/kinetic/setup.bash
roscore


[root@localhost ~]# cat /etc/systemd/system/ros.service
[Unit]
Description=ROS Kinetic
After=sshd.service

[Service]
Type=simple
ExecStart=/opt/ros/kinetic/bin/roscore.startup

[Install]
WantedBy=multi-user.target

Note that you need to run systemctl daemon-reload after you have edited the service file to make the changes active. To enable the service on systemboot, you have to enter systemctl enable ros.

I am not familiar with the roscore binary and it might be necessary to change Type= from simple (which is the default and normally not needed) to forking in the first two examples.


For normal logins, you could copy or symlink /opt/ros/kinetic/setup.bash to /etc/profile.d/ros.sh, which should be sourced on normal logins.

4
  • 1
    One more question: if I set some environmental variables in my service file named my_own.service, can other service files containing Requires=my_own.service inherit these environmental variables?
    – Yves
    Jul 14, 2018 at 11:57
  • 3
    No, the environment won't be inherited.
    – Thomas
    Jul 14, 2018 at 12:04
  • if I have ROS_IP and ROS_HOSTNAME insind my .bashrc file what could be a good solution? I think your answer would not work. Thanks in advance.
    – Micha93
    Jan 24, 2021 at 21:34
  • that's a terrible idea, why would anyone put .env file inside of the systemd folder. Just put them into /etc/service-name/service.conf or something like that. Systemd folder is preserved for systemd files only for god sake. Aug 15 at 11:55
4

you can try with this

[Unit]
Description=Run command with source /opt/ros/kinetic/setup.bash

[Service]
Type=simple
ExecStart=/bin/bash -c 'source /opt/ros/kinetic/setup.bash && /opt/ros/kinetic/bin/roscore'

[Install]
WantedBy=multi-user.target
2
  • 4
    We prefer answers that have at least a few sentences of non-code text (and “you can try with this” doesn’t count).  While it may be obvious, you should mention that this solution doesn’t set the ROS-related environment variables for the whole system, which was part of the question. Sep 15, 2020 at 4:09
  • 1
    @Scott but this is actually an answer :-P Sep 28, 2021 at 14:50

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .