Why does executable script behave differently from when its commands are run manually?

I am trying to add a private key to my sshagent. Running the commands

$ eval "$(ssh-agent -s)"
$ ssh-add ~/.ssh/id_rsa_personal

does the job just fine so that when I run ssh-add -l, I see the key has been added. This is also the case even without running the eval command at all (which perhaps begs the question why I would need to run it). However, if I instead create an executable file add_key.sh (using the shebang and chmod +x) and add those exact commands to it and then run it, ssh-add -l does not show the key and instead shows "The agent has no identities".

If I comment out the eval command in the script and run it, there is no problem and it properly adds the key to the agent. What is it about my script that causes ssh-add to fail adding the key, and why is that not a problem if I comment out the eval command from the script or just run the commands manually?


Solution 1:

ssh-agent -s starts a new agent; when you eval its output, you change the shell environment so that the following ssh-add adds the identity to that agent.

If you do that in a script, then when you return to the parent environment the new values of SSH_AUTH_SOCK / SSH_AGENT_PID are lost, so (although the new agent is still running), ssh-add -l can't connect to it.

When you just run ssh-agent -s without eval, it starts a new agent but just prints the new environment to standard output, so ssh-add adds the new identity to whatever agent was already running in the parent environment.