通过 SSH 连接后如何立即运行脚本?

con*_*nrs 24 ssh tmux environment-variables

我开始问这个问题,但在我打开它时回答了它。我将发布这个问题,跟进我的解决方案,并将其留给其他潜在的解决方案。

<背景故事>

我是 tmux 和 vim 用户。我喜欢远程 vim 工作,因为我不必担心 Ubuntu 开发机器在 Flash 电影给我内核恐慌时卡住。运行 tmux 意味着在我重新启动后打开的文件正在等待我,我可以从我离开的地方继续。当我像这样连接时,在 tmux 会话中运行 vim 时遇到了问题:

ssh example.com -t 'tmux attach'
Run Code Online (Sandbox Code Playgroud)

UTF-8 问题突然出现,在正常脱壳时不会出现,只是手动附加到 tmux 会话。

</背景故事>

所以我想要一种在 ssh 登录时启动一些东西的可重用方法,这不会影响我在我的.zshrc(或者你的,.bashrc如果你仍然使用 bash)中配置的任何其他东西,这些东西可能是我的开发环境所需要的,这不会当我偶尔在这台机器上本地工作时出现。

Gil*_*il' 14

当您运行时ssh example.com,ssh 守护进程会为您启动一个登录 shell,并且登录 shell 会读取您的~/.profile(或~/.bash_profile~/.zprofile~/.login取决于您的登录 shell)。当您指定要远程运行的命令(使用或不使用-t)时,ssh 守护程序会启动一个普通的 shell,因此.profile不会读取您的命令。补救:

ssh example.com -t '. /etc/profile; . ~/.profile; tmux attach'
Run Code Online (Sandbox Code Playgroud)

大多数 ssh 守护进程被配置为拒绝传输环境变量,除了LC_*. 如果 ssh 守护进程example.com允许它,你可以滥用自定义LC_*变量来自动启动 tmux——把它放在你的~/.profile

if [ -n "$LC_tmux_session" ] && tmux has -t "$LC_tmux_session"; then
  exec tmux attach -t "$LC_tmux_session"
elif [ -n "${LC_tmux_session+1}" ] && tmux has; then
  exec tmux attach
fi
Run Code Online (Sandbox Code Playgroud)

然后使用LC_tmux_session= ssh example.com或登录LC_tmux_session=session_name ssh example.com

这个答案有更多关于通过 ssh 传递环境变量的信息。


con*_*nrs 6

我之前建议PermitUserEnvironment yes在您的环境中设置和添加一个环境变量,~/.ssh/environment直到Eli Heady在下面的评论中提出更好的建议。

打开你的.zlogin(bash: .bash_profileetc.) 并输入以下内容:

if [[ "$SSH_CONNECTION" != "" && "$MY_SSH_CONNECTION" != "yes" ]]; then
    while true; do
        echo -n "Do you want to attach to a tmux session? [y/n]"
        read yn
        case $yn in
            [Yy]* ) MY_SSH_CONNECTION="yes" tmux attach; break;;
            [Nn]* ) break;;
            * ) echo "Please answer y/n";;
        esac
    done
fi
Run Code Online (Sandbox Code Playgroud)

灵感来自:如何在 Linux shell 脚本中提示输入?

请注意,我已经使用了该.zlogin文件,但您可以使用您的.zshrc文件,但我喜欢保持我的点文件整洁并将其分开,以便我可以在其他机器上使用它。

用适合自己的问题替换问题,并替换MY_SSH_CONNECTION="yes" tmux attach为您当时希望运行的任何内容。

请注意脚本MY_SSH_CONNECTION="yes"tmux attach将其传递给 tmux之前是如何设置的,因为它还将打开一个 shell,该 shell 将访问与上面完全相同的脚本并防止任何递归。

  • 由于潜在的安全隐患,在某些环境中无法使用 PermitUserEnvironment。SSH 设置了 $SSH_CONNECTION 变量,它可以用来代替 .zlogin 中的 $SSH_LOGIN,从而无需使用 ~/.ssh/environment。像`if [[ "$SSH_CONNECTION" != "" ]]` 应该这样做。 (2认同)