Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/ssh/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java JSch:有没有办法将用户环境变量公开给;执行官;频道_Java_Ssh_Jsch - Fatal编程技术网

Java JSch:有没有办法将用户环境变量公开给;执行官;频道

Java JSch:有没有办法将用户环境变量公开给;执行官;频道,java,ssh,jsch,Java,Ssh,Jsch,我试图运行使用本地Linux逻辑路径的命令,如cat$test\u dir/test.dat,但逻辑路径$test\u dir(这是一个用户环境变量)无法通过ChannelExec获得。但是,当我使用interactiveChannelShell时,我能够看到用户变量和命令在交互会话中正常运行。我只能从“exec”会话查看系统级环境变量。甚至可以使用JSch库吗?如果可以,那么我应该如何实现它?如果不可以,我应该使用什么库来实现它 在下面添加我的班级代码: `公共类SecureShell{ pr

我试图运行使用本地Linux逻辑路径的命令,如
cat$test\u dir/test.dat
,但逻辑路径
$test\u dir
(这是一个用户环境变量)无法通过
ChannelExec
获得。但是,当我使用interactive
ChannelShell
时,我能够看到用户变量和命令在交互会话中正常运行。我只能从“exec”会话查看系统级环境变量。甚至可以使用JSch库吗?如果可以,那么我应该如何实现它?如果不可以,我应该使用什么库来实现它

在下面添加我的班级代码: `公共类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(i<0)
                         break;
                }
                 if(channel.isClosed()){
                     if(in.available()>0) 
                         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();
}
private static final Logger Logger=LogManager.getLogger(SecureShell.class);
私有字符串uName;
私有字符串pWord;
我的私人字符串;
专用int端口;
私有会话=null;
专用通道=空;
/**创建一个实例来启动和停止远程shell,并通过java远程执行命令。
* 
*@param uName
*主机用户名
*@param pWord
*主机密码
*@param-hName
*主机名
*@param端口
*主机端口号
*/
公共SecureShell(字符串uName、字符串pWord、字符串hName、int端口){
this.uName=uName;
this.pWord=pWord;
this.hName=hName;
this.port=端口;
}
/**创建一个实例来启动和停止远程shell,并通过java远程执行命令。
* 
*@param uName
*主机用户名
*@param pWord
*主机密码
*@param-hName
*主机名
*/
公共SecureShell(字符串uName、字符串pWord、字符串hName){
this.uName=uName;
this.pWord=pWord;
this.hName=hName;
这个端口=22;
}
/**启动与主机的会话。
*@返回
*如果会话成功启动,则为true,否则为false
*/
公共布尔startSession(){
JSch JSch=新的JSch();
试一试{
session=jsch.getSession(uName、hName、port);
java.util.Properties config=new java.util.Properties();
配置放置(“检查”、“否”);
session.setConfig(config);
会话设置密码(pWord);
session.connect();
}捕获(JSCHEException jsche){
logger.error(jsche.getMessage());
返回false;
} 
返回true;
}
/**在主机上执行命令;
*@param命令
*要在主机上执行的命令。
*@返回
*执行情况
*/
公共int执行(字符串命令){
int status=-1;
if(session!=null&&session.isConnected()){
试一试{
channel=session.openChannel(“exec”);
//(ChannelExec)channel.setEnv(“LC_XXX”,“xxxxxxx”);
((ChannelExec)channel).setPty(true);
((ChannelExec)channel).setCommand(command);
InputStream in=channel.getInputStream();
channel.connect();
字节[]缓冲区=新字节[1024];
while(true){
while(in.available()>0){
inti=in.read(缓冲区,0,1024);
系统输出打印(新字符串(缓冲区,0,i));
if(i0)
继续;
状态=channel.getExitStatus();
打破
}
}
}捕获(JSCHEException jsche){
logger.error(jsche.getMessage());
}捕获(ioe异常ioe){
logger.error(ioe.getMessage());
}最后{
if(channel!=null&&channel.isConnected())
通道断开();
} 
}
返回状态;
}
/**停止与远程服务器的会话。
* 
*/
公共会话(){
if(session!=null&&session.isConnected())
session.disconnect();
}
公共静态void main(字符串[]args){
SecureShell ssh=新的SecureShell(“用户”、“密码”、“主机名”);
ssh.startSession();
System.out.println(ssh.execute(“env”);
ssh.stopSession();
}
}`默认情况下,JSch中的“exec”通道(正确)不会为会话分配伪终端(PTY)。因此,将(可能)获取一组不同的启动脚本。和/或根据
术语
环境变量的缺失/存在,在脚本中采用不同的分支。因此,环境可能不同于交互式JSch“shell”会话或使用SSH客户端时的环境


解决此问题的方法:

  • 修复启动脚本,将交互式和非交互式会话的环境变量设置为相同

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

    Channel channel=session.openChannel("exec");
    ((ChannelExec)channel).setPty(true);
    
    使用伪终端自动执行命令可能会带来严重的副作用。例如,见


  • 有关类似问题的详细信息,请参阅


      • 由于您没有打开交互式shell,因此不会设置环境变量。但是,您可以将bash命令与--login(manbash了解更多详细信息)一起使用,以获得所需的结果

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

        我可以通过在.bashrc文件中设置环境变量来解决这个问题。通过setEnv方法设置环境变量对我没有帮助。

        我尝试将pty设置为true,并使用下面给出的命令在远程服务器中运行环境脚本,但仍然无法使用其他可用的逻辑路径。我使用的命令是“sh environment.sh&&env”@user3221714:
        sh environment.sh&&env
        创建一个新的shell进程,称为sh#2,它执行脚本
        environment.sh
        ,该脚本可能会设置一些环境变量。然后,sh#2成功退出,其内存被丢弃。然后,原始shell创建一个
        env
        进程,该进程将看到原始shell未更改的一组envvar