为了账号安全,请及时绑定邮箱和手机立即绑定

当使用JSch通过Java执行时,某些Unix命令失败并显示“... not found”

当使用JSch通过Java执行时,某些Unix命令失败并显示“... not found”

largeQ 2019-08-23 10:23:06
当使用JSch通过Java执行时,某些Unix命令失败并显示“... not found”我有一段连接到Unix服务器并执行命令的代码。我一直在尝试简单的命令,他们工作正常。我能够登录并获得命令的输出。我需要通过Java运行Ab-initio图。我正在使用此air sandbox run graph命令。当我使用SSH客户端登录并运行命令时,它运行正常。我能够运行图表。但是,当我尝试通过Java运行命令时,它会给我一个“未找到空气”的错误。对JSch支持的Unix命令有什么限制吗?知道为什么我无法通过我的Java代码运行命令吗?这是代码:public static void connect(){     try{       JSch jsch=new JSch();         String host="*****";       String user="*****";       String config =                 "Host foo\n"+                 "  User "+user+"\n"+                 "  Hostname "+host+"\n";       ConfigRepository configRepository =             com.jcraft.jsch.OpenSSHConfig.parse(config);       jsch.setConfigRepository(configRepository);       Session session=jsch.getSession("foo");       String passwd ="*****";       session.setPassword(passwd);       UserInfo ui = new MyUserInfo(){           public boolean promptYesNo(String message){             int foo = 0;             return foo==0;           }       };       session.setUserInfo(ui);       session.connect();       String command="air sandbox run <graph-path>";       Channel channel=session.openChannel("exec");       ((ChannelExec)channel).setCommand(command);       channel.setInputStream(null);       ((ChannelExec)channel).setErrStream(System.err);       InputStream in=channel.getInputStream();       channel.connect();       byte[] tmp=new byte[1024];       while(true){         while(in.available()>0){           int i=in.read(tmp, 0, 1024);           if(i<0)break;           page_message=new String(tmp, 0, i);           System.out.print(page_message);         }         if(channel.isClosed()){           if(in.available()>0) continue;            System.out.println("exit-status: "+channel.getExitStatus());           break;         }         try{Thread.sleep(1000);}catch(Exception ee){}       }       channel.disconnect();       session.disconnect();     }     catch(Exception e){       System.out.println(e);     }}
查看完整描述

3 回答

?
大话西游666

TA贡献1817条经验 获得超14个赞

JSch中的“exec”通道(正确地)不为会话分配伪终端(PTY)。因此,可能(可能)采购了一组不同的启动脚本(特别是对于非交互式会话,.bash_profile未采购)。和/或脚本中的不同分支基于TERM环境变量的存在/存在而被采用。所以环境可能与交互式会话不同,您可以使用SSH客户端。

所以,在你的情况下,PATH可能设置不同; 因此air无法找到可执行文件。

要验证这是根本原因,请在SSH客户端中禁用伪终端分配。例如,在PuTTY中,它的连接> SSH> TTY>不分配伪终端。然后,转到Connection> SSH> Remote命令并输入您的air ...命令。在退出时检查会话>关闭窗口>从不打开会话。您应该得到相同的“未找到空气”错误。


按优先顺序解决此问题的方法:

  1. 修复命令不依赖于特定环境。air在命令中使用完整路径。例如:

    /bin/air sandbox run <graph-path>

    如果您不知道完整路径,则在常见的* nix系统上,您可以which air在交互式SSH会话中使用命令。

  2. 修复启动脚本,PATH为交互式和非交互式会话设置相同的启动脚本。

  3. 尝试通过登录shell显式运行脚本(使用--login带有常见* nix shell的开关):

    bash --login -c "air sandbox run sandbox run <graph-path>"
  4. 如果命令本身依赖于特定的环境设置而无法修复启动脚本,则可以在命令本身中更改环境。该语法取决于远程系统和/或shell。在常见的* nix系统中,这有效:

    String command="PATH=\"$PATH;/path/to/air\" && air sandbox run <graph-path>";
  5. 另一种(不推荐)方法是使用以下.setPty方法强制“exec”通道的伪终端分配:

    Channel channel = session.openChannel("exec");((ChannelExec)channel).setPty(true);

    使用伪终端自动执行命令可能会带来令人讨厌的副作用。

查看完整回答
反对 回复 2019-08-23
?
明月笑刀无情

TA贡献1828条经验 获得超4个赞

您可以使用〜/ .ssh / environment文件来设置AB_HOME和PATH变量。


查看完整回答
反对 回复 2019-08-23
?
HUH函数

TA贡献1836条经验 获得超4个赞

你可以尝试找出“空气”所在的位置

whereis air

然后使用这个结果。

就像是

/usr/bin/air sandbox run graph


查看完整回答
反对 回复 2019-08-23
  • 3 回答
  • 0 关注
  • 1956 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信