On Fri, Jul 18, 2003 at 20:20:58 -0500, Jesse Meyer wrote: > On Fri, 18 Jul 2003, Vincent Lefevre wrote: > > I wrote some zsh scripts to start ssh-agent if one is not running, > > and call ssh-add only when needed (ssh, slogin and scp are wrappers). > > The ssh-agent is killed when it isn't needed any longer (but this > > doesn't work very well with screen, perhaps unless one chooses to > > make all shells login shells). > > I'm curious - mind showing us the scripts?
I've attached the two ssh functions _call_sshagent and _call_sshadd (put them in your fpath). Use these scripts at your own risks. I tried to avoid race conditions but there may still be something I forgot. The .zlogin should contain a call to _call_sshagent. The .zlogout should contain something like: # Unregister from ssh-agent and kill it if need be. if [[ -n $SSH_AUTH_SOCK ]] then if [[ `whence -w _call_sshagent` == '_call_sshagent: function' ]] then _call_sshagent -r elif [[ -n $SSH_AGENT_PID ]] then eval `ssh-agent -k` fi fi Alternativement, if you use programs like screen, you could put the call to _call_sshagent into the .zshrc and use a trap to clean up. And wrappers to automatically call ssh-add if need be: ssh() { _call_sshadd "$@" command ssh "$@" } slogin() { _call_sshadd "$@" command slogin "$@" } scp() { _call_sshadd "$@" command scp "$@" } I also have a wrapper scripts/ssh that contains: #!/usr/bin/env zsh # Note: put this script in ~/scripts (not in path) source ~/.zshenv source ~/.zalias unset DISPLAY ssh "$@" # $Id: ssh 11 2003-06-18 19:30:04Z lefevre $ (the .zalias file contains the definitions of the above 3 functions). This is useful for some programs like cvs or svn: export CVS_RSH=$HOME/scripts/ssh export SVN_SSH=$HOME/scripts/ssh -- Vincent Lefèvre <[EMAIL PROTECTED]> - Web: <http://www.vinc17.org/> - 100% validated (X)HTML - Acorn Risc PC, Yellow Pig 17, Championnat International des Jeux Mathématiques et Logiques, TETRHEX, etc. Work: CR INRIA - computer arithmetic / SPACES project at LORIA
#!/usr/bin/env zsh # Usage: _call_sshagent [ -l | -r ] # -l: try to use an existing ssh-agent and change SSH_AUTH_SOCK # accordingly. This is useful for some non-login shells (no # possible clean-up by the .zlogout). # -r: remove the socket associated with the current process and # kill ssh-agent if there are no sockets any longer. emulate -LR zsh local link=/tmp/ssh-agent-$USER local i=4 until (ln -s /dev/null $link.lock) do if [[ $((--i)) -eq 0 ]] then echo "$0: can't lock $link" return fi sleep 2 done local dir=`readlink $link` if [[ $1 == -r ]] then if [[ -O $link && -d $dir && -O $dir && $SSH_AUTH_SOCK == $link/* ]] then local others rm -f $SSH_AUTH_SOCK unset SSH_AUTH_SOCK others=($dir/agent.*(N=)) if [[ -z $others ]] then local pid=$(<$dir/ssh-agent.pid) rm -f $link $dir/ssh-agent.pid kill -TERM $pid fi else # Inconsistent data, try to kill ssh-agent in the standard way eval `ssh-agent -k` fi elif [[ $1 == -l ]] then if [[ -O $link && -d $dir && -O $dir ]] then local old old=($link/agent.*(N=[1])) if [[ -S $old ]] then SSH_AUTH_SOCK=$old ssh-add -l >& /dev/null if [[ $? -ne 2 ]] then export SSH_AUTH_SOCK=$old unset SSH_AGENT_PID fi else echo "$0: $old isn't a socket" fi fi else if [[ -O $link && -d $dir && -O $dir ]] then local old old=($link/agent.*(N=[1])) if [[ -S $old ]] then SSH_AUTH_SOCK=$old ssh-add -l >& /dev/null if [[ $? -eq 2 ]] then # The agent could not be contacted, assume that it has died rm -f $dir/agent.*(N) $dir/ssh-agent.pid && rmdir $dir rm -f $link rm -f $link.lock $0 return fi local new=$link/agent.$$ if [[ $new == $old ]] || ln -f $old $new; then export SSH_AUTH_SOCK=$new unset SSH_AGENT_PID else echo "$0: can't link $new -> $old" fi else echo "$0: $old isn't a socket" fi elif eval `ssh-agent`; then if ln -fs $SSH_AUTH_SOCK:h $link; then local old=$SSH_AUTH_SOCK echo $SSH_AGENT_PID > $link/ssh-agent.pid rm -f $link.lock $0 && rm -f $old return else echo "$0: can't symlink $dir -> $SSH_AUTH_SOCK:h" fi else echo "$0: can't call ssh-agent" fi fi rm -f $link.lock # $Id: _call_sshagent 11 2003-06-18 19:30:04Z lefevre $
#!/usr/bin/env zsh emulate -LR zsh ssh-add -l >& /dev/null local err=$? if [[ $err -eq 2 ]] then _call_sshagent -l ssh-add -l >& /dev/null err=$? fi if [[ $err -eq 1 ]] then local file i file=() for i in id_rsa id_rsa-internal identity do [[ -f $HOME/.ssh/$i ]] && file=($file $HOME/.ssh/$i) done ssh-add $file fi true # $Id: _call_sshadd 11 2003-06-18 19:30:04Z lefevre $