CodingIsAwesome
CodingIsAwesome

Reputation: 1966

Please explain Linux bash exec and ssh-agent behavior

According to https://www.centos.org/docs/5/html/5.2/Deployment_Guide/s3-openssh-config-ssh-agent.html

I need to execute exec /usr/bin/ssh-agent $SHELL and as I understand it exec replaces my current shell with the program I specify.

I read http://www.openbsd.org/cgi-bin/man.cgi/OpenBSD-current/man1/ssh-agent.1?query=ssh-agent&sec=1 which states "If a commandline is given, this is executed as a sub process of the agent. When the command dies, so does the agent."

So I guess what I expect that is bash is replaced by ssh-agent, but because I specified a commandline, a new bash is executed, then the ssh-agent is executed, and the old bash is replaced.

What is really happening?

Upvotes: 2

Views: 1004

Answers (1)

rici
rici

Reputation: 241671

Not quite. What happens is exactly what the documentation says will happen.

  1. exec replaces the currently running shell with ssh-agent, so the "old bash" has now been replaced.

  2. ssh-agent sees that it has a non-option argument (the value of $SHELL), so it creates a child process and in the child process execs that command. That causes ssh-agent's child to be replaced with a new bash.

  3. ssh-agent itself now waits for its child to finish.

  4. Meanwhile, the new bash has inherited the terminal so it starts responding to your commands.

  5. Eventually, you get tired of doing whatever you were doing, and you either exit or type a control-D (end-of-file), at which the bash process terminates.

  6. ssh-agent notices that its child finished, so it, too, exits.

  7. If the original bash process had a parent, that parent now gets notified that its child has terminated. If the original bash's parent no longer exists, the init process (process 1) has become the parent. In either case, the parent -- assuming that it is well-behaved -- does something appropriate and cleans up the child's status code in order to avoid leaving a zombie.

Note that "replaced" means that the executable running in the process has been replaced. It doesn't mean that the process itself has been terminated and a new process started. After calling exec, a process is still the same process, with the same process-id and the same parent (and, for that matter, the same controlling terminal and the same open file descriptors, except for the file descriptors which the process had marked to be "closed on exec"). If the preceding sentence appears too complicated, the minimum take-away is "the same parent".

Upvotes: 3

Related Questions