【问题标题】:How do I check if a file is executable in node.js?如何检查文件在 node.js 中是否可执行?
【发布时间】:2013-04-21 22:25:56
【问题描述】:

如何在 node.js 中检查文件是否可执行?

可能是这样的

fs.isExecutable(function (isExecutable) {

})

【问题讨论】:

    标签: node.js filesystems


    【解决方案1】:

    在Node中fs.stat方法返回一个fs.Stats对象,你可以通过fs.Stats.mode属性获取文件权限。来自这篇文章:Nodejs File Permissions

    【讨论】:

      【解决方案2】:

      您可以使用fs.stat 调用。

      fs.stat 调用返回一个fs.Stats 对象。

      在那个对象中有一个mode 属性。该模式会告诉你文件是否可执行。

      就我而言,我创建了一个文件并执行了chmod 755 test_file,然后通过以下代码运行它:

      var fs = require('fs');
      test = fs.statSync('test_file');
      console.log(test);
      

      test.mode 我得到的是 33261。

      This link 有助于将mode 转换回等效的 unix 文件权限。

      【讨论】:

      • 还有一个非常有用的模块mode-to-permissions——如果你不想弄乱细节的话。
      • 对,我会赞成这个,如果它解释了如何在给定模式下找出文件是可执行的
      • 他们已经在标准库 BTW 中添加了像 fs.constants.S_IXUSR 这样的常量:stackoverflow.com/a/69897809/895245
      【解决方案3】:

      看看https://www.npmjs.com/package/executable,它甚至有一个 .sync() 方法

      executable('bash').then(exec => {
          console.log(exec);
          //=> true 
      });
      

      【讨论】:

        【解决方案4】:

        另一个仅依赖于内置fs 模块的选项是使用fs.accessfs.accessSync。这种方法比获取和解析文件模式更容易。一个例子:

        const fs = require('fs');
        
        fs.access('./foobar.sh', fs.constants.X_OK, (err) => {
            console.log(err ? 'cannot execute' : 'can execute');
        });
        

        【讨论】:

        • 读/写,还是执行?我们需要能够执行文件
        • 好点。我更新了示例以匹配特定问题。
        【解决方案5】:

        这个版本功能更全面一些。但它确实依赖于特定于操作系统的whichwhere。这包括 Windows 和 Posix(Mac、Linux、Unix、Windows,如果 Posix 层暴露或安装了 Posix 工具)。

        const fs = require('fs');
        const path = require('path');
        const child = require("child_process");
        
        function getExecPath(exec) {
          let result;
          try {
            result = child.execSync("which " + exec).toString().trim();
          } catch(ex) {
            try {
              result = child.execSync("where " + exec).toString().trim();
            } catch(ex2) {
              return;
            }
          }
          if (result.toLowerCase().indexOf("command not found") !== -1 ||
              result.toLowerCase().indexOf("could not find files") !== -1) {
            return;
          }
          return result;
        }    
        
        
        function isExec(exec) {
          if (process.platform === "win32") {
            switch(Path.GetExtension(exec).toLowerCase()) {
              case "exe": case "bat": case "cmd": case "vbs": case "ps1": {
                return true;
              }
            }
          }
          try {
            // Check if linux has execution rights
            fs.accessSync(exec, fs.constants.X_OK);
            return true;
          } catch(ex) {
          }
          // Exists on the system path
          return typeof(getExecPath(exec)) !== 'undefined';
        }
        

        【讨论】:

          【解决方案6】:

          fs.stat 命名位掩码模式检查与fs.constants.S_IXUSR

          Node.js 似乎在编写 https://stackoverflow.com/a/16258627/895245 后添加了这些,您现在可以这样做:

          const fs = require('fs');
          
          function isExec(p) {
            return !!(fs.statSync(p).mode & fs.constants.S_IXUSR)
          }
          
          console.log(isExec('/usr/bin/ls'))
          console.log(isExec('/dev/random'))
          

          当然,这突出了一个事实,即执行实际的“我可以执行此文件检查吗”有点困难,因为我们有三个这样的常量,如 https://nodejs.org/docs/latest-v17.x/api/fs.html#file-mode-constants 所述:

          • fs.constants.S_IXUSR:用户
          • fs.constants.S_IXGRP:群
          • fs.constants.S_IXOTH:其他

          根据:

          man 2 chmod
          

          因此,使用 stat 进行全面检查需要检查您是否与文件所有者匹配,或者是否属于某个组。

          所以也许最好只使用fs.accessSync 中提到的繁琐的 raise API,就像在 https://stackoverflow.com/a/41929624/895245 中提到的那样:

          const fs = require('fs');
          
          function isExec(p) {
            try {
              fs.accessSync(p, fs.constants.X_OK)
              return true
            } catch (e) {
              return false
            }
          }
          
          console.log(isExec('/usr/bin/ls'))
          console.log(isExec('/dev/random'))
          

          它应该为我们做所有这些检查。

          【讨论】:

            猜你喜欢
            • 2013-05-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-04-08
            • 1970-01-01
            相关资源
            最近更新 更多