如何检查文件在 node.js 中是否可执行?
也许像
fs.isExecutable(function (isExecutable) {
})
仅依赖于内置fs
模块的另一个选项是使用fs.access或fs.accessSync。这种方法比获取和解析文件模式更容易。一个例子:
const fs = require('fs');
fs.access('./foobar.sh', fs.constants.X_OK, (err) => {
console.log(err ? 'cannot execute' : 'can execute');
});
在 Node 中fs.stat
方法返回一个fs.Stats
对象,你可以通过 fs.Stats.mode 属性获取文件权限。来自这篇文章:Nodejs 文件权限
看看https://www.npmjs.com/package/executable它甚至有一个 .sync() 方法
executable('bash').then(exec => {
console.log(exec);
//=> true
});
这个版本功能更全面一些。但它确实依赖于which
or where
,它们是操作系统特定的。这包括 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';
}
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
需要检查您是否与文件所有者匹配,或者是否属于某个组。
所以也许最好只使用https://stackoverflow.com/a/41929624/895245fs.accessSync
中提到的繁琐的 raise API :
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'))
它应该为我们做所有这些检查。