Client (sic) frames argv as netstrings and pipes it over ssh to a daemon (sicd) that execvp's it, so no shell re-parses the arguments. exec mode by default; opt-in sh mode for pipes/redirects/globs. Go client + daemon, Python reference daemon, design doc, quoting-hell demo, and foreground/background agent skills. Renamed from the climcp prototype. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01EWpfhDgYNA21tETDP9ueBE
2.1 KiB
name, description
| name | description |
|---|---|
| sic-bg | Run a long-running command on a remote host in the background via sic, capture its output to a log, and poll or follow it. |
sic-bg — background remote commands
For commands that outlive a single sic call (builds, downloads, soak tests).
The command is launched detached on the host, its output goes to a log file, and
you poll or follow the log with later sic calls. Built on sic --sh; no extra
binary. sic --sh delivers the launch string to the host's sh -c unchanged,
so there is only one shell to reason about.
Jobs live in ~/.sic-jobs/<name>.{log,pid,rc} on the target host.
Launch
sic --sh <host> 'mkdir -p ~/.sic-jobs && setsid sh -c '\''<command>; echo $? >~/.sic-jobs/<name>.rc'\'' >~/.sic-jobs/<name>.log 2>&1 </dev/null & echo launched <name> pid=$!'
<command> is a shell snippet (pipes and redirects allowed). setsid detaches
it from the ssh session, so it keeps running after sic returns. <name> is any
label. Example:
sic --sh boltz 'mkdir -p ~/.sic-jobs && setsid sh -c '\''make -j8 2>&1; echo $? >~/.sic-jobs/build.rc'\'' >~/.sic-jobs/build.log 2>&1 </dev/null & echo launched build pid=$!'
Follow for a bounded time
timeout caps how long the follow runs, then returns. Use this to watch
progress without blocking:
sic --sh <host> 'timeout 20 tail -f ~/.sic-jobs/<name>.log'
Snapshot the tail
No shell needed:
sic <host> tail -n 60 ~/.sic-jobs/<name>.log
Status and exit code
sic --sh <host> 'p=$(cat ~/.sic-jobs/<name>.pid 2>/dev/null); kill -0 "$p" 2>/dev/null && echo running || echo "done rc=$(cat ~/.sic-jobs/<name>.rc 2>/dev/null)"'
The .rc file holds the command's exit code once it finishes.
Stop a job
sic --sh <host> 'kill $(cat ~/.sic-jobs/<name>.pid) 2>/dev/null; echo stopped'
Notes
- One
<name>per job. Reusing a name overwrites its log. setsid ... </dev/nullis required: without it the job is killed when the ssh session closes.- Poll with the bounded
tail -for a snapshot; do not hold asiccall open for the whole job.