我想将 ssh-agent 作为系统服务运行,因此我运行一个全局 ssh-agent,可以从所有 shell 和 GUI 程序访问。在 Linux 上,我遵循这些说明作为 systemd 用户服务运行ssh-agent
,并且运行良好。ssh-agent
在启动时自动启动,并且一切都可以通过变量访问代理SSH_AUTH_SOCK
。
在 Mac 上,我在做同样的事情时遇到了麻烦。服务ssh-agent
正在运行并导出一个SSH_AUTH_SOCK
变量。该变量指向一个全局可读的套接字。但是,当我尝试使用时ssh-add
,我得到“没有这样的文件或目录”。我该如何让它工作?
$ launchctl list | grep com.openssh.ssh-agent
90829 -9 com.openssh.ssh-agent
$ pgrep ssh-agent
90829
$ launchctl print gui/501/com.openssh.ssh-agent | grep SSH_AUTH
SSH_AUTH_SOCK => /private/tmp/com.apple.launchd.PktEMOxKOJ/Listeners
secure key = SSH_AUTH_SOCK
$ file $SSH_AUTH_SOCK
/private/tmp/com.apple.launchd.PktEMOxKOJ/Listeners: socket
$ stat -f '%Sp' $SSH_AUTH_SOCK
srw-rw-rw-
$ ssh-add -l
Error connecting to agent: No such file or directory
我是这样设置SSH_AUTH_SOCK
的:.bash_profile
# linux ssh-agent
[ -z "$XDG_RUNTIME_DIR" ] && export SSH_AUTH_SOCK="$XDG_RUNTIME_DIR/ssh-agent.socket"
# mac ssh-agent (dealing with weirdly inconsistent socket path)
[ -d /private/tmp/com.apple.launchd.* ] && export SSH_AUTH_SOCK=/private/tmp/com.apple.launchd.*/Listeners
Mac 的实现感觉真的很粗糙,但我不确定如何处理它每次启动时创建不同的路径。
注意:我知道你可以ssh-agent
在 shell 中启动像这样。我发现在 Linux 上将其作为系统服务进行管理会更干净,并且想知道这种方法在 Mac 上是否可行。
答案1
我认为基本问题是 shell 在分配给变量时不会扩展通配符,因此SSH_AUTH_SOCK
不会将其设置为套接字的实际路径,而是将其设置为未扩展的通配符,该通配符不指向任何实际项目。
当您使用 测试它时stat -f '%Sp' $SSH_AUTH_SOCK
,变量引用没有双引号,因此它会在该点扩展通配符表达式。但该扩展是一个 shell 函数;ssh 在查找套接字时不会执行此操作,因此您会收到错误。尝试stat -f '%Sp' "$SSH_AUTH_SOCK"
在 shell 中查看此效果。
一个可能的解决方法是分配给一个数组(其中你能立即扩展通配符)而不是普通变量:
# mac ssh-agent (dealing with weirdly inconsistent socket path)
possible_sockets=(/private/tmp/com.apple.launchd.*/Listeners)
if [[ ${#possible_sockets[@]} -gt 0 ]]; then
echo "Found multiple possible ssh-agent sockets; you should probably investigate this." >&2
fi
for possible_socket in "${possible_sockets[@]}"; do
if [[ -e "$possible_socket" ]]; then
export SSH_AUTH_SOCK="$possible_socket"
break
fi
done
我添加了对多个匹配项的检查,因为这似乎是一种脆弱的做事方式。我还没有尝试过这个,但我很想用它来ssh-agent -a /some/predictable/path
将套接字放在一个确定的位置。