2017-11-15 8 views
1

ssh2 npmパッケージを使用してアプリケーションに別のシステムでsudoコマンドを実行させようとしています。私は最終結果が働いているが、何らかの理由でコードが無限ループに陥っている。私はconn.endとの接続を閉じると、これが起こらないようにすると考えていたので、これがどのように可能なのか分かりません。誰もがなぜ私はここに無限ループで立ち往生しているのかについていくつかの光を当てることができますか?シェルを使用しているときにjavascriptのssh2が無限ループに陥る理由

プライマリコードが実行されている:

function sshRunSudoCommand(user, pass, lanIP, command) { 

    return new Promise((resolve, reject) => { 
    var Connection = require('ssh2'); 
    var pwSent  = false; 
    var sudosu  = false; 
    var password = pass; 
    var conn  = new Connection(); 

    conn.on('ready', function() { 
     console.log('Sudo Connection :: ready'); 
     conn.shell(function(err, stream) { 
     if (err) throw err; 
     stream 
      .on('close', function() { 
      console.log('Sudo Stream :: close'); 
      conn.end(); 
      resolve(); 
     }) 
      .on('data', function(data) { 
      //handle sudo password prompt 
      stream.write(password + '\n'); 
      stream.write(command + '\n'); 
      console.log('Sudo STDOUT: ' + data); 
      resolve(data); 
     }) 
      .on('exit', function(code, signal) { 
      let exitCode = 'Stream :: exit :: code: ' + code + ', signal: ' + signal; 
      conn.end(); 
      resolve(exitCode); 
     }) 
      .on('end', function() { 
      conn.end(); 
      resolve('end'); 
      }) 
      .stderr.on('data', function(data) { 
      console.log('STDERR: ' + data); 
      conn.end(); 
      resolve(data); 
     }); 

     }); 
    }) 
     .on('keyboard-interactive', 
     function(name, instructions, instructionsLang, prompts, finish) { 
      // Pass answers to `prompts` to `finish()`. Typically `prompts.length === 1` 
      // with `prompts[0] === "Password: "` 
      console.log('pass before finish is ', pass); 
      finish([pass]); 
     }).on('ready', function() { 
    }).connect({ 
     host: lanIP, 
     port: 22, 
     username: user, 
     password: pass, 
     readyTimeout: 99999, 
     tryKeyboard: true // this attempts keyboard-interactive auth 
    }); 
    }; 
} 

結果:(繰り返し何度も永遠に)

Sudo STDOUT: activedash:~ activeadmin$ s 
Sudo STDOUT: udo 
Sudo STDOUT: profiles -I - 
Sudo STDOUT: F /Users/S 
Sudo STDOUT: hared/Sym 
Sudo STDOUT: ply/activ 
Sudo STDOUT: e-uuid. 
onfigpr 
Sudo STDOUT: ofile 

Sudo STDOUT: active 
sudo profiles -I -F /Users/Shared/Symply/active-uuid.configprofile 
active 
sudo profiles -I -F /Users/Shared/Symply/active-uuid.configprofile 
active 
sudo profiles -I -F /Users/Shared/Symply/active-uuid.configprofile 
active 
sudo profiles -I -F /Users/Shared/Symply/active-uuid.configprofile 
active 
sudo profiles 

答えて

0

それでは、私が見つけたことは、私は繰り返しアクションを防ぐために行うために必要な2つのことがあったました。

  1. 私はその後、私は私の決意()コールバックを移動することができ、私はconn.shell

  2. で作成されたセッションを終了するには、シェルを伝えるためにstream.writeに「終了」コマンドを追加し、するために必要なexitコマンドを正常に実行した後にだけ戻るようにコードの.on( 'exit)セクションに移動します。

最終的なコードは次のようになります。

function sshRunSudoCommand(user, pass, lanIP, command) { 

    return new Promise((resolve, reject) => { 
    var Connection = require('ssh2'); 
    var password = pass; 
    var conn  = new Connection(); 

    conn.on('ready', function() { 
     console.log('Sudo Connection :: ready'); 
     conn.shell(function(err, stream) { 
     if (err) throw err; 
     stream 
      .on('close', function() { 
      console.log('Sudo Stream :: close'); 
      conn.end(); 
      resolve(); 
     }) 
      .on('data', function(data) { 
      //handle sudo password prompt 
      stream.write(password + '\n'); 
      stream.write(command + '\n'); 
      stream.write('exit\n'); 
     }) 
      .on('exit', function(code, signal) { 
      let exitCode = 'Stream :: exit :: code: ' + code + ', signal: ' + signal; 
      conn.end(); 
      resolve(exitCode); 
     }) 
      .on('end', function() { 
      conn.end(); 
      resolve('end'); 
      }) 
      .stderr.on('data', function(data) { 
      console.log('STDERR: ' + data); 
      conn.end(); 
      resolve(data); 
     }); 

     }); 
    }) 
     .on('keyboard-interactive', 
     function(name, instructions, instructionsLang, prompts, finish) { 
      // Pass answers to `prompts` to `finish()`. Typically `prompts.length === 1` 
      // with `prompts[0] === "Password: "` 
      console.log('pass before finish is ', pass); 
      finish([pass]); 
     }).on('ready', function() { 
    }).connect({ 
     host: lanIP, 
     port: 22, 
     username: user, 
     password: pass, 
     readyTimeout: 99999, 
     tryKeyboard: true // this attempts keyboard-interactive auth 
    }); 
    }; 
} 
関連する問題