SSH与nodejs

时间:2017-06-02 02:54:37

标签: javascript node.js ssh

尝试在使用api创建的新vps上创建文件等。由于某种原因,此函数不运行第二个ssh命令。在运行此功能之前,还运行另一个在安装文件之前发送一些命令来安装软件包。我在定时器用完后运行该函数,以便它可以使用一些软件包来运行像屏幕这样的命令。它运行第一个ssh而不是第二个ssh,我尝试使用计时器最多180秒。

function CreateServer( SIP, GUSER, SPORT ) {
var CDir = "";
var RPassword = generator.generate({
    length: 10,
    numbers: true
});
var ssh = new SSH({
    host: SIP,
    user: 'root',
    key: fs.readFileSync('serverkey.ppk')
    //pass: 'password'
});

ssh.exec('if test -d /home/' + GUSER + '; then echo "exist"; fi', {
    out: function(stdout) {
        CDir = stdout;
        //console.log(stdout);
    }
}).start();
setTimeout(function(){
    if(CDir == DMkdir) {
        console.log("User on machine not adding......");
        ssh.exec('chown -R ' + GUSER + ':' + GUSER + ' /home/' + GUSER + '; su - ' + GUSER + ' -c "cd /home/' + GUSER + '/steamcmd ; screen -mdSL ' + SIP + ':' + SPORT + ' ./steamcmd.sh +login anonymous +force_install_dir /home/' + GUSER + '/' + SIP + '.' + SPORT + ' +app_update 4020 validate +quit"', {
            out: function(stdout) {
                //console.log(stdout);
            }
        }).start();             
    } else {
        console.log("User not on machine adding......");
        ssh.exec('cd /home/; sudo adduser ' + GUSER + ' --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password; echo "' + GUSER + ':' + RPassword + '" | sudo chpasswd; cd /home/' + GUSER + '/; mkdir steamcmd; cd /home/' + GUSER + '/steamcmd; wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz; tar -xvzf steamcmd_linux.tar.gz; chown -R ' + GUSER + ':' + GUSER + ' /home/' + GUSER + '; su - ' + GUSER + ' -c "cd /home/' + GUSER + '/steamcmd ; screen -mdSL ' + SIP + ':' + SPORT + ' ./steamcmd.sh +login anonymous +force_install_dir /home/' + GUSER + '/' + SIP + '.' + SPORT + ' +app_update 4020 validate +quit"', {
            out: function(stdout) {
                console.log(stdout);
            }
        }).start();
    }
}, 5 * 1000);
return true;

}

1 个答案:

答案 0 :(得分:0)

除了处理两个异步事件的问题之外,我假设一切都是正确的。鉴于我无法看到DMkdir的来源以及您的其他代码的上下文,我假设它就像CDir一样,它的值是异步设置的。

假设您使用的是最新版本的节点,该节点使用本地承诺(如节点版本6及更高版本),则以下代码将适用于您。如果您没有使用更新版本的节点,则可以使用诸如bluebirdQ之类的承诺库,这将涉及不同的语法,但它将以类似的方式解决。

function sshPromise (string) {
    new Promise((resolve, reject) => {
      ssh.exec(string, {
          // on correct output the promise needs to be 
          // resolved by calling the resolve function with the data
          out: resolve
          // not sure what the error property is but it needs 
          // to reject the promise with the error data
          onError: reject
      }).start();
    });
}

var CDirPromise = sshPromise('if test -d /home/' + GUSER + '; then echo "exist"; fi');

var DMkdirPromise = sshPromise('whatever command you did for this one obviously not this string');

