Run a command in the background after SSH logout with nohup ./import.sh > import.log 2>&1 & — that covers the case where you know ahead of time the job will outlive your session. But five other situations aren't solved by that one command, from forgetting nohup after the fact to needing the process to survive not just a logout, but a reboot.
1. I know upfront the process will run long
$ clai run this script so it survives an ssh disconnect, and log the output to a file→ nohup ./import.sh > import.log 2>&1 &
nohup catches the SIGHUP a process receives when its terminal closes. & backgrounds it. The redirect isn't optional: skip it and the output lands in nohup.out in the current directory, and you'll be hunting for it later.
2. I already started it and forgot nohup
$ clai detach the process I already started, I forgot nohup→ Ctrl+Z; bg; disown -h %1
Ctrl+Z suspends it, bg resumes it in the background, disown -h drops the job from the shell's table so it won't get sent SIGHUP. It's the rescue option for when the job has been running an hour and killing it isn't on the table.
3. I need it fully detached from the session
$ clai run this command in its own session, fully detached from the terminal→ setsid --fork ./import.sh > import.log 2>&1
setsid creates a new session and process group, so the process never receives terminal signals at all. More radical than nohup: it never has a controlling terminal to lose in the first place.
4. I need to come back and check on it later
$ clai run this in the background so I can reattach later and check on it→ tmux new -d -s import './import.sh'
-d creates the session detached. Later, tmux attach -t import drops you right back into the live terminal the process is running in. It's the only option here where you can interact, not just watch.
5. I want systemd to supervise it
$ clai run this as a transient systemd service, with logs and status→ systemd-run --user --unit=import ./import.shRunning as unit: import.service; invocation ID: 74282bc256f144cdb323c19fc09452af
You get a log through journalctl --user -u import, status through systemctl --user status import, and automatic restarts if you want them. The best option for anything that needs to survive both your session and a reboot.
6. Verify the process is actually detached
$ clai check whether this process is actually detached from the terminal→ ps -o pid,ppid,sid,tty,comm -p 12345
If the TTY column shows ?, there's no controlling terminal and a disconnect can't touch it. If it shows pts/0, it's still tied to your session and will die with it.
Gotchas
nohupwithout a redirect writes to nohup.out. The file lands in the current directory, or your home directory if that's not writable. Set the path explicitly.disowndoesn't undo a SIGHUP that already went out. It only removes the job from the shell's bookkeeping. If you've already closed the terminal, it's too late.- tmux and screen don't survive a reboot. Anything that has to outlive a restart needs a systemd unit, not a multiplexer.
Related questions
nohup or tmux? nohup is fire-and-forget, output to a file. tmux is for when you need to come back to a live process and type something into it.
Why did the process die anyway after I logged out? Either it wasn't actually SIGHUP — it died with its parent — or it crashed on its own. Check the log, assuming you redirected to one.
How do I see the output of a background process that's already running? If it's going to a file, tail -f it. If it's going nowhere, you can peek with strace -p PID -e write or the descriptors in /proc/PID/fd.
See also
- Cron without the mind games
- The process that won't die
- Remote tasks in plain English: ssh, scp and rsync
CliAI won't remember to add nohup for you, but it picks the right tool for the situation before you run anything. Install it in one line.