如何通过ssh直接访问特定目录?

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

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]$

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

246415 次浏览

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

您可以执行以下操作:

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

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


解释

强制伪终端分配。这可以用于在远程机器上执行任意基于屏幕的程序,这非常有用,例如在实现菜单服务时。

多个-t选项强制tty分配,即使ssh没有本地tty。

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

我使用环境变量CDPATH

你可以加上

cd /some/directory/somewhere/named/Foo

到另一台主机上的.bashrc文件(或.profile或任何你称之为它的东西)。这样,无论你做什么,或者你从哪里ssh,无论你何时登录到服务器,它都会为你cd到适当的目录,而你所要做的就是像正常一样使用ssh

骂人的是,rogeriopvl的解决方案也工作,但它有点啰嗦,而且你必须记住每次都这样做(除非你做一个别名),所以它似乎有点不“有趣”。

登录后直接进入的另一种方法是创建“别名”。当你登录系统时,只要输入这个别名,你就会在那个目录下。

示例:Alias = myfolder '/var/www/Folder'

在您登录到您的系统后,键入别名(这可以从系统的任何部分工作)
这个命令如果不在bashrc中,将适用于当前会话。所以你也可以将这个别名添加到bashrc中,以便将来使用

$ myfolder =>带您到该文件夹

我已经创建了一个工具,SSH和CD到一个服务器连续-贴切地命名为sshcd。对于你给出的例子,你可以简单地使用:

sshcd somehost:/some/directory/somewhere/named/Foo

如果你有任何问题或问题,请告诉我!

简单地修改你的家命令: usermod -d /newhome username < / p >

在我非常具体的情况下,我只是想在一个远程主机上执行一个命令,在一个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"

根据@rogeriopvl的回答,我建议如下:

ssh -t xxx.xxx.xxx.xxx "cd /directory_wanted && bash"

通过&&链接命令将使下一个命令只在前一个命令成功时运行(与使用;相反,它按顺序执行命令)。当需要cd到执行命令的目录时,这特别有用。

想象一下这样做:

/home/me$ cd /usr/share/teminal; rm -R *

目录teminal不存在,这导致您停留在主目录中,并使用以下命令删除其中的所有文件。

如果你使用&&:

/home/me$ cd /usr/share/teminal && rm -R *

如果找不到目录,该命令将失败。

更进一步的-t思想。我保留了一组脚本,调用下面的脚本访问我经常访问的主机中的特定位置。我将它们都保存在~/bin中,并将该目录保存在我的路径中。

#!/bin/bash


# does ssh session switching to particular directory
# $1, hostname from config file
# $2, directory to move to after login
# can save this as say 'con' then
# make another script calling this one, e.g.
# con myhost repos/i2c


ssh -t $1 "cd $2; exec \$SHELL --login"

我的首选方法是使用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配置文件中设置RequestTTYRemoteCommand选项。

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

ssh qaapps18

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

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

所以我把这个添加到我的~/.ssh/config文件中:

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

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

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

我知道这个问题很久以前就有答案了,但我在尝试将ssh登录合并到bash脚本中时发现了这个问题,登录后运行几个命令,然后注销并继续使用bash脚本。我发现的最简单的方法,在其他地方没有提到,因为它是如此琐碎,就是这样做。

#!/bin/bash


sshpass -p "password" ssh user@server 'cd /path/to/dir;somecommand;someothercommand;exit;'

我的答案可能与你真正想要的不同,但我在这里写的可能对一些人有用。在我的解决方案中,您必须进入该目录一次,然后每个新的ssh会话都将进入相同的目录(在第一次登出之后)。

如何ssh到相同的目录,你已经在你上次登录。 (我假设您在远程节点上使用bash)

将这一行添加到~/。远程节点(!)上的bash_logout:

echo $PWD > ~/.bash_lastpwd

这些到~/的直线。bashrc文件(仍然在远程节点!)

if [ -f ~/.bash_lastpwd ]; then
cd $(cat ~/.bash_lastpwd)
fi

通过这种方式,您可以在每次登出时保存当前路径,并且在登录后.bashrc将您放入该目录。

ps:你可以进一步调整它,比如使用SSH_CLIENT变量来决定是否进入该目录,这样你就可以区分本地登录和ssh,甚至是不同的ssh客户端。

连接用户

如果您不知道这一点,您可以通过指定用户和主机来使用它进行连接
ssh -t <user>@<Host domain / IP> "cd /path/to/directory; bash --login"

例如:ssh -t admin@test.com "cd public_html; bash --login"

您还可以通过在每个命令之前用;在双引号中附加每次登录时执行的命令

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

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

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

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

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

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