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


24

我开始问这个问题,但是在我打开它时就回答了。我将发布此问题,并提出我的解决方案,并留给其他可能的解决方案。

<背景故事>

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

ssh example.com -t 'tmux attach'

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

</背景故事>

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

Answers:


13

当您运行时ssh example.com,ssh守护程序会为您启动一个登录shell,然后登录shell读取您的登录shell ~/.profile(或~/.bash_profileor ~/.zprofile或or ~/.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传递环境变量的更多信息。


我不使用的原因ssh example.com -t 'tmux attach'不是因为它在加载环境时出现问题,而是因为我在使用UTF-8字符显示时遇到了问题。以常规方式连接时不存在此问题。这就是为什么此问题与通过SSH连接后立即运行脚本有关。
connrs 2011年

我爱您的解决方案。优雅
connrs 2011年

@connrs:即使您运行UTF-8,您是否也遇到问题.profile?我认为该问题是由于您的/etc/profile.profile固定的目标计算机上的语言环境设置不正确引起的。语言环境问题可能可以通过更多信息解决。
吉尔(Gilles)“所以,别再邪恶了”,

我想回到办公室进行测试。您是完全正确的,采购/ etc / profile确实会触发适当的行为。您现在实际上已经解决了促使我提出这个更笼统的问题的问题

6

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

打开您的.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文件,但是我想保持我的dotfile整洁,并且将其分开,以便可以在其他计算机上使用它。

用适合自己的问题替换问题,然后替换MY_SSH_CONNECTION="yes" tmux attach为您希望运行的所有内容。

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


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

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函数设置为重新连接。


大!我设法通过改写bashrc来解决这个问题,然后在每个新的屏幕窗口中-更改为.profile时都可以正常工作。
雨果

0

您可以考虑跑步

ssh remotehost -t screen -DR

并在那里运行您的终端会话。然后,您可以分离(^A^D)并稍后重新连接(也可以从其他客户端重新连接)。当屏幕保持完整的交互式终端会话时,它将消除非交互式初始化的问题(也可以选择登录外壳程序man screen(1)或^A?


如我的问题所述,我使用的是tmux而不是GNU屏幕来管理会话。并且在加载时,-t 'tmux attach'我遇到了vim正常不存在的问题。这就是为什么真正的问题是关于在ssh connect而不是屏幕/会话管理上运行脚本的原因。抱歉,我的问题不够清楚
敬请关注2011年

很抱歉,您提到了tmux,但这对我没有任何意义。感谢您提及新工具!
sehe 2011年

0

具体说来要解决UTF-8问题,如果您添加

SendEnv LANG

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


0

如果您希望它在每次连接时都运行,则只需将其添加tmux attach~/.profile远程计算机的底部即可。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.