我该如何将node.js设置为bash的替代品?例如,我应该能够运行
这是否可行?
vi('file')
来打开文件,以及cd('location')
在目录之间切换。这是否可行?
usr/bin/node
,但这样只会得到一个没有其他程序设置的Node.js REPL。你需要做的是编写一个设置脚本,可以为你完成以下所有设置/便利步骤,最终生成一个REPL。当然,由于UNIX shell设置无法指定参数,你需要编写一个小的C程序,使用这些参数执行你的shell(例如exec("/usr/bin/node", "path/to/setup/script.js");
),并将其设置为你的UNIX shell。require()
到你的shell中 - 例如,要执行与文件系统相关的操作,执行以下命令:var fs = require("fs")
并且从fs
对象中进行所有的文件系统调用。这类似于将东西添加到您的PATH中。您可以使用shelljs
或类似的方式获取基本的shell命令,并且要获取实际的可执行程序,可以使用Node内置的child_process.spawnSync
用于前台任务,或者child_process.spawn
用于后台任务。
由于您的要求之一是要像调用函数一样调用每个程序,因此您需要自己编写这些函数,得到类似以下的内容:
function ls(path) {
child_process.spawnSync('/bin/ls', [path], { stdio: 'inherit' });
}
sh
/bash
/zsh
来运行你在互联网上找到的shell命令,而且那些专门调用你的用户shell并期望它与Bash兼容的程序(或者如果你在一个将/bin/sh
链接到你的用户shell的系统上)将不再起作用。但我当然能理解在命令行环境中利用JavaScript的吸引力。
repl.start()
返回的REPLServer
对象具有一个context
对象,该对象与REPL会话创建的全局对象相同。在编写设置脚本时,您需要将所有内容分配给context
对象:const context = repl.start('> ').context;
context.ls = function ls(path) { /* . . . */ }
context.cd = function cd(path) { /* . . . */ }
cd arg1 arg2
和 ls
这样的功能的超集Js语言会很好......我刚意识到我在描述CoffeeScript。 - Ray Foss我认为这将是一个有趣的提议。创建一个测试账户并告诉它使用node作为其shell。参见'man useradd'了解所有选项。
$ useradd -s /usr/bin/node test
$ su - test
这适用于Mac和Linux。
require('child_process').spawnSync('vi', ['file.txt'], { stdio: 'inherit' })
#!/bin/bash
node --experimental-repl-await -i -e "$(< scripts/noderc.js)"`
这使得像以下这样的事情成为可能:
> ls()
> run('vi','file.txt')
> await myAsyncFunc()
我想你正在寻找类似于这个https://youtu.be/rcwcigtOwQ0的东西!
如果是这样... 是的,你可以!
如果你愿意,我可以分享我的代码。但我需要先修复一些错误!
告诉我你是否喜欢。
我的.sh函数:
const hey = Object.create(null),
sh = Object.create(null);;
hey.shell = Object.create(null);
hey.shell.run = require('child_process').exec;
sh.help = 'Execute an OS command';
sh.action = (...args) => {
// repl_ is the replServer
// the runningExternalProgram property is one way to know if I should
// render the prompt and is not needed. I will create a better
// way to do this (action without if/decision)!
repl_.runningExternalProgram = true;
hey.shell.run(args.join(' '),
(...args) => {
['error', 'log'].forEach((command, idx) => {
if (args[idx]) {
console[command](args[idx]);
}
});
repl_.runningExternalProgram = false;
});
};
提示:要进入某个目录,只需更改 process.cwd(当前工作目录)。
提示2:为了避免为每个操作系统程序/命令编写 .sh,您可以在全局对象上使用代理。
vi('file')
来打开一个文件,以及cd('location')
在不同目录之间进行切换。 - Lime