143

In order to run ssh-agent I have to use:

eval $(ssh-agent)

Why is it necessary to eval the output of ssh-agent? Why can't I just run it?

jx12345
  • 1,640
  • 1
    Who says you have to use eval? What is dictating this? A little more context would help. – 0xSheepdog Mar 15 '17 at 21:14
  • 2
    https://help.github.com/articles/generating-a-new-ssh-key-and-adding-it-to-the-ssh-agent/ – jx12345 Mar 15 '17 at 21:16
  • 16
    @0xSheepdog the man page, for a start... – jasonwryan Mar 15 '17 at 21:17
  • Looks like the use cases are documented in the man page. As to "why is it designed a certain way" ... shrug. – 0xSheepdog Mar 15 '17 at 21:22
  • 14
    Reiterating, it's not ssh-agent that is "designed this way", it's unix/linux, because ssh-agent runs in a child process of the shell. Child processes can't modify parent processes. But a function can: because it runs in the current process. So you could write a function: do_set_ssh_agent() { evalssh-agent; } and that could be run simply as: $ do_set_ssh_agent . But "programs" aren't (typically) installed as "functions" in linux/unix; instead, programs are installed as files, which, as mentioned, run in a child process. (Sourcing scripts is an exception, but ssh-agent is binary.) – michael Mar 16 '17 at 15:55
  • @michael_n, err, you can't use single backticks inside a backtick-quoted area without StackOverflow's code formatting eating them. (Triple backticks work to quote single backticks, but I'd suggest $() instead). And BTW, quotes are important -- do_set_ssh_agent() { eval "$(ssh-agent)"; } is a bit more correct, inasmuch as it means that you don't have the output of ssh-agent being string-split on contents of IFS into individual words, with those words then being formed back into a single string to be processed by eval. – Charles Duffy Mar 16 '17 at 16:14
  • ...normally, that string-splitting and then re-joining won't hurt anything in this specific use case, but that wouldn't be true (for example) if you had IFS=';', or otherwise an IFS value containing a non-whitespace character present in ssh-agent's output. – Charles Duffy Mar 16 '17 at 16:17
  • ( @CharlesDuffy chrome crashed my laptop just as i was typing that -- i'm surprised it went through. I won't delete & re-type, since it'd screw with the comment thread. My comment was only partially baked. Thanks, chrome.) – michael Mar 16 '17 at 16:36

1 Answers1

165

ssh-agent outputs the environment variables you need to have to connect to it:

shadur@proteus:~$ ssh-agent
SSH_AUTH_SOCK=/tmp/ssh-492P67qzMeGA/agent.7948; export SSH_AUTH_SOCK;
SSH_AGENT_PID=7949; export SSH_AGENT_PID;
echo Agent pid 7949;
shadur@proteus:~$ 

By calling eval you immediately load those variables into your environment.

As to why ssh-agent can't do that itself... Note the word choice. Not "won't", "can't". In Unix, a process can only modify its own environment variables, and pass them on to children. It can not modify its parent process' environment because the system won't allow it. This is pretty basic security design.

You could get around the eval by using ssh-agent utility where utility is your login shell, your window manager or whatever other thing needs to have the SSH environment variables set. This is also mentioned in the manual.

muru
  • 72,889
  • 1
    Thanks, that clearly explains what's going on and I get that, but why is it designed that way rather than designed so running it automatically adds the variables to the environment? Does it add any sort of flexibility??? – jx12345 Mar 15 '17 at 21:35
  • 4
    @jx12345 You could get around the eval by using ssh-agent utility where utility is your login shell, your window manager or whatever other thing needs to have the SSH environment variables set. This is also mentioned in the manual. No external utility can ever set variables in the calling environment. – Kusalananda Mar 15 '17 at 21:36
  • @kusalananda Correct; feel free to add that as an edit. I'm off to bed now or I'd do it myself. – Shadur-don't-feed-the-AI Mar 15 '17 at 21:37
  • 5
    @jx12345 Because it can add variables to its own environment but it can't add variables to your shell's environment because it's not your shell. – user253751 Mar 16 '17 at 02:44
  • 3
    @jx12345 To clarify: If I can add or change env variables to my parent process, I could conceivably affect the parent's parent, and so on up to PID 1. This is called "privilege escalation" and it's a really bad thing from a security standpoint. – Shadur-don't-feed-the-AI Aug 29 '17 at 14:31
  • 2
    Great explanation. But why don't I have to do this every time I create a new session, like in my .bashrc? – pitosalas Oct 14 '20 at 15:34
  • @pitosalas I'm not sure what you're asking. Check your environment variables - you might already be running an agent; I know that gnome and KDE both start one. – Shadur-don't-feed-the-AI Oct 14 '20 at 20:46