简体   繁体   English

将SCP与JSch一起使用时,如何转义双引号?

[英]How can I escape doublequotes when using SCP with JSch?

On a Windows system is SSH installed and keys are exchanged with a remote host (Linux). 在Windows系统上,安装了SSH,并且密钥与远程主机(Linux)交换。 I want to run a JAR on the windows machine to SCP files to the Linux machine. 我想在Windows机器上运行JAR,将SCP文件发送到Linux机器。 Doing this on the command line with 在命令行上使用

"C:/Program Files (X86)/ICW/bin/SCP.exe" -i .ssh/id_rsa <filename> theUser@xxx.xxx.xx.xx:/target/path/<filename>

it works well (using the double quotes). 它运作良好(使用双引号)。

But when I run the SCP from within the JAR using JSch I get a sun.nio.file.InvalidPathException: Illegal char <"> at index... 但是,当我使用JSch在JAR中运行SCP时,我得到了sun.nio.file.InvalidPathException:索引处的非法char <> ...

The intention is that I have to gather a bunch of files programmatically from an FTP host (I already got this part working). 目的是我必须以编程方式从FTP主机上收集一堆文件(我已经使这部分工作了)。 These files must be forwarded to the already mentioned remote host. 这些文件必须转发到已经提到的远程主机。 The FTP host and the remote host cannot communicate direcly with each other. FTP主机和远程主机不能直接通信。 Thus, the Windows machine acts as a kind of broker. 因此,Windows计算机充当一种代理。 The JAR gets the files from the FTP server (currently keeping them in a map) and I want to use JSch SCP to directly put them into a particular folder on the remote Linux host. JAR从FTP服务器获取文件(当前将它们保存在地图中),我想使用JSch SCP将其直接放入远程Linux主机上的特定文件夹中。

How can I solve this problem? 我怎么解决这个问题? How to solve this double quote issue ? 如何解决这个双引号问题

    private void storeFiles() throws IOException {
        final JSch jsch = new JSch();
        final FileSystem fs = FileSystems.getDefault();
        final Path p = fs.getPath( getProperty("scp.key.file.private"));
        logger.info("Reading private key from " + getProperty("scp.key.file.private"));

        final Session session;
        try {
            session = jsch.getSession(getProperty("scp.user.name"), getProperty("scp.host.ip"),
                    Integer.parseInt(getProperty("scp.port")));
            jsch.addIdentity(p.toFile().getPath());
            final Properties config = new java.util.Properties();
            config.put("StrictHostKeyChecking", "no");
            session.setConfig(config);
            session.connect();
            logger.info("Connected to " + getProperty("scp.host.ip") + "...");

            vaFiles.forEach((k, v) ->{
                // get I/O streams for remote scp
                try {
                    final MessageFormat mf = new MessageFormat(getProperty("scp.command"));
                    final Object[] commandArgs = new Object[]{getProperty("scp.key.file.private"),
                            k, getProperty("scp.user.name"),
                            getProperty("scp.host.ip"),
                            getProperty("scp.target.path"), k};
                    final String command = mf.format(commandArgs);
                    logger.info(command);
                    final Channel channel;
                    try {
                        channel = session.openChannel("exec");
                        channel.connect();
                        ((ChannelExec)channel).setCommand(command);
//                        logger.info("Writing " + Arrays.toString(v) + " to SCP channel...");
                        final OutputStream out = channel.getOutputStream();
                        out.write(command.getBytes());
                        out.flush();
                        out.write(v);
                        out.close();
                        channel.disconnect();
                    } catch (JSchException e) {
                        e.printStackTrace();
                    }
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }); //end forEach
            session.disconnect();
        } catch (JSchException e) {
            e.printStackTrace();
        }
    }

Whereby vaFiles is Map<String, byte[]> and scp.command comes from a properties file and is 其中vaFiles是Map <String,byte []>和scp.command来自属性文件,并且

scp.command = '\"C\:/Program\u0020Files\u0020(x86)/ICW/bin/scp.exe\"' -i {0} {1} {2}@{3}\:{4}/{5} 

(I tried to wrap the command string in single quotes, double quotes, without quotes, without \ , ...) (我尝试将命令字符串用单引号,双引号,不带引号,不带\\ u0020等包装)。

being filled up using MessageFormat with 使用MessageFormat填充

{0} = '\\"C:/Program\ Files\ (x86)/ICW/bin/scp.exe\\"' {0} ='\\“ C:/ Program \\ u0020Files \\ u0020(x86)/ICW/bin/scp.exe \\”

{1} = the filename {1} =文件名

{2} = scp username {2} = SCP用户名

{3} = scp hist IP address {3} = SCP历史IP地址

{4} = target path on remote host {4} =远程主机上的目标路径

{5} = the filename (see {1}) {5} =文件名(请参阅{1})

SFTP is currently no option, only SCP is installed on the Windows machine and the remote Linux host. 目前没有SFTP选项,只有SCP安装在Windows计算机和远程Linux主机上。 If I have complete misunderstanding in doing this I would appreciate any know-how transfer to learn how to do it the proper way. 如果我对这样做有完全的误解,我将不胜感激任何知识转让,以学习如何正确地做。 :-) :-)

