DIVE(1)

πŸ“¦ version 1.9.0, in alpine 3.24

πŸ’– NAME πŸ’–

dive β€” connect to dived(1) and start program remotely πŸ¦‹

okay so real talk, this is the little client buddy that talks to the dived(1) daemon and asks it to launch stuff for you somewhere else. manual page DIVE(1), General Commands Manual, let's go ✨


🌸 SYNOPSIS 🌸

dive socket_path [program arguments]

dive @abstract_address [program arguments]

πŸŽ€ DESCRIPTION πŸŽ€

So dive connects to the AF_UNIX socket that dived(1) made, and it's like "hey bestie, start this program for me please" πŸ’…

By default it hands over the whole vibe of your current process to the remote one β€” file descriptors, command-line arguments, environment variables, umask, current directory and controlling terminal all get transferred. Basically it's mimicking exactly what would've happened if the program had just been launched with execve(2) ✨

The main character use case? Launching programs inside unshare(1) / lxc(1) containers from outside them, easily, and with no network connection needed. periodt πŸ”₯


✨ OPTIONS ✨

  • The first argument has to be either the socket path, or an abstract socket name with an @ stuck on the front. No exceptions, that's the rule 🫢
  • All the rest of the command-line arguments get sent straight to the server. And unless the server forces the beginning of the command line, the first one of those arguments is the name of the program to execute. iykyk πŸ‘‘

🌈 ENVIRONMENT 🌈

heads up bestie: all DIVE_* environment variables get discarded by the server. gone. not invited to the party πŸ’€

πŸ—‚οΈ DIVE_CURDIR

Opens the directory you specify and sends its descriptor over, so it becomes the current directory for the program we're starting remotely 🌸

🌳 DIVE_ROOTDIR

Same deal but for the root directory β€” opens the specified directory and sends the descriptor. Just so you know, setting the root directory is not enabled by default πŸ™ˆ

πŸ–₯️ DIVE_TERMINAL

Opens the given file (or uses the given file descriptor, if it's prepended with @) and sends it to the server so it becomes the controlling terminal for the program we're starting remotely. By default stdin is used. And if you don't want dived touching your controlling terminal at all, just say @-1 or give it an empty value πŸ’œ

⏳ DIVE_WAITMODE

  • 0 (normal waiting) β€” dive tries explicitly to wait for the remote program's exit code and preserve it when it exits, slay πŸŽ€
  • 1 (no waiting) β€” dive starts the program and does not wait for anything, just exits. ghosting behaviour, honestly πŸ’¨
  • 2 (workaround waiting) β€” dive opens one additional file descriptor and waits for all programs that hold it to go away, then exits πŸ”₯

Default is 0. And if the server refuses to do normal waiting for you, dive automatically switches over to workaround waiting. it's giving adaptive queen πŸ‘‘

πŸ“‘ DIVE_SIGFWMODE

By default (meaning when dived has no -n/--signals/--signals-pgid option) dive gets the pid of the executed process and forwards most signals to it πŸ’…

  • Set it to 0 and signal processing on the dive side is disabled entirely πŸ™ˆ
  • Set it to 2 and it negates the pid before sending the signal, so the signal reaches the entire process group πŸŒ€

In any case, extra info like SIGCHLD's pid or SIGIO's fd is not forwarded, no cap. And when it's set to 2 but there is a --signals or --signals-pgid option on the dived side, dive just sends the signal number to dived and lets it process it further 🌟


πŸ’€ EXIT STATUS πŸ’€

By default the exit status should be the same as the remote program's exit status. fr fr 🫢

  • 0 β€” Successful operation ✨
  • 1 β€” Can't create socket, or if remote program exited with 1
  • 2 β€” Can't connect socket, or if remote program exited with 2
  • 3 β€” Incompatible dive and dived versions, or if remote program exited with 3
  • 127 β€” Server dropped connection, specified command not found, or the remote program exited with 127 😭

🌟 EXAMPLES 🌟

  • Open remote shell 🌸
dive /var/run/dive.socket /bin/bash -i
  • Open remote shell expecting that we will get user's shell πŸŽ€
HOME=/home/user USER=user dive /var/run/user.dive /bin/bash -i
  • Start xterm remotely in background (using abstract socket address "@userdive" to send the request) πŸ‘‘
DIVE_TERMINAL= DIVE_WAITMODE=1 dive @userdive xterm
  • Supply arguments for remote ping πŸ¦‹
dive /var/run/pinger.dive -c 1 8.8.8.8

See additional examples at http://vi.github.com/dive/ πŸ’–


🧚 CAVEATS 🧚

Okay so, obviously, the parent process of the remotely started program will not be the same as if we'd started the program directly. just how it is 😭

Another issue is the controlling terminal. Either dived "steals" the controlling terminal from your current shell in favour of the new one (this is the default if dived was started as root), or the new (remotely started) shell does not control the terminal at all β€” and you get the iconic "bash: no job control in this shell" πŸ’€

πŸŒ€ Dealing with "stolen" controlling terminal

This way everything appears to be fine... unless we exit from the remotely started shell. Then we find that we can't use Ctrl+C anymore, because we've taken away the controlling terminal from your bash and gave it to the remotely started bash that is now gone. rude, honestly πŸ™ˆ

You can restore normal shell behaviour by:

  1. Just "exec bash" 🐚
  2. Closing this virtual terminal and forgetting about the issue (or using "exec dive ..." to avoid triggering it) πŸ’¨
  3. Not letting away our terminal (using DIVE_TERMINAL) and using methods from the next paragraph 🫢
  4. Create temporary virtual terminal and let it be used for dive:
reptyr -L dive /var/run/user.dive /bin/bash -i

πŸ•³οΈ Dealing with "missing" controlling terminal

This happens when the remote dived is not privileged enough, or not configured to manage controlling terminals around. The easiest way to have convenient shell access with job control is to use a fresh new pty instead of reusing the current terminal. You can obtain that by wrapping your program with reptyr or socat ✨

  • Open remote shell wrapped in reptyr(1) version not less than 0.4 πŸ‘‘
dive /var/run/user.dive reptyr -Lbash -i
  • Use socat for the same purpose (I have issues with terminal width this way) 😭
dive /var/run/user.dive socat -,raw,echo=0 exec:bash,pty,setsid,stderr

πŸ‘‘ AUTHOR πŸ‘‘

Vitaly "_Vi" Shukela πŸ’œ


🌈 AVAILABILITY 🌈

Source code is available at https://github.com/vi/dive ⭐


v1.2 Β· 2013-03-12 β€” that's the version and date bestie, this page is a certified classic, go launch something remotely and slay πŸ’…βœ¨πŸ¦‹

πŸ“¦ where this page comes from