为什么jsch不执行scp命令?

时间:2020-05-20 10:11:35

标签: java scp jsch

我正在尝试使用function sww_wc_free_shipping_label( $label ) { global $current_user; $wholesale_customer = get_user_meta( $current_user->ID, 'wcs_wholesale_customer', true ); if( ( $wholesale_customer ) ) { if( WC()->cart->subtotal >= 80 ) { $label = 'WHOLESALE Shipping & GST to be added at dispatch'; } else { $label = 'WHOLESALE Shipping & GST to be added at dispatch + Flat rate of $10'; } } return $label; } add_filter( 'woocommerce_cart_shipping_method_full_label', 'sww_wc_free_shipping_label', 10, 2 ); 将文件从本地传输到远程。本地是Windows(OpenSSH作为服务运行),远程是FreeBSD(已设置rsa键)。 为此,我正在使用Jsch库。

scp

命令try { if (ses == null) ses = fsaTo.getSession(); channel = ses.openChannel("exec"); String cmd = "scp "+ UserHostIdentity.getTransferUser(fsaFrom.getSystem()) + "@" + UserHostIdentity.getTransferHost(fsaFrom.getSystem()) + ":" + from + " " + to; ((ChannelExec)channel).setCommand(cmd); ((ChannelExec)channel).setErrStream(System.err); channel.connect(); } catch (JSchException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (Exception e) { // TODO Auto-generated catch block e.printStackTrace(); } 我对其进行了测试,手动执行了该命令,并且该命令可以正常工作。这是我启动会话的方式:

cmd

问题是调用JSch jsch = new JSch(); try { sshSession = jsch.getSession(UserHostIdentity.getTransferUser(fs), UserHostIdentity.getTransferHost(fs),22); UserInfo lui = UserHostIdentity.getTransferUserInfo(fs); sshSession.setUserInfo(lui); sshSession.setConfig("StrictHostKeyChecking", "no"); sshSession.connect(); } catch (JSchException e) { logger.error("Could not access fileserver."); throw new RuntimeException(e); } 之后没有任何反应,没有错误,没有任何反应。 在相同的上下文中,以下代码执行channel.connect()并返回正确的结果:

"sha256 -q " + filePath

我的问题是,为什么它不能与public String doCommand(String cmd) { if (sshSession == null) { initiateConnection(); } Channel channel; String result = ""; try { channel = sshSession.openChannel("exec"); ((ChannelExec)channel).setCommand(cmd); channel.setInputStream(null); ((ChannelExec)channel).setErrStream(System.err); InputStream input = channel.getInputStream(); channel.connect(); InputStreamReader inputReader = new InputStreamReader(input); BufferedReader bufferedReader = new BufferedReader(inputReader); String line = null; while((line = bufferedReader.readLine()) != null){ result = line; } bufferedReader.close(); inputReader.close(); channel.disconnect(); } catch (JSchException e) { logger.error("Problem with communication to Fileserver."); throw new RuntimeException(e); } catch (IOException e) { logger.error("Problem with command stream."); throw new RuntimeException(e); } return result; } 命令一起使用。

3 个答案:

答案 0 :(得分:0)

最开始的事情可能是使用详细参数运行scp:

scp -v src dest

或者如果这不帮助您查看是否可以安装strace(如果尚未安装)并运行:

strace scp -v src dest

这应该向您提示可能出了什么问题(尽管您说已设置了主机密钥,但是您是否对其进行了测试?),例如:

  • 主机密钥验证可能失败
  • 您可能需要输入私钥的密码短语
  • 可能存在一些安全性不兼容

您还会忘记继续阅读InputStream,也许在channel.connect()行周围做类似的事情:

InputStream in = channel.getInputStream();
channel.connect();
in.transferTo(System.out);

或者像sha256命令一样继续读取InputStream(来自scp的stdout),直到该过程完成(这样就可以在我的机器上工作了)。

答案 1 :(得分:0)

好的,所以您的代码正在执行以下操作:

  1. 使用SSH连接到<fsaTo>
  2. <fsaTo>上运行命令“ scp @:/”。

scp命令将尝试打开与<fsaFrom> ...的另一条SSH连接 back ...,这大概是该主机... ... em>通过该连接恢复文件

这可能有效,但仅在以下情况下有效:

  • <fsaFrom>正在侦听传入的SSH连接
  • 您正在使用的<fsaTo>帐户具有SSH私钥(无密码),该私钥与注册为以<fsaFrom>登录<user>的公共密钥之一相对应。< / li>

有一个更好的方法,没有任何先决条件。当您将scp命令作为普通命令运行时,远程系统上会使用一些未公开的scp命令命令行开关。

  • scp -f <remote-file><remote-file>读取并将其发送到ssh输出流。
  • scp -t <remote-file>从ssh输入流中读取并输出到<remote-file>

有关更多详细信息,请参见SSH: The Secure Shell, the definitive guide section 3.8

或者,如果您只想举个例子,JSch ScpTo.java example展示了如何去做您想做的事情。

答案 2 :(得分:0)

如果您已经在使用JSch库,为什么不使用SFTP?

请参见使用JSch SFTP上传文件的示例代码:

public void uploadFile(File file, String location) {
    ChannelSftp channelSftp = null;
    try {
        channelSftp = (ChannelSftp)connect();
        if(location.startsWith(ROOT_DIR)) {
            channelSftp.cd(ROOT_DIR);
        }
        final List<String> directories = Splitter.on(File.separatorChar).omitEmptyStrings().splitToList(location);
        for(String dir : directories) {
            try {
                channelSftp.ls(dir);
            } catch (SftpException e) {
                channelSftp.mkdir(dir);
            }
            channelSftp.cd(dir);
        }
        if(LOGGER.isDebugEnabled()) {
            LOGGER.debug("Uploading file " + file.getPath() + " in " + location);
        }
        channelSftp.put(new FileInputStream(file), file.getName());
    } catch(Throwable e) {
        throw new RuntimeException("Upload file " + file.getPath() + " failed.", e);
    } finally {
        disconnect(channelSftp);
    }
}