SSH,在登录时运行命令,然后保持登录状态?


29

我以期望的方式尝试了此操作,但未成功:最后关闭了连接。

我们是否可以通过ssh运行脚本,该脚本将登录到远程计算机,运行命令而不断开连接?

因此,将ssh放入一台计算机中,将cd插入该目录,然后运行命令,并保持登录状态。

乔纳森

(我曾经用过)

#!/usr/bin/expect -f
set password [lrange $argv 0 0]
spawn ssh root@marlboro "cd /tmp; ls -altr | tail"
expect "?assword:*"
send -- "$password\r"
send -- "\r"
interact

9
是我还是您以这种方式“自动”进行密码验证,而不是使用pubkeys或其他理智的方法?
grawity

Answers:


25

; /bin/bash在远端的命令行末尾添加a 吗?那是:

spawn ssh -t root@marlboro "cd /tmp; ls -altr | tail; /bin/bash -i"

更好的是,将root的.bashrc更改为如下所示:

PROMPT_COMMAND="cd /tmp && ls -altr | tail ; unset PROMPT_COMMAND"

:)


2
您可能要添加-i到该bash。
Teddy

是的,我想是:)
Bill Weiss,

当我这样做时,制表符补全会在新的shell中中断(即使带有“ -i”)-知道为什么/如何解决?
Coderer

1
我在这里测试了新答案,效果很好。有点粗糙,但可以。
比尔·魏斯

7
尝试ssh -t分配pty。
暂停,直到另行通知。

4

如果可以在Python中执行此操作,则pexpect的示例几乎可以完全满足您的要求:

import pexpect
child = pexpect.spawn ('ftp ftp.openbsd.org')
child.expect ('Name .*: ')
child.sendline ('anonymous')
child.expect ('Password:')
child.sendline ('noah@example.com')
child.expect ('ftp> ')
child.sendline ('ls /pub/OpenBSD/')
child.expect ('ftp> ')
print child.before   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

要使用ssh而不是ftp来执行此操作,您需要类似于以下代码(pexpect中的示例文件具有更多详细信息和信息,但这里是基础知识):

import pexpect
child = pexpect.spawn ('ssh root@marlboro')
child.expect ('Password:')
child.sendline ('password')
child.expect ('prompt# ')
child.sendline ('cd /tmp')
child.expect ('prompt# ')
child.sendline ('ls -altr | tail')
child.expect ('prompt# ')
print child.before, child.after   # Print the result of the ls command.
child.interact()     # Give control of the child to the user.

不要误会我的意思,我很期待(尤其是自动预期),但是python实在让我更容易理解。


我也正在从期望过渡到期望。python现在无处不在。
JM Becker

4

ssh进入服务器,生成交互式shell并在该shell中运行命令的最简单,最干净的方法是为bash创建一个自定义rc文件。

在服务器上的自定义bashrc文件中,首先获取默认文件,然后添加自定义命令,例如

〜/ .bashrc_custom:

. ~/.bashrc
cd dir/
workon virtualenvproject

然后,您可以像这样启动SSH会话:

$ ssh -t server "/bin/bash --rcfile ~/.bashrc_custom -i"

-t选项强制执行伪tty分配,以便诸如制表符补全之类的功能起作用。

--rcfile选项指定要加载的rcfile,而不是默认的rcfile。重要说明:必须在命令行上在单字符选项之前放置“双破折号参数”才能被识别。

-i/ bin / bash 的参数在那里调用交互式外壳程序。


其实并不是。如果我想为每个连接运行不同的命令怎么办?
Eugen Konkov'3

1

如果有人想了解后台发生的事情,则应查看sshd手册:

用户成功登录后,sshd将执行以下操作:

  1. 如果登录名是在tty上,并且未指定任何命令,则显示上次登录时间和/ etc / motd(除非在配置文件或〜/ .hushlogin中被阻止;请参见FILES部分)。
  2. 如果登录名是tty,则记录登录时间。
  3. 检查/ etc / nologin和/ var / run / nologin; 如果存在,它将打印内容并退出(除非root)。
  4. 更改以普通用户权限运行。
  5. 设置基本环境。
  6. 读取〜/ .ssh / environment文件(如果存在),并且允许用户更改其环境。请参阅sshd_config(5)中的PermitUserEnvironment选项。
  7. 更改到用户的主目录。
  8. 如果〜/ .ssh / rc存在,请运行它;否则,请运行它。否则,如果/ etc / ssh / sshrc存在,则运行它;否则运行xauth(1)。在标准输入中为``rc''文件提供了X11身份验证协议和cookie。请参阅下面的SSHRC。
  9. 运行用户的外壳程序命令。

https://www.freebsd.org/cgi/man.cgi?sshd(8)#LOGIN_PROCESS


0

您通常应该避免以这种方式使用ssh,因为它无法达到目的。
做一个

ssh-add -l | grep "file_of_your_rsa_priv_key_here"

查看您的密钥是否在ssh活动会话池中列出,或者自己添加(使用ssh-add)。

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.