Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 6 years ago.
Improve this question
Is there anything similar to Microsoft Powershell (an object-oriented shell built on the .NET framework) for Linux (possibly built on Java, GObject, or its own object type/nothing)?
edit: especially if similar to bash or powershell or cmd etc. syntax (=''standard'' shell syntax)
Python. No joking.
Scripting languages are scripting languages, and Python is a particularly nice one that many people find very approachable.
Even though this question is pretty old, I think its worth mentioning that in August 2016 Microsoft made Powershell open-source and cross platform. Instructions for installation are on github.
https://github.com/PowerShell/PowerShell
Perl, Python, and Ruby
Ok, I'm sure you already know that, but someone had to say it.
Perl is the oldest and most popular.
If you like objects, you will probably love Ruby. It has an elaborate object system inspired by Smalltalk.
Python has this cool block-structure-by-indent syntax.
Unix is a gold mine of advanced scripting tools...
Hotwire
NodeJS can do that, in fact it's one of the samples included in the download. Use it interactively, or (probably more usefully) write shell scripts in JavaScript.
For example:
#!/usr/local/bin/node
var sys = require('sys'),
exec = require('child_process').exec;
// Run `ls`:
exec('ls -lh /usr', function(error, output, erroutput) {
sys.print('output: ' + output);
sys.print('erroutput: ' + erroutput);
});
...but that's just the high-level interface that buffers all the output for you, etc. You can get a lot more down and dirty than that if you like.
NodeJS takes asynchronicity as the normal state of affairs, and so if you want a "traditional" shell script, you may find it's not a good match as it doesn't (as of this writing, as far as I know) offer a synchronous version of exec. So an ad hoc series of serial statements becomes an exercise in callbacks:
exec('first_command', function(error) {
if (error != null) {
exec('second_command', function(error) {
if (error != null) {
// ....
}
});
}
});
...but of course, you can create a function that handles that for you and takes (say) an array of sequential statements to execute (and then install it as a module via Node's module sysstem). So for instance:
#!/usr/local/bin/node
var sys = require('sys'),
exec = require('child_process').exec;
execSeries([
'ls -ld /usr',
'foobar',
'ls -ld /etc'
], {echo: true}, function(results) {
sys.print("Done\n");
});
// ===> This would be in a module, not in the script itself <===
function execSeries(series, options, callback) {
var index = 0,
results = [];
// Make 'options' optional
if (!callback && typeof options === "function") {
callback = options;
options = undefined;
}
// Default options
options = options || {};
// Go
callNext();
function callNext() {
if (index >= series.length) {
// Done
callback(results);
}
else {
// Call the next one
exec(series[index++], function(error, stdout, stderr) {
// Record result
results.push({error: error, stdout: stdout, stderr: stderr});
// Echo?
if (options.echo) {
if (error == null) {
sys.print(stdout);
}
else {
sys.print("Error: " + error + "\n");
}
}
// Stop on error?
if (options.breakOnError && error != null) {
// Yes, and there was an error; stop
callback(results);
}
else {
// No, continue
callNext();
}
});
}
}
}
You should rethink why it is you think you need an object-oriented shell. That said, if you're set trying weird shells you can't go wrong with zoid. Unlike many of the other suggestions I see here it really is a shell. On the other hand, if you don't know or don't like Perl you probably won't be happy.
jq is not quite an object-oriented shell, but it provides some of the benefits which object-oriented shells may have; I use it a lot, together with shell scripts, for such tasks.
Related
I have a script setupDB.js that runs asynchronously and is intended to be called from command line. Recently, I added test cases to my project, some of which require a database to be set up (and thus the execution of aforementioned script).
Now, I would like to know when the script has finished doing its thing. At the moment I'm simply waiting for a few seconds after requiring setupDB.js before I start my tests, which is obviously a bad idea.
The problem with simply exporting a function with a callback parameter is that it is important that the script can be run without any overhead, meaning no command line arguments, no additional function calls etc., since it is part of a bigger build process.
Do you have any suggestions for a better approach?
I was also looking for this recently, and came across a somewhat-related question: "Node.JS: Detect if called through require or directly by command line
" which has an answer that helped me build something like the following just a few minutes ago where the export is only run if it's used as a module, and the CLI library is only required if ran as a script.
function doSomething (opts) {
}
/*
* Based on
* https://stackoverflow.com/a/46962952/7665043
*/
function isScript () {
return require.main && require.main.filename === /\((.*):\d+:\d+\)$/.exec((new Error()).stack.split('\n')[ 2 ])[ 1 ]
}
if (isScript) {
const cli = require('some CLI library')
opts = cli.parseCLISomehow()
doSomething(opts)
} else {
module.exports = {
doSomething
}
}
There may be some reason that this is not a good idea, but I am not an expert.
I have now handled it this way: I export a function that does the setup. At the beginning I check if the script has been called from command line, and if so, I simply call the function. At the same time, I can also call it directly from another module and pass a callback.
if (require.main === module) {
// Called from command line
runSetup(function (err, res) {
// do callback handling
});
}
function runSetup(callback) {
// do the setup
}
exports.runSetup = runSetup;
make-runnable npm module can help with this.
As the title suggests, I need to find a way to get the list of running applications (atom, chrome, etc.). I am currently using:
var exec = require('child_process').exec
exec('tasklist', (error, stdout, stderr) {
// stdout contains a list of running processes.
})
However this also gives services and hidden applications (redis-server, etc.) and doesn't return whether or not the window is currently active or not. Is there a way for this to be done? For reference, this is for a Windows system, but a cross-operating system solution would be preferable.
I found the wonderful winctl library allowed me to do what I needed. I used the following code:
const winctl = require('winctl')
// Iterate over all windows with a custom filter
winctl.FindWindows(win => win.isVisible() && win.getTitle()).then(windows => {
console.log("Visible windows:");
windows.sort((a,b) => a.getTitle().localeCompare(b.getTitle())).forEach(window => console.log(" - %s [pid=%d, hwnd=%d, parent=%d]", window.getTitle(), window.getPid(), window.getHwnd(), window.getParent()));
});
EDIT: I am using the twitch-irc library from Github for Node.js, installed via npm.
This is such a basic question and I feel like a bit of an idiot for asking, but...
if (message.toLowerCase().indexOf('!os') === 0) {
}
Let's say I used this code, how would I add if statements for the arguments that the user provides? By this, I mean after typing !os, they would create a space and type something else, this would either be the 0th or 1st argument.
Would it be possible to just use this?:
if (message.toLowerCase().indexOf('kernel') === 4) {
}
In pseudo code, I want to do:
if (firstargument === 'kernel') {
//Do stuff.
}
Thank you for your time.
You could simply use var args = message.match(/\S+/g) to get all the arguements (including '!os') in an array and use them as you wish.
e.g.
var args = message.match(/\S+g/);
var cmd = args[1]; //do a length check before accessing args[1] though
switch (cmd) {
case 'kernel':
// do stuff
break;
case 'process':
// do stuff
break;
default:
// invalid command
}
What you said would make sense to do, but you should remove white space (spaces) so that a command like !os kernel will still work (note the two spaces).
Do that like this:
if (message.replace(/\s\g, '').toLowerCase().indexOf('kernel') === 3) {
//Do stuff
}
When using gulp. Is there any way to suppress the 'Started' and 'Finished' log entries for certain tasks? I want to use the dependency tree, but I have a few tasks in the tree that I don't want logging for because they are intermediary steps that have their own logging facilities.
You can use the --silent flag with the gulp CLI to disable all gulp logging.
https://github.com/gulpjs/gulp/blob/master/docs/CLI.md
[UPDATE]
As of July 2014, a --silent option has been added to gulp (https://github.com/gulpjs/gulp/commit/3a62b2b3dbefdf91c06e523245ea3c8f8342fa2c#diff-6515adedce347f8386e21d15eb775605).
This is demonstrated in #slamborne answer below, and you should favor using it instead of the below solution if it matches your use case.
[/UPDATE]
Here is a way of doing it (inside your gulpfile):
var cl = console.log;
console.log = function () {
var args = Array.prototype.slice.call(arguments);
if (args.length) {
if (/^\[.*gulp.*\]$/.test(args[0])){
return;
}
}
return cl.apply(console, args);
};
... and that will ignore EVERY message sent using gutil.log.
The trick here obviously is to inspect messages sent to console.log for a first argument that looks like "[gulp]" (see gulp.util.log source code) and eventually ignore it entirely.
Now, this really is dirty - you really shouldn't do that without parental supervision, and you have been warned :-)
Bit late but i think it would be better to use noop from gulp-util no?
var gutil = require('gulp-util');
// ...
gutil.log = gutil.noop;
// or
gutil.log = function() { return this; };
As addressed here
Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
We don’t allow questions seeking recommendations for books, tools, software libraries, and more. You can edit the question so it can be answered with facts and citations.
Closed 3 years ago.
Improve this question
I want to achieve below goals:
Read a MP3 metadata
Modify the encoding of that metadata (if I could modify the content of that metadata, that would be better)
Save the modification to that MP3 file
All these operations could be based on native Node.js (without browser). Is there any module provide such function or I can develop based on?
For those coming to this question through Google, there is a node module that can do this, both read and write metadata:
https://www.npmjs.org/package/ffmetadata
I don't know whether there's a way to actually do the meta data manipulation in NodeJS. This is a work around way but you could do this using child_process.exec and perl:
NodeJS Code
var exec = require('child_process').exec,
child;
child = exec('perl changeTags.pl file.mp3',
function (error, stdout, stderr) {
console.log('stdout: ' + stdout);
console.log('stderr: ' + stderr);
if (error !== null) {
console.log('exec error: ' + error);
}
});
Perl code
#!/usr/bin/perl
use MP3::Tag;
$mp3 = MP3::Tag->new(#ARGV[0]); # create object
$mp3->get_tags(); # read tags
print "Attempting to print tags for #ARGV[0]\n";
if (exists $mp3->{ID3v2}) {
print "Comments: " . $mp3->{ID3v2}->comment . "\n";
print "Zip: " . $mp3->{ID3v2}->album . "\n";
print "Tags: " . $mp3->{ID3v2}->title . "\n";
} else {
print "#ARGV[0] does not have ID3v2 tags\n";
}
$mp3->close(); # destroy object
Something like that. You'd obviously want to give more arguments for what you actually want to change the meta data to.... Good luck!
So far i found jsmediatags is best npm package to read ID3v2 tags
var jsmediatags = require("jsmediatags");
jsmediatags.read("./song.mp3", {
onSuccess: function(tag) {
console.log(tag);
},
onError: function(error) {
console.log(':(', error.type, error.info);
}
});