Promise.all([CDirPromise, DMkdirPromise]).then(function ([CDir, DMKdir]) {
    // this then method will fire when all the promises resolve.
    if(CDir == DMkdir) {
        console.log("User on machine not adding......");
        ssh.exec('chown -R ' + GUSER + ':' + GUSER + ' /home/' + GUSER + '; su - ' + GUSER + ' -c "cd /home/' + GUSER + '/steamcmd ; screen -mdSL ' + SIP + ':' + SPORT + ' ./steamcmd.sh +login anonymous +force_install_dir /home/' + GUSER + '/' + SIP + '.' + SPORT + ' +app_update 4020 validate +quit"', {
            out: function(stdout) {
                //console.log(stdout);
            }
        }).start();             
    } else {
        console.log("User not on machine adding......");
        ssh.exec('cd /home/; sudo adduser ' + GUSER + ' --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password; echo "' + GUSER + ':' + RPassword + '" | sudo chpasswd; cd /home/' + GUSER + '/; mkdir steamcmd; cd /home/' + GUSER + '/steamcmd; wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz; tar -xvzf steamcmd_linux.tar.gz; chown -R ' + GUSER + ':' + GUSER + ' /home/' + GUSER + '; su - ' + GUSER + ' -c "cd /home/' + GUSER + '/steamcmd ; screen -mdSL ' + SIP + ':' + SPORT + ' ./steamcmd.sh +login anonymous +force_install_dir /home/' + GUSER + '/' + SIP + '.' + SPORT + ' +app_update 4020 validate +quit"', {
            out: function(stdout) {
                console.log(stdout);
            }
        }).start();
    }
}).catch(function (err) {
    // handle the error one of the promises rejected.
});

你也应该对错误进行处理(当说ssh.exec时应该有办法处理错误输出我只是猜到它是onError但是你应该把它改成实际的错误。我不知道你正在使用什么ssh库所以我猜它是onError。)因为你的代码目前似乎没有检查是否会抛出错误。

我会写一些关于承诺的内容。它们非常适合发生一次的异步事件。他们也擅长处理这些异步事件的错误。承诺有三种状态:'待定'这是一个未完成的状态,已经解决了#39;这是一个成功的完成状态,或被拒绝,这是一个可能由错误引起的不成功的完成状态。您可以使用.then方法处理承诺中的已解决值,并使用.catch方法处理被拒绝的值。

我建议阅读以下关于Promises的链接,以真正掌握它们。

祝你好运。 :)

编辑:

根据评论,这个问题相当简单。所有你真正需要做的就是在ssh.exec的out属性上提供CDir之后,让你的函数运行。

ssh.exec('if test -d /home/' + GUSER + '; then echo "exist"; fi', {
    out: function (CDir) {
        if(CDir == DMkdir) {
            console.log("User on machine not adding......");
            ssh.exec('chown -R ' + GUSER + ':' + GUSER + ' /home/' + GUSER + '; su - ' + GUSER + ' -c "cd /home/' + GUSER + '/steamcmd ; screen -mdSL ' + SIP + ':' + SPORT + ' ./steamcmd.sh +login anonymous +force_install_dir /home/' + GUSER + '/' + SIP + '.' + SPORT + ' +app_update 4020 validate +quit"', {
                out: function(stdout) {
                    //console.log(stdout);
                }
            }).start();             
        } else {
            console.log("User not on machine adding......");
            ssh.exec('cd /home/; sudo adduser ' + GUSER + ' --gecos "First Last,RoomNumber,WorkPhone,HomePhone" --disabled-password; echo "' + GUSER + ':' + RPassword + '" | sudo chpasswd; cd /home/' + GUSER + '/; mkdir steamcmd; cd /home/' + GUSER + '/steamcmd; wget https://steamcdn-a.akamaihd.net/client/installer/steamcmd_linux.tar.gz; tar -xvzf steamcmd_linux.tar.gz; chown -R ' + GUSER + ':' + GUSER + ' /home/' + GUSER + '; su - ' + GUSER + ' -c "cd /home/' + GUSER + '/steamcmd ; screen -mdSL ' + SIP + ':' + SPORT + ' ./steamcmd.sh +login anonymous +force_install_dir /home/' + GUSER + '/' + SIP + '.' + SPORT + ' +app_update 4020 validate +quit"', {
                out: function(stdout) {
                    console.log(stdout);
                }
            }).start();
        }
    }
}).start();