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

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

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

<背景故事>

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

ssh example.com -t 'tmux attach'

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

</背景故事>

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

答案1

当您运行时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'

大多数 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

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

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

答案2

我之前建议PermitUserEnvironment yes在您的~/.ssh/environment直到伊莱·赫迪在下面的评论中提出了更好的建议。

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

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

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

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

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

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

答案3

我自己将其添加到我的 .bash_profile 文件中:

if [ -z "$STY" ]; then
    reattach() { exec screen -A -D -RR ${1:+"$@"} ; }
fi
if [ -t 0 ]; then
    screen -wipe
    echo 'starting screen... (type Ctrl-C to abort)'
    sleep 5 && reattach
fi

这给了我一些时间来中止重新连接或创建屏幕会话。它不适用于“ssh 系统命令”格式(不调用 ~/.*profile)。设置了一个 shell 函数,以便在我中止时重新连接。

答案4

要具体讨论 UTF-8 问题,如果添加

SendEnv LANG

并且在本地端$LANG设置为类似的值en_US.UTF-8,并且远程端的 sshd 允许该SendEnv指令(使用AcceptEnvin sshd_config),另一端的 tmux 应该遵守它。我遇到这个问题有一段时间了,而且很难解决。

相关内容