从 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 是措施之一。

两种解决方案:

另见 How to pass password to scp command used in bash script?