首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何避免在JSch中使用SCP时的双引号?

如何避免在JSch中使用SCP时的双引号?
EN

Stack Overflow用户
提问于 2017-10-09 15:34:16
回答 2查看 787关注 0票数 0

在Windows系统上安装了SSH,并与远程主机(Linux)交换了密钥。我想在windows机器上运行一个JAR来将SCP文件放到Linux机器上。在命令行上使用

代码语言:javascript
复制
"C:/Program Files (X86)/ICW/bin/SCP.exe" -i .ssh/id_rsa <filename> theUser@xxx.xxx.xx.xx:/target/path/<filename>

它工作得很好(使用双引号)。

但是当我使用JSch从JAR中运行SCP时,我得到了一个sun.nio.file.InvalidPathException:非法的char <"> at索引.

我的意图是,我必须从FTP主机上以编程方式收集一堆文件(我已经完成了这个部分的工作)。必须将这些文件转发到前面提到的远程主机。FTP主机和远程主机不能直接通信。因此,Windows机器充当一种代理。JAR从FTP服务器获取文件(当前将它们保存在映射中),我希望使用JSch SCP直接将它们放在远程Linux主机上的特定文件夹中。

我该如何解决这个问题?如何解决这一双重报价问题

代码语言:javascript
复制
    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();
        }
    }

其中vaFiles是Map和scp.command来自属性文件,并且是

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

(我尝试将命令字符串包装为单引号、双引号、不带引号、不带\u 0020、.)

使用MessageFormat填充

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

{1} =文件名

{2} = scp用户名

{3} = scp hist IP地址

{4} =远程主机上的目标路径

{5} =文件名(见{1})

SFTP目前没有选项,只有SCP安装在Windows机器和远程Linux主机上。如果我在做这件事时有完全的误解,我会很感激任何的技术转移,以学习如何做正确的方式。:-)

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2017-10-10 09:20:16

很明显,您正在尝试启动SCP文件从本地Windows机器到远程Linux机器的传输。

但是代码所做的是,它将ssh发送到远程Linux机器,并尝试在那里运行Windows风格的命令C:\Program Files (x86)\ICW\bin\scp.exe。这是行不通的,不管你会用什么样的报价。

  1. 不要使用SCP,这是一个古老的协议。使用SFTP。所有Linux机器都支持SFTP。JSch也有对SFTP的本机支持。您将不需要任何本地OpenSSH安装。
  2. 即使您决定继续使用SCP,将JSch SSH/SFTP库与本地独立SCP客户端结合也是没有意义的。
代码语言:javascript
复制
- Either use a native Java SCP implementation:

http://www.jcraft.com/jsch/examples/ScpTo.java.html

(您将不需要本地OpenSSH安装)

-或者在本地运行scp.exe (您将不需要JSch SSH库)--尽管我根本不推荐这个选项。

票数 1
EN

Stack Overflow用户

发布于 2017-10-10 11:28:04

好的,马丁,谢谢你指引我走向正确的方向。我可能会检查并尝试使用SFTP实现它。目前,您帮助我至少使用SCP实现了一个工作版本(尽管它是一个古老的协议):

代码语言:javascript
复制
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();
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/46650096

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档