Reputation: 20145
How do I check if a file is executable in node.js?
Maybe something like
fs.isExecutable(function (isExecutable) {
})
Upvotes: 12
Views: 8712
Reputation: 383708
fs.stat
named bitmask mode check with fs.constants.S_IXUSR
Node.js appears to have added those since https://stackoverflow.com/a/16258627/895245 had been written, you can now do:
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'))
Of course, this highlights the fact that it is a bit harder to do an actual "can I execute this file check", since we have three such constants as documented at https://nodejs.org/docs/latest-v17.x/api/fs.html#file-mode-constants:
fs.constants.S_IXUSR
: userfs.constants.S_IXGRP
: groupfs.constants.S_IXOTH
: otheras per:
man 2 chmod
so a full check with stat
requires checking if you match the file owner, or are part of a group.
So perhaps it is better to just use the cumbersome raise API of fs.accessSync
as mentioned athttps://stackoverflow.com/a/41929624/895245 which actually checks if the current user could execute a given file or not:
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'))
which should be doing all those checks for us.
Upvotes: 4
Reputation: 834
This version is a little more fully featured. But it does rely on either which
or where
, which are os specific. This covers Windows and Posix (Mac, Linux, Unix, Windows if Posix layer exposed or Posix tools installed).
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';
}
Upvotes: 1
Reputation: 1022
Another option that relies only on the built-in fs
module is to use either fs.access or fs.accessSync. This method is easier than getting and parsing the file mode. An example:
const fs = require('fs');
fs.access('./foobar.sh', fs.constants.X_OK, (err) => {
console.log(err ? 'cannot execute' : 'can execute');
});
Upvotes: 19
Reputation: 5022
Take a look at https://www.npmjs.com/package/executable it even has a .sync() method
executable('bash').then(exec => {
console.log(exec);
//=> true
});
Upvotes: 2
Reputation: 38821
You would use the fs.stat
call for that.
The fs.stat
call returns a fs.Stats object.
In that object is a mode
attribute. The mode will tell you if the file is executable.
In my case, I created a file and did a chmod 755 test_file
and then ran it through the following code:
var fs = require('fs');
test = fs.statSync('test_file');
console.log(test);
What I got for test.mode
was 33261.
This link is helpful for converting mode
back to unix file permissions equivalent.
Upvotes: 9
Reputation: 6682
In Node the fs.stat
method returns an fs.Stats
object, you can get the file permission through the fs.Stats.mode property. From this post: Nodejs File Permissions
Upvotes: 2