Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Running commands remotely

devsync exec -- <command>
devsync run -- <command>      # same thing

exec makes the remote feel like a local shell:

  • Same directory. Run it from src/api/ and the command runs in <remote path>/src/api/.
  • Live output. stdout and stderr are combined and streamed as the command runs.
  • Same exit code. devsync exec -- false exits with 1, so it works in scripts and && chains. Exit code 255 means devsync itself failed (for example, the remote could not be reached and retries were exhausted), just like ssh.
  • Ctrl-C stops the remote command (SIGTERM to its whole process group, then SIGKILL after 3 s). Press Ctrl-C twice to quit immediately.

Quoting

With a single argument, the string is passed to the remote shell as is, which is convenient for pipes and &&:

devsync exec -- 'cd web && npm run build | tail -20'

With several arguments, each one is quoted, exactly like running them locally:

devsync exec -- python3 -c 'print("hello world")'

Environment

Commands run in a login shell (bash -l, or sh -l if bash is missing), so ~/.profile and ~/.bash_profile are loaded. For setup that only happens in interactive shells (nvm, conda, pyenv), use prelude:

[exec]
prelude = "source ~/.nvm/nvm.sh && nvm use 20 >/dev/null"

[exec.env]
PYTHONUNBUFFERED = "1"

DEVSYNC_JOB is set to the job id inside every command.

Files generated by commands

When a command finishes, devsync copies back files it created or changed on the remote: lockfiles after npm install, generated code, migrations, build output in synced directories. Built-in excludes still apply, so node_modules never comes back.

It never overwrites your work. If you edited a file locally while a remote command was changing the same file, your version is kept and the remote one is saved next to it:

[devsync] src/schema.py was changed both locally and by the remote command; remote version saved as src/schema.py.devsync-remote

Turn pull-back off per command with --no-pull-back, or for the project with exec.pull_back = false. Files the command deletes are not deleted locally.

Without syncing first

devsync exec --no-push -- nvidia-smi