6

I have a systemd container running, and I can login into it with machinectl login <container>. How can I execute a command inside the container directly, i.e. without first logging in, executing the command, and then logging out?

Another way to put it is that I'm looking for the systemd equivalent of:

$ docker exec <container> <command> 

or

$ ssh <host> <command>
  • 1
    Run a sshd or something that keeps listening inside then. Or let expect get the password-input job done. – Arthur2e5 Oct 25 '15 at 9:13
  • Both suggestions sound like workarounds for something that should be possible directly. But maybe systemd just isn't there yet. A small expect script gets the job done nicely. Thanks, @Arthur2e5. – Ilari Scheinin Oct 26 '15 at 11:30
  • To be honest, I often treat a container as a real machine and I run sshd on say, port 61022 inside. – Arthur2e5 Oct 26 '15 at 12:36
  • similar question (for others searching): unix.stackexchange.com/q/302239/4808 – deceleratedcaviar Sep 21 '17 at 8:15
5

Try systemd-run:

# systemd-nspawn -D <machine-root> -b 3 --link-journal host

# systemd-run --machine <machine-name> env
Running as unit run-1356.service.

# journalctl --machine <machine-name> -u run-1356 -b -q
Oct 30 07:45:09 jessie-64 systemd[1]: Started /usr/bin/env.
Oct 30 07:45:09 jessie-64 env[37]: PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin

Excerpt from the manpage:

Use shell (see below) or systemd-run(1) with the --machine= switch to directly invoke a single command, either interactively or in the background.

(The command shell available since v225)

  • Thanks. I have v215, so don't have shell, but systemd-run works. This I find weird though: In systemd-run [OPTIONS...] COMMAND [ARGS...], if for COMMAND I use the path inside the container, I (immediately) get an error saying Failed to find executable /container/path.sh: No such file or directory. And if I give the full host path, I (through journalctl) get an error saying Failed at step EXEC spawning /var/lib/machines/<container>/container/path.sh: No such file or directory. Since mine is a shell script, I can use /bin/sh /container/path.sh, but there must be a "correct" way. – Ilari Scheinin Nov 2 '15 at 8:25
  • 1
    @IlariScheinin, that was fixed: "It's not reasonably possible to look for binaries on remote systems, we hence should not pretend we could." – Evgeny Vereshchagin Nov 2 '15 at 8:59
2

For systems without machinectl shell (e.g. systemd v219 on CentOS 7 Atomic) or during situations where machinectl login fails for any reason, you can get a shell or run commands directly using nsenter:

Example:

$ nsenter \
     --target=$(machinectl show --property Leader ipsec-libreswan | sed "s/^Leader=//") \
     --mount --uts --ipc --net --pid

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.