32

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

55

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/ros/roscore.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/ros/roscore.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.

5
  • 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
    Commented Jul 14, 2018 at 11:57
  • 3
    No, the environment won't be inherited.
    – Thomas
    Commented 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
    Commented Jan 24, 2021 at 21:34
  • 1
    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. Commented Aug 15, 2023 at 11:55
  • I must agree with @MertÇELEN and updated the path accordingly. Thanks.
    – Thomas
    Commented Nov 4, 2023 at 12:04
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. Commented Sep 15, 2020 at 4:09
  • 1
    @Scott but this is actually an answer :-P Commented Sep 28, 2021 at 14:50

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.