从 Daemon 线程调用的 scp 进程因缺少 /dev/tty 而失败
Scp process invoked from Daemon thread fails with missing /dev/tty
我在 java 中有一个守护进程,我正在 运行ning 通过 jsvc。大多数守护进程工作正常,但我一直无法让它通过 SCP 传输文件。由于要将文件传输到的计算机的设置,我需要使用 public 密钥身份验证。然而,这似乎要求父进程与终端相关联,如果没有则失败。它似乎从来没有进入实际询问密码的阶段,在此之前失败了。
Java 代码片段,创建过程
String[] command = { "scp", "-v", "-o", "PubkeyAuthentication=no",
localFile.getAbsolutePath(),
username + "@" + destinationIP + ":" + destinationPath };
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process scpProcess = builder.start();
提供密码
InputStream inStream = scpProcess.getInputStream();
InputStreamReader inReader = new InputStreamReader(inStream);
bInReader = new BufferedReader(inReader);
String recievedLine = null;
StringBuilder recievedLines = new StringBuilder();
boolean passwordFlag = false;
while ((recievedLine = bInReader.readLine()) != null) {
recievedLines.append(recievedLine + "\n");
// send password to the scp program
if (recievedLine.contains("password:")) {
OutputStream outStream = scpProcess.getOutputStream();
OutputStreamWriter outWriter = new OutputStreamWriter(
outStream);
bOutWriter = new BufferedWriter(outWriter);
bOutWriter.write(password + "\n");
bOutWriter.flush();
passwordFlag = true;
break;
}
}
带有详细 SCP 输出的日志文件片段
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Permission denied, please try again.
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Permission denied, please try again.
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug1: No more authentication methods to try.
Permission denied (publickey,password,keyboard-interactive).
据我所知,正在发生的事情是创建的进程从父进程继承了 tty,由于 jsvc 运行将其作为守护进程而未设置。但是,我要求此进程作为守护程序 运行,并且无法更改。
有谁知道我如何使用 tty 强制进程 运行,这样它就不会这样做 - 同时仍然能够从父级访问 input/output/error 流 java程序?如果做不到这一点,有没有人知道使用密码身份验证使 SCP 传输正常工作的不同方法?有没有人有解决这个问题的任何其他想法?
所有 OpenSSH 二进制文件,包括 scp
,都是为了防止自动 password/passphrase 输入而构建的。坚持使用 TTY 是措施之一。
两种解决方案:
- 使用
sshpass
to fake TTY. See the sshpass man page.
- 使用未加密的私钥以避免密码提示。
我在 java 中有一个守护进程,我正在 运行ning 通过 jsvc。大多数守护进程工作正常,但我一直无法让它通过 SCP 传输文件。由于要将文件传输到的计算机的设置,我需要使用 public 密钥身份验证。然而,这似乎要求父进程与终端相关联,如果没有则失败。它似乎从来没有进入实际询问密码的阶段,在此之前失败了。
Java 代码片段,创建过程
String[] command = { "scp", "-v", "-o", "PubkeyAuthentication=no",
localFile.getAbsolutePath(),
username + "@" + destinationIP + ":" + destinationPath };
ProcessBuilder builder = new ProcessBuilder(command);
builder.redirectErrorStream(true);
Process scpProcess = builder.start();
提供密码
InputStream inStream = scpProcess.getInputStream();
InputStreamReader inReader = new InputStreamReader(inStream);
bInReader = new BufferedReader(inReader);
String recievedLine = null;
StringBuilder recievedLines = new StringBuilder();
boolean passwordFlag = false;
while ((recievedLine = bInReader.readLine()) != null) {
recievedLines.append(recievedLine + "\n");
// send password to the scp program
if (recievedLine.contains("password:")) {
OutputStream outStream = scpProcess.getOutputStream();
OutputStreamWriter outWriter = new OutputStreamWriter(
outStream);
bOutWriter = new BufferedWriter(outWriter);
bOutWriter.write(password + "\n");
bOutWriter.flush();
passwordFlag = true;
break;
}
}
带有详细 SCP 输出的日志文件片段
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Permission denied, please try again.
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
Permission denied, please try again.
debug1: read_passphrase: can't open /dev/tty: No such device or address
debug1: Authentications that can continue: publickey,password,keyboard-interactive
debug1: No more authentication methods to try.
Permission denied (publickey,password,keyboard-interactive).
据我所知,正在发生的事情是创建的进程从父进程继承了 tty,由于 jsvc 运行将其作为守护进程而未设置。但是,我要求此进程作为守护程序 运行,并且无法更改。
有谁知道我如何使用 tty 强制进程 运行,这样它就不会这样做 - 同时仍然能够从父级访问 input/output/error 流 java程序?如果做不到这一点,有没有人知道使用密码身份验证使 SCP 传输正常工作的不同方法?有没有人有解决这个问题的任何其他想法?
所有 OpenSSH 二进制文件,包括 scp
,都是为了防止自动 password/passphrase 输入而构建的。坚持使用 TTY 是措施之一。
两种解决方案:
- 使用
sshpass
to fake TTY. See the sshpass man page. - 使用未加密的私钥以避免密码提示。