Javascript 带nodejs的SSH

Javascript 带nodejs的SSH,javascript,node.js,ssh,Javascript,Node.js,Ssh,试图在使用api创建的新VP上创建文件等。由于某些原因,此函数不运行第二个ssh命令。在运行这个函数之前,还有一个函数也在运行,它在安装文件之前发送一些命令来安装软件包。我有一个在计时器用完后运行的函数,这样它就可以使用一些包来运行screen之类的命令。它运行第一个ssh,但不运行第二个ssh,我已经尝试使用长达180秒的计时器 function CreateServer( SIP, GUSER, SPORT ) { var CDir = ""; var RPassword = generat

试图在使用api创建的新VP上创建文件等。由于某些原因,此函数不运行第二个ssh命令。在运行这个函数之前,还有一个函数也在运行,它在安装文件之前发送一些命令来安装软件包。我有一个在计时器用完后运行的函数,这样它就可以使用一些包来运行screen之类的命令。它运行第一个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;

}

除了处理两个异步事件的问题之外,我假设一切都是正确的。考虑到我看不到
DMkdir
来自何处,以及您的其他代码的上下文,我假设它的值与
CDir
一样是异步设置的

假设您使用的是node的最新版本,该版本使用了node版本6及更高版本等本机承诺,那么以下代码将适用于您。如果您不使用较新版本的node,则可以使用类似或的promise库,它将涉及不同的语法,但将以类似的方式解决

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
)目前,您的代码似乎没有检查抛出的错误

我会写一些关于承诺的东西。它们非常适合于只发生一次的异步事件。他们还擅长处理这些异步事件的错误。承诺有三种状态:“待定”为未完成状态,“已解决”为成功完成状态,或“拒绝”为可能由错误导致的不成功完成状态。您可以使用
方法处理承诺中已解析的值,然后使用
方法处理已拒绝的值,并使用
方法处理已拒绝的值

我建议阅读下面关于承诺的链接,真正了解承诺

祝你好运

编辑: 根据评论,问题要简单得多。您真正需要做的就是在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();

除了处理两个异步事件的问题之外,我假设一切都是正确的。考虑到我看不到
DMkdir
来自何处,以及您的其他代码的上下文,我假设它的值与
CDir
一样是异步设置的

假设您使用的是node的最新版本,该版本使用了node版本6及更高版本等本机承诺,那么以下代码将适用于您。如果您不使用较新版本的node,则可以使用类似或的promise库,它将涉及不同的语法,但将以类似的方式解决

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
)目前,您的代码似乎没有检查抛出的错误

我会写一些关于承诺的东西。它们非常适合于只发生一次的异步事件。他们还擅长处理这些异步事件的错误。承诺有三种状态:“待定”为未完成状态,“已解决”为成功完成状态,或“拒绝”为可能由错误导致的不成功完成状态。您可以使用
方法处理承诺中已解析的值,然后使用
方法处理已拒绝的值,并使用
方法处理已拒绝的值

我建议阅读下面关于承诺的链接,真正了解承诺

祝你好运

编辑: 根据评论,问题要简单得多。您真正需要做的就是在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();

有可能它正在写信给stderr,而你没有对此做出解释,但也可能是你的信息还没有回来。如果是后者,我有一个可能对你有用的答案,我正在写。有可能是写给stderr的,你没有解释,但也可能是你的信息还没有回来。如果是后者,我有一个可能对你有用的答案,我正在写。DMkdir只是一个字符串。删除承诺中的承诺会改变什么吗?@RaulGonzales不,事实上,如果DMkdir不是一个随时间设置的值,那么这是一个简单得多的解决方案。所以它只是一个字符串,但您是否直接设置它,而不在不同的时间设置?它直接从appOkay开始设置。我将相应地更新我的答案@RaulGonzales@RaulGonzales我已经更新了我的答案。我认为这应该对你有用。DMkdir只是一个字符串。删除承诺中对该字符串的承诺会改变什么吗?@RaulGonzales不,事实上,如果DMkdir不是一个随时间设置的值,那么这是一个简单得多的解决方案。所以它只是一个字符串,但您是否直接设置它,而不在不同的时间设置?它直接从appOkay开始设置。我将相应地更新我的答案@RaulGonzales@RaulGonzales我已经更新了我的答案。我想这对你应该有用。