You are obviously trying to initiate an SCP file transfer from a local Windows machine to a remote Linux machine. 您显然正在尝试启动从本地Windows计算机到远程Linux计算机的SCP文件传输。

But what you code does, is that it ssh to the remote Linux machine and tries to run Windows-style command C:\\Program Files (x86)\\ICW\\bin\\scp.exe there. 但是,您执行的代码是将它SSH到远程Linux计算机,并尝试在其中运行Windows风格的命令C:\\Program Files (x86)\\ICW\\bin\\scp.exe That cannot work, no matter, what kind of quotation you will use. 不管您使用哪种报价,这都是行不通的。

  1. Do not use SCP, it's an ancient protocol. 不要使用SCP,这是一个古老的协议。 Use SFTP. 使用SFTP。 All Linux machines support SFTP. 所有Linux机器都支持SFTP。 JSch has a native support for SFTP too. JSch也具有SFTP的本机支持。 You won't need any local OpenSSH installation. 您不需要任何本地OpenSSH安装。

  2. Even if you decide to stick with SCP, it makes no sense to combine JSch SSH/SFTP library with a local standalone SCP client. 即使您决定坚持使用SCP,也没有必要将JSch SSH / SFTP库与本地独立SCP客户端结合使用。

Okay, Martin, thank you for guiding me in the right direction. 好的,马丁,谢谢您为我提供了正确的指导。 Probably I will check and try to implement it using SFTP. 可能我会检查并尝试使用SFTP实施它。 For the time being you helped my to implement at least a working version using SCP (even though it's an ancient protocol): 暂时,您帮助我使用SCP至少实现了一个工作版本(即使这是一个古老的协议):

private void storeFilesSCP() throws IOException {
    final JSch jsch = new JSch();
    final FileSystem fs = FileSystems.getDefault();
    final Path p = fs.getPath( getProperty("scp.key.file.private"));
    logger.info("Reading private key from " + getProperty("scp.key.file.private"));

    final Session session;
    try {
        session = jsch.getSession(getProperty("scp.user.name"), getProperty("scp.host.ip"),
                Integer.parseInt(getProperty("scp.port")));
        jsch.addIdentity(p.toFile().getPath());
        final Properties config = new java.util.Properties();
        config.put("StrictHostKeyChecking", "no");
        session.setConfig(config);
        final UserInfo userInfo = new UserInfo();
        session.setUserInfo(userInfo);
        session.connect();
        logger.info("Connected to " + getProperty("scp.host.ip") + "...");

        vaFiles.forEach((k, v) ->{
            // get I/O streams for remote scp
            try {
                final Channel channel;
                String command = "scp -t " + getProperty("scp.target.path") + "/" + k + " ";
                System.out.println(command);
                try {
                    channel = session.openChannel("exec");
                    ((ChannelExec)channel).setCommand(command);
                    channel.connect();
                    command="C0644 " + v.length + " " + k + "\n";
                    System.out.println(command);
                    final OutputStream out = channel.getOutputStream();
                    out.write(command.getBytes());
                    out.flush();
                    out.write(v);
                    out.flush();
                    out.close();
                    channel.disconnect();
                } catch (JSchException e) {
                    e.printStackTrace();
                }
            } catch (IOException e) {
                e.printStackTrace();
            }
        }); //end forEach
        session.disconnect();
    } catch (JSchException e) {
        e.printStackTrace();
    }
}

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

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