JSch:有没有办法将用户环境变量暴露给“exec”通道?

我正在尝试运行使用本地Linux逻辑路径的命令,例如cat $test_dir/test.dat ,但是逻辑路径$test_dir (用户环境变量)不能通过ChannelExec 。 但是当我使用交互式ChannelShell ,我能够看到用户变量和命令在交互式会话中运行良好。 我只能从“exec”会话中查看系统级环境变量。 甚至可以使用JSch库,如果是,那么我该如何实现它,如果不是我将使用什么库来实现这一目标?

在下面添加我的类代码:`public class SecureShell {

 private static final Logger logger = LogManager.getLogger(SecureShell.class); private String uName; private String pWord; private String hName; private int port; private Session session = null; private Channel channel = null; /**Create an instance to start and stop the remote shell and execute commands remotely via java. * * @param uName * host username * @param pWord * host password * @param hName * host name * @param port * host port number */ public SecureShell(String uName, String pWord, String hName, int port) { this.uName = uName; this.pWord = pWord; this.hName = hName; this.port = port; } /**Create an instance to start and stop the remote shell and execute commands remotely via java. * *@param uName * host username * @param pWord * host password * @param hName * host name */ public SecureShell(String uName, String pWord, String hName) { this.uName = uName; this.pWord = pWord; this.hName = hName; this.port = 22; } /**Start the session with the host. * @return * true if the session started successfully, false otherwise */ public boolean startSession() { JSch jsch = new JSch(); try { session = jsch.getSession(uName, hName, port); java.util.Properties config = new java.util.Properties(); config.put("StrictHostKeyChecking", "no"); session.setConfig(config); session.setPassword(pWord); session.connect(); } catch (JSchException jsche) { logger.error(jsche.getMessage()); return false; } return true; } /** Execute commands on the host; * @param command * command to be executed on the host. * @return * status of the execution */ public int execute(String command) { int status = -1; if(session != null && session.isConnected()) { try { channel = session.openChannel("exec"); //((ChannelExec)channel).setEnv("LC_XXX", "xxxxxxx"); ((ChannelExec)channel).setPty(true); ((ChannelExec) channel).setCommand(command); InputStream in = channel.getInputStream(); channel.connect(); byte[] buffer = new byte[1024]; while(true){ while(in.available()>0){ int i=in.read(buffer, 0, 1024); System.out.print(new String(buffer, 0, i)); if(i0) continue; status = channel.getExitStatus(); break; } } } catch (JSchException jsche) { logger.error(jsche.getMessage()); } catch (IOException ioe) { logger.error(ioe.getMessage()); } finally { if(channel!=null && channel.isConnected()) channel.disconnect(); } } return status; } /**Stop the session with the remote. * */ public void stopSession() { if(session!=null && session.isConnected()) session.disconnect(); } public static void main(String[] args) { SecureShell ssh = new SecureShell("user", "password", "hostname"); ssh.startSession(); System.out.println(ssh.execute("env")); ssh.stopSession(); } 

}`

由于您没有打开交互式shell,因此不会设置环境变量。 但是,您可以使用带有–login的bash命令(man bash获取更多详细信息)来获得所需的结果

 bash --login -c 'command arg1 ...'" 

JSch中的“exec”通道(正确地)默认情况下不为会话分配伪终端(PTY)。 因此,可能(可能)采购了一组不同的启动脚本。 和/或脚本中的不同分支基于TERM环境变量的不存在/存在而被采用。 因此,环境可能与交互式JSch“shell”会话或使用SSH客户端不同。


解决这个问题的方法:

  1. 修复启动脚本,以便为交互式和非交互式会话设置相同的环境变量。

  2. 另一种(不推荐)方法是使用.setPty方法强制“exec”通道的伪终端分配:

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

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

    • 有没有一种简单的方法来摆脱使用Python的Paramiko库进行SSH并从远程计算机的CLI获取输出时出现的垃圾值?
    • 当我使用jsch运行命令时删除不需要的字符
    • 从JSch中的命令输出中删除shell东西(如提示)

对于类似的问题,请参阅

  • 当使用JSch通过Java执行时,某些Unix命令失败并显示“… not found”
  • 使用JSch执行的命令与SSH终端的行为不同(绕过确认提示消息“是/”否“)