tips and tricks for dealing with processes on linux
Tags: linux
Published: 2019-12-04 00:57:52

- detaching an already running process on a remote server
- start a process and leave it on the background without `screen`

## detaching an already running process on a remote server

Suppose you _sshed_ into an instance and began a long-running process but forgot to enter `screen` (terminal multiplexer) or another technique, and now want to go home. There are two "easy" ways that I do this:

For both of our techniques, suppose the command you're running is `ping google.com`

### 1) _sshing_ again, entering `screen` and reparenting the process with `reptyr`

Explanation of the programs used: 

- `screen`: a terminal multiplexer, in other words, you can start session with screen  and open any other number of windows (like if you were not using screen). The thing here is that you can exit screen and the processes that were running will remain running, even if the window is not visible or you disconnected. This guide has great examples: [https://linuxize.com/post/how-to-use-linux-screen/](https://linuxize.com/post/how-to-use-linux-screen/)
- `reptyr`: a program that takes an existing running program, which we'll call it a process, and attaches it to a new terminal. Their [README.md](https://github.com/nelhage/reptyr) is pretty good.

**Preconditions**:

- Install `reptyr` and `screen`.
    - `screen`: `sudo apt-get install screen`
    - `reptyr` : install the latest version, 0.7.0, because if otherwise, the flag needed (`-T` - steal the entire terminal session of the target) won't be present:

`wget github.com/nelhage/reptyr/archive/reptyr-0.7.0.zip && unzip reptyr-0.7.0.zip`



**Steps**:

1) ssh into the instance and run `ping google.com`

![1](https://i.imgur.com/WSsYlbe.png)

2) ssh again in another session and start screen with `screen`

![2](https://i.imgur.com/y4XCOuS.png)

3) fetch the PID of the process running on the other session: `ps aux | grep ping google.com`

![3](https://i.imgur.com/tOY3P7L.png)

4) with the PID, 20364, enter the `reptyr` folder and run `./reptyr -T 20364`

5) exit screen with a Ctrl-A, and Ctrl-D. It will display a `[detached]` message.

![4](https://i.imgur.com/iGPSGQz.png)

6) the other session that was running the program with be frozen probably, you can just exit it by closing the terminal.

7) done, if you ssh into the instance again, and do `ps aux | grep ping`. You'll see that it is running.

### 2) suspending the process (`Ctrl-Z`), resuming it on the background (`bg`) and disowning it (`disown`).

This is a technique without the need for any other programs besides the ones present by default in Linux (Ubuntu, in my case). Here we use the commands provided to control [jobs on Linux](https://www.quora.com/What-is-the-meaning-of-job-in-Linux)

The drawback of this option is that it has some downtime regarding the process execution. The interval between resuming the process on the background accounts for that.

**Steps**:

1) ssh into the instance and execute `ping google.com`

2) suspend the process with `Ctrl-Z`, which will create a job an entry on the jobs table. Check out [here](https://unix.stackexchange.com/questions/4214/what-is-the-difference-between-a-job-and-a-process) the difference between a job and a process

![5](https://i.imgur.com/IiaTIkq.png)

3) resume the job with `bg` (this will resume the last suspended job and run it on the background). Note that the stdout will still be tied to your session.

![6](https://i.imgur.com/5mYO4uo.png)

4) run `disown`, which disowns (remove the job from the jobs list in order for you to be able to exit the session and the job not stop). Notice that resuming the jobs on the background with `bg` still sends the stdout to your current session, that's why `disown` is in between the pings (this [thread](https://askubuntu.com/questions/662817/why-can-i-see-the-output-of-background-processes) explains the reason nicely)

![7](https://i.imgur.com/1CarqAZ.png)

## start a process and leave it on the background without `screen`

suppose you don't have `screen` installed nor want to install it, you can also use the default tools to achieve this. Run `nohup <command> &` and that'll do the job. Let me break down the command:

- `nohup` will intercept the [SIGHUP](https://en.wikipedia.org/wiki/SIGHUP) signal from the controlling terminal. This means that when the controlling terminal is closed, the processes running on the session won't receive this signal and thus will continue executing.
- `&` will just leave the process on the background, because `nohup` doesn't do that by default (which doesn't make much sense for me because why would someone run a program on the foreground that does not respond to SIGHUP (?))

Note: in some shells, like zsh, when you try to close the terminal, you'll still get a message `you have running jobs`. You can just ignore it and close the terminal, the job will continue running.