且构网

分享程序员开发的那些事...
且构网 - 分享程序员编程开发的那些事

Java JSch在远程机器上更改用户并执行命令

更新时间:2023-11-11 20:11:58

这里有几个问题。

首先,SSH连接中的每个通道独立于其他通道,每个exec通道中的命令在其自己的shell(命令行解释器)中执行。因此,您在一个频道中所做的任何更改都不会对其他频道产生任何影响。你也做不到这样的事情:

First, each channel in a SSH connection is independent of the other ones, and the command in each exec channel is executed in its own shell (command line interpreter). So any changes you are doing in one channel have no effect at all to the other channels. You also can't do stuff like this:

runSshCommand("cd Documents", session);
runSshCommand("ls -l", session);

(实际上你可以这样做,但它不会显示 Documents 目录,但是主目录。)

(Actually you can do this, but it will not show the contents of the Documents directory, but of the home directory.)

对于 cd ,你可以通过将两个命令作为一个命令传递来解决,以便在相同的 exec 频道中使用:

For cd, you can work around by passing both commands as one "command", to be used in the same exec channel:

runSshCommand("cd Documents; ls -l");

(而不是; 你也可以使用换行符 \ n 分隔命令或shell接受的任何其他命令。)

(Instead of the ; you can also use a line break \n to separate the commands, or whatever else your shell accepts.)

For su 这不起作用,我们来到第二个问题

For su this will not work, where we come to the second problem.

su 不是更改当前shell状态的命令(如 cd ),而是一个打开新shell的命令在现有的内部。当您离开由 su 启动的shell时,它将仅返回到外壳(例如,通过 exit logout 或end-of-file),然后你再次成为与之前相同的用户。

su is not a command which changes the state of the current shell (like cd), but a command which opens a new shell inside the existing one. It will only return to the outer shell when you leave the shell started by su (e.g. by exit, logout or end-of-file), and then you are again the same user as before.

将命令传递给内壳,你必须将它们传递给shell输入。或者使用 su $ c $的 -c - 命令)参数c>:

To pass commands to the "inner shell", you'll have to pass them to the shells input. Or use the -c (--command) argument of su:

runSshCommand("su -c 'tail -1 ~/mylog.log' - john ",session);

然后您可能会遇到第三个问题 su 会询问john的密码,并可能拒绝从标准输入中读取密码,但请尝试从终端读取密码。而你的频道没有伪终端。您可以尝试使用 cannel.setPty(true) 然后实际将密码写入输出流,但我不确定这是否有效。

You might then run in the third problem: su will ask for john's password, and might refuse to read it from the standard input, but try to read it from the terminal. And your channel has no pseudo-terminal. You can try to use cannel.setPty(true) and then actually write your password to the output stream, though I'm not sure that this will work.

替代方案:您可以使用 sudo 代替 su -c ,可以配置为不要求某些命令和用户的密码(否则您将再次遇到相同的终端问题)。或者你可以直接以 john 的身份登录,或者让tom的日志文件可读。 (另外,我希望您的真实密码比源代码中的密码更好。)

Alternatives: Instead of su -c you can use sudo, which can be configured not to ask for a password for certain commands and users (otherwise you'll have the same terminal problem again). Or you could directly log in as john, or make the logfile readable for tom. (Also, I hope your real password is better than the one in your source code.)