【问题标题】:node.js how to check a process is running by the process name?node.js 如何通过进程名称检查进程是否正在运行?
【发布时间】:2020-12-29 16:06:33
【问题描述】:

我在 linux 中运行 node.js,从 node.js 如何从进程名称检查进程是否正在运行? 最坏的情况我使用 child_process,但想知道是否有更好的方法?

谢谢!

【问题讨论】:

    标签: node.js


    【解决方案1】:

    你可以使用 ps-node 包。

    https://www.npmjs.com/package/ps-node

    var ps = require('ps-node');
    
    // A simple pid lookup 
    ps.lookup({
        command: 'node',
        psargs: 'ux'
        }, function(err, resultList ) {
        if (err) {
            throw new Error( err );
        }
    
        resultList.forEach(function( process ){
            if( process ){
                console.log( 'PID: %s, COMMAND: %s, ARGUMENTS: %s', process.pid, process.command, process.arguments );
            }
        });
    });
    

    我相信你会看到这个例子。查看该站点,它们还有很多其他用途。试试看吧。

    如果你没有绑定到 nodejs,你也可以从 linux 命令行执行ps -ef | grep "YOUR_PROCESS_NAME_e.g._nodejs" 来检查正在运行的进程。

    【讨论】:

    • 这将如何在windws上工作。我认为它会在 Windows 上出错
    • @Shyam 在ps-node 主页上宣传。它“应该”在 Windows 上工作。如果没有,那么也许值得一个 github 问题。
    • 注意:此模块需要安装其他软件。这可能不适用于未安装正确工具的系统或容器。
    【解决方案2】:

    d_scalzi 对代码进行了一些改进。使用回调而不是 Promise 的函数,只有一个变量查询并且使用 switch 而不是 if/else。

    const exec = require('child_process').exec;
    
    const isRunning = (query, cb) => {
        let platform = process.platform;
        let cmd = '';
        switch (platform) {
            case 'win32' : cmd = `tasklist`; break;
            case 'darwin' : cmd = `ps -ax | grep ${query}`; break;
            case 'linux' : cmd = `ps -A`; break;
            default: break;
        }
        exec(cmd, (err, stdout, stderr) => {
            cb(stdout.toLowerCase().indexOf(query.toLowerCase()) > -1);
        });
    }
    
    isRunning('chrome.exe', (status) => {
        console.log(status); // true|false
    })
    

    【讨论】:

    • 这个在所有平台上都像魔术一样工作。谢谢!
    • 投反对票。此函数将始终在 mac 上返回 true,因为会有进程 'px -ax | grep {查询}'
    • 在linux平台下如何查看isRunning功能,软件名称如chrome.exe
    【解决方案3】:

    以下应该有效。将根据操作系统生成一个进程列表,并将该输出解析为所需的程序。该函数接受三个参数,每个参数只是相应操作系统上的预期进程名称。

    根据我的经验,ps-node 需要太多的内存和时间来搜索进程。如果您计划经常检查进程,此解决方案会更好。

    const exec = require('child_process').exec
    
    function isRunning(win, mac, linux){
        return new Promise(function(resolve, reject){
            const plat = process.platform
            const cmd = plat == 'win32' ? 'tasklist' : (plat == 'darwin' ? 'ps -ax | grep ' + mac : (plat == 'linux' ? 'ps -A' : ''))
            const proc = plat == 'win32' ? win : (plat == 'darwin' ? mac : (plat == 'linux' ? linux : ''))
            if(cmd === '' || proc === ''){
                resolve(false)
            }
            exec(cmd, function(err, stdout, stderr) {
                resolve(stdout.toLowerCase().indexOf(proc.toLowerCase()) > -1)
            })
        })
    }
    
    isRunning('myprocess.exe', 'myprocess', 'myprocess').then((v) => console.log(v))

    【讨论】:

      【解决方案4】:

      这是其他答案的另一个版本,带有 TypeScript 和 Promise:

      export async function isProcessRunning(processName: string): Promise<boolean> {
        const cmd = (() => {
          switch (process.platform) {
            case 'win32': return `tasklist`
            case 'darwin': return `ps -ax | grep ${processName}`
            case 'linux': return `ps -A`
            default: return false
          }
        })()
      
        return new Promise((resolve, reject) => {
          require('child_process').exec(cmd, (err: Error, stdout: string, stderr: string) => {
            if (err) reject(err)
      
            resolve(stdout.toLowerCase().indexOf(processName.toLowerCase()) > -1)
          })
        })
      }
      
      const running: boolean = await isProcessRunning('myProcess')
      

      【讨论】:

        【解决方案5】:

        对于相关主题,这里有一些最好的包:

        按 pid、名称模式和不同方式搜索包:

        仅通过 pid 进行检查

        查找过程示例

        按名称搜索

        const processesList = await findProcess(
            'name',
            /.*?\/kidoAgent\/Broker\/process.js.*/ // regex pattern
        );
        
        console.log({ processesList });
        
        if (processesList.length === 0) {
             /**
              * No process
              * (create it)
              */
             // ......
        }
        

        它将找到的进程列表作为数组返回!

        运行时,console.log({ processesList }); 会显示:

        {
          processesList: [
            {
              pid: 7415,
              ppid: 2451,
              uid: 1000,
              gid: 1000,
              name: 'node',
              bin: '/opt/node-v12.4.0-linux-x64/bin/node',
              cmd: '/opt/node-v12.4.0-linux-x64/bin/node ' +
                '/home/coderhero/Dev/.../build/.../kidoAgent/Broker/process.js'
            }
          ]
        }
        

        检查模块的所有选项和方式!

        【讨论】:

        • is-running 是这里最好的模块,因为它不需要安装外部程序即可工作。
        • 如果你只需要通过 pid 检查
        【解决方案6】:

        @musatin 解决方案的另一个改进是使用自调用 switch 语句而不是重新分配 let

        /**
         * 
         * @param {string} processName The executable name to check
         * @param {function} cb The callback function
         * @returns {boolean} True: Process running, else false
         */
          isProcessRunning(processName, cb){
              const cmd = (()=>{
                  switch (process.platform) {
                      case 'win32' : return `tasklist`;
                      case 'darwin' : return `ps -ax | grep ${processName}`;
                      case 'linux' : return `ps -A`;
                      default: return false;
                  }
              })();
              require('child_process').exec(cmd, (err, stdout, stderr) => {
                  cb(stdout.toLowerCase().indexOf(processName.toLowerCase()) > -1);
              });
          }
        

        cmd 将被分配 switch 语句的结果并生成更易于阅读的代码(特别是如果涉及更复杂的代码,自调用 switch 语句意味着您只创建您需要和不需要的变量精神上跟踪他们的价值观可能是什么)。

        【讨论】:

          猜你喜欢
          • 2010-12-21
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2010-09-14
          • 2015-05-28
          相关资源
          最近更新 更多