繁体   English   中英

“远程确认失败:scp:模糊目标”,同时使用 Windows 机器上的“scp”上传文件,而它适用于 Linux 和 Mac

[英]“Remote Acknowledge failed: scp: ambiguous target” while uploading files using “scp” from Windows machine, while it works on Linux and Mac

我正在尝试运行一个测试用例,它基本上将文件从我的机器复制到在 docker 中运行的模拟服务器。 相同的测试在 Mac 和 Ubuntu 上运行良好。 但是在 Windows 上它失败并出现以下错误:-

Exception while executing command on remote SSH server
java.lang.RuntimeException: Exception while executing command on remote SSH server
    at com.org.implementation.RemoteCommandWrapper.runSshCommandWithTimeout(RemoteCommandWrapper.java:53)
    at com.org.implementation.RemoteCommandWrapper.copyLocalToRemote(RemoteCommandWrapper.java:121)
...
    
Caused by: java.util.concurrent.ExecutionException: java.lang.RuntimeException: Remote Acknowledge failed: scp: ambiguous target

    at java.base/java.util.concurrent.CompletableFuture.reportGet(CompletableFuture.java:395)
    at java.base/java.util.concurrent.CompletableFuture.get(CompletableFuture.java:2022)
    at com.org.implementation.cboserver.RemoteCommandWrapper.runSshCommandWithTimeout(RemoteCommandWrapper.java:49)
    ... 92 more
Caused by: java.lang.RuntimeException: Remote Acknowledge failed: scp: ambiguous target

    at com.org.implementation.RemoteCommandWrapper.checkAck(RemoteCommandWrapper.java:174)
    at com.org.implementation.RemoteCommandWrapper.waitForFileCopied(RemoteCommandWrapper.java:136)
    at com.org.implementation.RemoteCommandWrapper.lambda$copyLocalToRemote$1(RemoteCommandWrapper.java:124)
    at com.org.implementation.RemoteCommandWrapper.tryToExecuteCommand(RemoteCommandWrapper.java:68)
    at com.org.implementation.RemoteCommandWrapper.lambda$runSshCommandWithTimeout$0(RemoteCommandWrapper.java:45)
...

RemoteCommand.java:-

public void copyLocalToRemote(Session session, Path localPath, Path remotePath, String fileName) {
    log.info("localPath: {}",localPath); //localPath:C:\Users\myuser\project1\src\test\resources\5f9cce18-362e-4973-a26b-730131841d7b
    log.info("remotePath: {}",remotePath); // remotePath:\
    log.info("fileName: {}",fileName);// fileName: CustomFile.zip
    String copyCommand = createCopyCommand(remotePath);
    runSshCommandWithTimeout(session,
            copyCommand,
            (channel, in, out) -> {
                waitForFileCopied(channel, in, out, localPath, fileName);
                return null;
            });
}

private String createCopyCommand(Path remotePath) {
    return String.format("scp -p -t %s\n", remotePath);
}

private void waitForFileCopied(Channel channel, InputStream in, OutputStream out, Path localPath, String fileName) {
    Path from = localPath.resolve(fileName);
    try (FileInputStream fis = new FileInputStream(from.toString())) {
        checkAck(in);
        setFileAccess(from, out, in);
        fis.transferTo(out);

        // send '\0'
        out.write(new byte[]{0}, 0, 1);
        out.flush();
        checkAck(in);
    } catch (IOException e) {
        throw new RuntimeException("Error copying custom file", e);
    }
}

@SneakyThrows
private void checkAck(InputStream in){
    int b = in.read();
    if (b == 0) return;

    if (b < 0) throw new RuntimeException("Remote Acknowledge failed: " + Integer.valueOf(b));

    StringBuilder sb = new StringBuilder();
    int c;
    do {
        c = in.read();
        sb.append((char) c);
    }
    while (c != '\n');
    throw new RuntimeException("Remote Acknowledge failed: " + sb.toString());
}

<T> T runSshCommandWithTimeout(final Session session, String command, RemoteResultFactory<T> resultFactory) {
    CompletableFuture<T> future = CompletableFuture.supplyAsync(
            () -> tryToExecuteCommand(session, command, resultFactory)
    );

    try {
        return future.get(timeoutMs, TimeUnit.MILLISECONDS);
    } catch (TimeoutException e) {
        throw new RemoteTimeoutException(String.format("Timeout while executing command on remote SSH server: %d ms", timeoutMs));
    } catch (Exception e) {
        throw new RuntimeException("Exception while executing command on remote SSH server", e);
    }
}

private <T> T tryToExecuteCommand(Session session, String command, RemoteResultFactory<T> resultFactory) {
    Channel channel = null;
    try {
        channel = session.openChannel("exec");
        ((ChannelExec) channel).setCommand(command);

        // TODO handle extInputStream (error stream)
        try (InputStream in = channel.getInputStream();
             OutputStream out = channel.getOutputStream()) {

            channel.connect();
            return resultFactory.getResult(channel, in, out);
        }
    } catch (JSchException | IOException e) {
        throw new RuntimeException("Exception while executing command on remote SSH server", e);
    } finally {
        if (channel != null) {
            channel.disconnect();
        }
        session.disconnect();
    }
}

在 Google 上搜索此错误时,我可以理解scp无法识别目标目的地,这也应该是 Window 路径的问题,或者可能是因为"/""\" ,因为相同的测试正在基于 Linux文件系统(以及在 Mac 中)。

我无法弄清楚确切的问题以及如何解决它。

任何人都可以建议从中恢复过来吗?

谢谢

远程路径必须是/ ,而不是\

并且createCopyCommand的参数不能是Path ,就像在 Windows 上一样,这会将/转换为\

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM