4

When I want to start (or restart) ssh-agent, it gives me a few commands that I should run by doing eval $(ssh-agent). Of course this fails for fish, since it gives syntax for bash or csh.

The commands look like:

SSH_AUTH_SOCK=/var/folders/v4/c116f_790t7g58lh3jbr7_vm0000gq/T//ssh-L95xhmGl9FZo/agent.36846; export SSH_AUTH_SOCK;
SSH_AGENT_PID=36847; export SSH_AGENT_PID;
echo Agent pid 36847;

or for csh:

setenv SSH_AUTH_SOCK /var/folders/v4/c116f_790t7g58lh3jbr7_vm0000gq/T//ssh-Tf8etHZfP9k3/agent.36873;
setenv SSH_AGENT_PID 36874;
echo Agent pid 36874;

The csh version runs without complaint when I do eval (ssh-agent -c), and then echo $SSH_AGENT_PID $SSH_AUTH_SOCK gives the expected output. However, new shells do not keep those variables. What does setenv do? clearly it sets variables somehow, but it's nowhere in the documentation. If I start a new terminal, the variables are lost, so I'm not sure they're exported?

I just found that setenv is a fish function, with definition set -gx, so I suppose it sets the variable as a global variable and exports it. I don't have a good understanding of the variable scope, so is the the appropriate thing for the ssh-agent variables?

For context, I'm doing this based on instructions at github. I've been using an ssh key for github for years and never did the ssh-agent or ssh-add thing, but I noticed it while setting up on a new computer. It also seems that os x is running ssh-agent on its own (or something else I set up long in the past), because there exists $SSH_AUTH_SOCK already. So maybe running this is not important? ssh-add does run without complaint even without running ssh-agent.

2
  • At a fish prompt, type type setenv Sep 3, 2015 at 17:10
  • Thanks @glenn, I discovered that with functions setenv, see my edit. type is nice, though. It seems to be some combination of which and functions.
    – askewchan
    Sep 3, 2015 at 17:11

3 Answers 3

3

I wrote this a while ago:

function ssh_agent --description 'launch the ssh-agent and add the id_rsa identity'
    if begin
            set -q SSH_AGENT_PID
            and kill -0 $SSH_AGENT_PID
            and grep -q '^ssh-agent' /proc/$SSH_AGENT_PID/cmdline
    end
        echo "ssh-agent running on pid $SSH_AGENT_PID"
    else
        eval (command ssh-agent -c | sed 's/^setenv/set -Ux/')
    end
    set -l identity $HOME/.ssh/id_rsa
    set -l fingerprint (ssh-keygen -lf $identity | awk '{print $2}')
    ssh-add -l | grep -q $fingerprint
        or ssh-add $identity
end

To emphasize, I use create universal variables from the ssh-agent output, and setenv will create global variables

5
  • What is kill -0? I don't see that in the man page. And /proc doesn't exist on my system (maybe os x doens't have it).
    – askewchan
    Sep 3, 2015 at 17:48
  • kill -0 pid returns successfully if that pid is a running process, error otherwise. I use /proc to check that a running pid is actually a ssh-agent process: there are other ways to do this (pgrep, parsing ps output) Sep 3, 2015 at 18:12
  • This works on mac os x if I change the /proc/ line to: and ps -p $SSH_AGENT_PID | grep -q 'ssh-agent'
    – askewchan
    Sep 3, 2015 at 22:34
  • 1
    I recomment changing the grep pattern to '[s]sh-agent' so you don't accidentally match the grep command itself in the ps output. Sep 4, 2015 at 15:08
  • This works on cygwin :P
    – Zardoz89
    Jul 6, 2016 at 10:11
1

This works for me on FreeBSD 10.2. Add the following to ~/.config/fish/config.fish:

if begin; test -z (command pgrep ssh-agent); and not test -S $SSH_AUTH_SOCK; end
    eval (command ssh-agent -c | sed -E 's/^setenv (.+);$/set \1; set -Ux \1;/')
end

The first set, without the -Ux, sets the environment variables for the first terminal that launches ssh-agent. The second set, with -Ux, sets the environment variables for all other terminals.

1

Consider to use

fish_ssh_agent

Utility functions to start your ssh agent when using fish shell. You will only need to run ssh-add and type your password once, after the running ssh_agent should do the work for you. Need to run once, environment variables shared between sessions.

Installation
wget https://gitlab.com/kyb/fish_ssh_agent/raw/master/functions/fish_ssh_agent.fish -P ~/.config/fish/functions/
Usage
fish_ssh_agent

SOURCE

Put this to ~/.config/fish/functions/fish_ssh_agent.fish

function __ssh_agent_is_started -d "check if ssh agent is already started"
   if begin; test -f $SSH_ENV; and test -z "$SSH_AGENT_PID"; end
      source $SSH_ENV > /dev/null
   end

   if test -z "$SSH_AGENT_PID"
      return 1
   end

   ps -ef | grep $SSH_AGENT_PID | grep -v grep | grep -q ssh-agent
   #pgrep ssh-agent
   return $status
end


function __ssh_agent_start -d "start a new ssh agent"
   ssh-agent -c | sed 's/^echo/#echo/' > $SSH_ENV
   chmod 600 $SSH_ENV
   source $SSH_ENV > /dev/null
   true  # suppress errors from setenv, i.e. set -gx
end


function fish_ssh_agent --description "Start ssh-agent if not started yet, or uses already started ssh-agent."
   if test -z "$SSH_ENV"
      set -xg SSH_ENV $HOME/.ssh/environment
   end

   if not __ssh_agent_is_started
      __ssh_agent_start
   end
end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.