我经常必须登录到几个服务器中的一个,然后进入这些机器上的几个目录中的一个。目前我做的事情是这样的:

localhost ~]$ ssh somehost

Welcome to somehost!

somehost ~]$ cd /some/directory/somewhere/named/Foo
somehost Foo]$ 

我有脚本,可以确定哪个主机和哪个目录,我需要进入,但我不知道如何做到这一点:

localhost ~]$ go_to_dir Foo

Welcome to somehost!

somehost Foo]$

有没有简单、聪明或任何方法可以做到这一点?


当前回答

不幸的是,建议的解决方案(@rogeriopvl)在使用多个跳时不起作用,所以我找到了另一个。 在远程机器上添加到~/。Bashrc:

[ "x$CDTO" != "x" ] && cd $CDTO

这允许你在命令行上以这样的方式指定所需的目标目录:

ssh -t host1 ssh -t host2 "CDTO=/desired_directory exec bash --login"

当然,这种方式也可以用于单跳。

这个解决方案可以与@redseven的有用提示相结合,以获得更大的灵活性(如果没有$CDTO,则转到保存目录,如果存在的话)。

其他回答

不幸的是,建议的解决方案(@rogeriopvl)在使用多个跳时不起作用,所以我找到了另一个。 在远程机器上添加到~/。Bashrc:

[ "x$CDTO" != "x" ] && cd $CDTO

这允许你在命令行上以这样的方式指定所需的目标目录:

ssh -t host1 ssh -t host2 "CDTO=/desired_directory exec bash --login"

当然,这种方式也可以用于单跳。

这个解决方案可以与@redseven的有用提示相结合,以获得更大的灵活性(如果没有$CDTO,则转到保存目录,如果存在的话)。

您可以执行以下操作:

ssh -t xxx.xxx.xxx.xxx "cd /directory_wanted ; bash --login"

这样,您将在directory_wanted上获得一个登录shell。


解释

-t强制伪终端分配。这可以用于在远程机器上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。 多个-t选项强制分配tty,即使ssh没有本地tty。

如果不使用-t,则不会出现提示。 如果你不加;Bash则连接将被关闭,并将控制权返回到本地计算机 如果你不添加bash——login,那么它将不会使用你的配置,因为它不是一个登录shell

SSH本身提供了一种通信手段,它不知道任何关于目录的信息。因为您可以指定要执行哪个远程命令(默认情况下,这是您的shell),所以我将从这里开始。

在我非常具体的情况下,我只是想在一个远程主机上执行一个命令,在一个Jenkins从机的特定目录中:

ssh myuser@mydomain
cd /home/myuser/somedir 
./commandThatMustBeRunInside_somedir
exit

但是我的机器不能执行ssh(我想它不能分配伪tty),并让我给出以下错误:

Pseudo-terminal will not be allocated because stdin is not a terminal

我可以绕过这个问题,将“cd to dir + my command”作为ssh命令的参数(不必分配伪终端),并通过传递选项-T显式地告诉ssh命令我不需要分配伪终端。

ssh -T myuser@mydomain "cd /home/myuser/somedir; ./commandThatMustBeRunInside_somedir"

我的首选方法是使用SSH配置文件(如下所述),但根据您的用途,有一些可能的解决方案。

命令行参数

我认为这种方法的最佳答案是christianbundy对公认答案的回答:

ssh -t example.com "cd /foo/bar; exec \$SHELL -l"

使用双引号将允许您使用本地机器中的变量,除非它们被转义(如此处的$SHELL)。或者,你可以使用单引号,你使用的所有变量都将是来自目标机器的变量:

ssh -t example.com 'cd /foo/bar; exec $SHELL -l'

Bash函数

您可以通过将该命令包装在bash函数中来简化它。假设你只想输入这个:

sshcd example.com /foo/bar

你可以通过添加到~/.bashrc来实现:

sshcd () { ssh -t "$1" "cd \"$2\"; exec \$SHELL -l"; }

如果使用远程机器上存在的变量作为目录,请确保对其进行转义或将其放在单引号中。例如,这将cd到远程机器上存储在JBOSS_HOME变量中的目录:

sshcd example.com \$JBOSS_HOME

SSH配置文件

如果您希望使用普通的ssh命令在特定(或任何)主机上一直看到这种行为,而不必使用额外的命令行参数,您可以在ssh配置文件中设置RequestTTY和RemoteCommand选项。

例如,我只想输入以下命令:

ssh qaapps18

但希望它总是像这样的命令:

ssh -t qaapps18 'cd $JBOSS_HOME; exec $SHELL'

所以我把这个加到~/。ssh /配置文件:

Host *apps*
    RequestTTY yes
    RemoteCommand cd $JBOSS_HOME; exec $SHELL

现在,该规则适用于主机名中包含“apps”的任何主机。

欲了解更多信息,请参见http://man7.org/linux/man-pages/man5/ssh_config.5.html