如何手动写一个命令行工具?

本文介绍了如何手动创建一个命令行工具,包括编写基础逻辑、使用commander解析命令行参数、命令行美化及发布npm包的步骤。通过commander库实现选项和命令的定义,利用co-prompt获取用户输入,结合readline、chalk和figlet进行命令行提示的美化。最后详细阐述了发布npm包的流程。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


前言

如何手动写一个命令行甚至说发布一个npm包,这涉及到所需要提供服务的接口和优雅的命令行外观,本文将分为两部分去介绍构建命令行工具的方法。


提示:以下是本篇文章正文内容,下面案例可供参考

一、一个最简单的命令行工具

如何在命令行中输入一条命令,使它返回一句话?
首先我们需要建立一个文件夹,并在文件夹中npm init,建立一个index.js文件,在该文件中编写主要逻辑代码。

#!/usr/bin/env node
console.log('hello,world!')

/usr/bin/env就是告诉系统可以在PATH目录中查找。 所以配置#!/usr/bin/env node, 就是解决了不同的用户node路径不同的问题,可以让系统动态的去查找node来执行你的脚本文件。

要不要加–harmony?
文档里这么说,windows下不支持这么做。这个写法一般用于一些子命令的脚本中。

Use #! /usr/bin/env node --harmony in the subcommands scripts. (Note Windows does not support this pattern.)
Use the --harmony option when call the command, like node --harmony examples/pm publish. The --harmony option will be preserved when spawning subcommand process.

修改package.json

{
  "name": "mycli",
  "version": "1.0.0",
  "description": "",
  "main": "index.js",
  "scripts": {
    "test": "echo \"Error: no test specified\" && exit 1"
  },
  "author": "",
  "bin":{
    "hi":"./index.js"
  },
  "license": "ISC"
}

二、命令行解析工具

1.commander

文档地址:https://www.npmjs.com/package/commander

(1)option

Options are defined with the .option() method, also serving as documentation for the options. Each option can have a short flag (single character) and a long name, separated by a comma or space or vertical bar (’|’).

意思是可以这么使用options的第一个参数,简写和完整形式之间可以用逗号,空格和‘|’连接。

program
	.option('-u, --username <username>', 'The user to authenticate as')

The two most used option types are a boolean option, and an option which takes its value from the following argument (declared with angle brackets like --expect ). Both are undefined unless specified on command line.

如果没有传参每个option返回的是一个布尔值,用于判断该option是否被执行;如果有传参,在定义时需要加上<>来进行参数传递。

The parsed options can be accessed by calling .opts() on a Command object, and are passed to the action handler. Multi-word options such as “–template-engine” are camel-cased, becoming program.opts().templateEngine etc.

如这段代码所示调用program的opts()方法可以对options进行一些逻辑判断,从而给每个option不同的方法,注意option如果碰到一长串字符的选项会自动变成驼峰命名,在opt方法中调用参数的话,需要用模板字符串来返回。

var co = require('co');
var prompt = require('co-prompt');
var program = require('commander');
program
  .option('-d, --debug', 'output extra debugging')
  .option('-s, --small', 'small pizza size')
  .option('-p, --pizza-type <type>', 'flavour of pizza');

program.parse(process.argv);
const options = program.opts();
if (options.debug) console.log(options);
console.log('pizza details:');
if (options.small) console.log('- small pizza size');
if (options.pizzaType) console.log(`- ${options.pizzaType}`);

如果没有设置默认值的话,控制台会返回这样的结果,C:\Users\15905\mycli>hi -p error: option '-p, --pizza-type <type>' argument missing,所以我们可以在option里面增加参数,使得他有一个默认的返回值。

program
  .option('-c, --cheese <type>', 'add the specified type of cheese', 'blue');
program.parse();
console.log(`cheese: ${program.opts().cheese}`);

增加一些option

program
  .addOption(new Option('-s, --secret').hideHelp())
  .addOption(new Option('-t, --timeout <delay>', 'timeout in seconds').default(60, 'one minute'))
  .addOption(new Option('-d, --drink <size>', 'drink size').choices(['small', 'medium', 'large']));

也可以在action中对options进行判断

program
  .arguments('<name>')
  .option('-t, --title <honorific>', 'title to use before name')
  .option('-d, --debug', 'display some debugging')
  .action((name, options, command) => {
    if (options.debug) {
      console.error('Called %s with options %o', command.name(), options);
    }
    const title = options.title ? `${options.title} ` : '';
    console.log(`Thank-you ${title}${name}`);
  });

(2)version

program.version('0.0.1');

(3)command

和-option有些像,可以将它的参数传入action,因此逻辑可以在action里面处理。
如果和-option卸载一个段落,option会作为他的子命令出现。

