kar*_*ani 2 java unix ssh shell jsch
我有一段连接到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);
}
}
public static void main(String arg[]){
connect();
}
public String return_message(){
String ret_message=page_message;
return ret_message;
}
public static abstract class MyUserInfo
implements UserInfo, UIKeyboardInteractive{
public String getPassword(){ return null; }
public boolean promptYesNo(String str){ return false; }
public String getPassphrase(){ return null; }
public boolean promptPassphrase(String message){ return false; }
public boolean promptPassword(String message){ return false; }
public void showMessage(String message){ }
public String[] promptKeyboardInteractive(String destination,
String name,
String instruction,
String[] prompt,
boolean[] echo){
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
JSch中的"exec"通道(正确地)不为会话分配伪终端(PTY).因此,可能(可能)采购了一组不同的启动脚本(特别是对于非交互式会话,.bash_profile
未采购).和/或脚本中的不同分支基于TERM
环境变量的存在/存在而被采用.所以环境可能与交互式会话不同,您可以使用SSH客户端.
所以,在你的情况下,PATH
可能设置不同; 因此air
无法找到可执行文件.
要验证这是根本原因,请在SSH客户端中禁用伪终端分配.例如,在PuTTY中,它的连接> SSH> TTY>不分配伪终端.然后,转到Connection> SSH> Remote命令并输入您的air ...
命令.在退出时检查会话>关闭窗口>从不打开会话.您应该得到相同的"未找到空气"错误.
按优先顺序解决此问题的方法:
修复命令不依赖于特定环境.air
在命令中使用完整路径.
修复启动脚本,which air
为交互式和非交互式会话设置相同的启动脚本.
尝试通过登录shell显式运行脚本(使用PATH
带有常见*nix shell的开关):
/bin/air sandbox run <graph-path>
Run Code Online (Sandbox Code Playgroud)如果命令本身依赖于特定的环境设置而无法修复启动脚本,则可以在命令本身中更改环境.该语法取决于远程系统和/或shell.在常见的*nix系统中,这有效:
bash --login -c "air sandbox run sandbox run <graph-path>"
Run Code Online (Sandbox Code Playgroud)另一种(不推荐)方法是使用以下--login
方法强制"exec"通道的伪终端分配:
String command="PATH=\"$PATH;/path/to/air\" && air sandbox run <graph-path>";
Run Code Online (Sandbox Code Playgroud)
使用伪终端自动执行命令可能会带来令人讨厌的副作用.请参阅示例是否有一种简单的方法可以摆脱使用Python的Paramiko库进行SSH并从远程计算机的CLI获取输出时出现的垃圾值?
对于类似的问题,请参阅
归档时间: |
|
查看次数: |
1691 次 |
最近记录: |