3

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.

  • At a fish prompt, type type setenv – glenn jackman Sep 3 '15 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 '15 at 17:11
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

| improve this answer | |
  • 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 '15 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) – glenn jackman Sep 3 '15 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 '15 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. – glenn jackman Sep 4 '15 at 15:08
  • This works on cygwin :P – Zardoz89 Jul 6 '16 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.

| improve this answer | |
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
| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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