program
  .command('clone <source> [destination]')
  .description('clone a repository into a newly created directory')
  .action((source, destination) => {
    console.log('clone command called');
  });
  program.parse();

(4)argument

在当前command下添加传入参数,假设有两个参数,一个是username,另外一个是password,第一个参数是必须要填的(否则不能判断第二个参数是那个),第二个参数可不填且有默认值。

program
  .version('0.1.0')
  .arguments('<username> [password]')
  .description('test command', {
    username: 'user to login',
    password: 'password for user, if required'
  })
  .action((username, password) => {
    console.log('username:', username);
    console.log('environment:', password || 'no password given');
  });
  program.parse()

输出如下

C:\Users\15905\mycli>hi
error: missing required argument 'username'

C:\Users\15905\mycli>hi 'mouziyao' '123456'
username: 'mouziyao'
environment: '123456'


C:\Users\15905\mycli>hi 'mouziyao'
username: 'mouziyao'
environment: no password given

C:\Users\15905\mycli>

2.co-prompt

文档地址:https://www.npmjs.com/package/co-prompt
通过这个依赖更好的实现了登录逻辑,异步获得了账户名和密码,prompt和prompt.password API可以调用并返回值,password提供了不显示具体数字的功能。

#!/usr/bin/env node
var co = require('co');
var prompt = require('co-prompt');
var program = require('commander');
program
    .version('0.0.2')
    .arguments('<file>')
    .option('-u, --username <username>', 'The user to authenticate as')
    .option('-p, --password <password>', 'The user\'s password')
    .action(function(file){
        co(function *(){
            var username = yield prompt('username: ');
            var password = yield prompt.password('password: ');
            console.log('user: %s password: %s file: %s',
                username, password, file);
        });
    })
    .parse(process.argv);

三、命令行美化提示依赖

1.readline

2.chalk

3.figlet

四、发布一个npm包

1、执行get registry

npm config get registry https://registry.npm.taobao.org/

2、配置本地仓库

npm config set registry=http://registry.npmjs.org

3、执行npm adduser

4、执行npm publish

5、执行成功

在npm官网的个人资料中能查看到发布的包

6、最后记得将本地仓库还原

npm config set registry=https://registry.npm.taobao.org/

总结

以上是手写命令行工具和发布的流程,对文档进行了一点解读,也动手制作了一个npm包,仅作参考。

### 关于 TexStudio 的命令行工具位置及其使用方法 TexStudio 是一款功能强大的 LaTeX 编辑器,虽然其主要用途是通过图形化界面进行文档编辑,但它也支持命令行工具协同工作。以下是关于 TexStudio 命令行工具的位置以及如何使用的详细介绍。 #### 1. **TexStudio 的命令行工具** TexStudio 并未提供独立的命令行工具,而是依赖底层的 TeX 发行版(如 TeX Live 或 MiKTeX)所提供的命令行工具来进行编译操作。因此,在查找 TexStudio 的命令行工具时,实际上是在查找这些发行版的相关工具[^4]。 对于 Mac 用户来说,如果安装了 MacTeX,则可以利用 `pdflatex`、`xelatex` 或 `lualatex` 等命令行工具完成文档编译。这些工具通常位于 `/usr/local/texlive/YYYY/bin/x86_64-darwin/` 路径下(其中 YYYY 表示年份),具体路径可以通过终端运行以下命令找到: ```bash which pdflatex ``` 这会返回实际可执行文件的具体路径。 #### 2. **TexStudio 配置命令行工具** 尽管 TexStudio 不直接作为命令行工具存在,但可以在其设置中指定外部命令行工具用于编译。进入菜单栏中的 `Options -> Configure TeXstudio`,然后导航至 `Commands` 页面,可以看到各种编译命令的配置项。例如,默认情况下 PDFLaTeX 的调用可能如下所示: ```plaintext pdflatex -synctex=1 -interaction=nonstopmode %.tex ``` 此命令会在后台调用系统的 `pdflatex` 工具来处理 `.tex` 文件。用户可以根据需求修改这一命令以适应特定的工作流[^3]。 #### 3. **手动使用命令行工具** 假如希望完全脱离 TexStudio 图形界面并仅依靠命令行完成编译过程,可以直接在终端输入相应指令。假设当前目录下有一个名为 `example.tex` 的文件,那么可以用下面的方式生成 PDF 输出: ```bash pdflatex example.tex ``` 或者针对中文环境下的 XeLaTeX 处理方案: ```bash xelatex example.tex ``` 每次运行上述任一命令都会触发一次完整的编译流程;若有参考文献或索引等内容涉及多次迭代,则需重复执行直至所有交叉引用均被正确解析[^2]。 --- ###
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值