前端工程化之脚本世界
npm scripts
常用命令
// 初始化工程
npm init
// 执行脚本命令
npm run
// 安装依赖
npm install
// 升级依赖
npm update
// 查看bin文件目录
npm bin
// 将工程软件连接到全局
npm link
// 发布包
npm publish
// 废弃包
npm deprecate
内部变量
通过npm_package_*
前缀,npm 脚本可以拿到package.json
里面的字段。
console.log(process.env.npm_package_name)
或者在bash脚本中通过$npm_package_*
获取到对应变量。
echo $npm_package_name
传递参数
有时候,我们需要对npm scripts二次包装过的命令传递参数,我们使用--
来标识,进行参数传递。--
后面的内容会被作为参数传递到process.env
对象中。
"scripts": {
"serve": "serve ./index",
"serve:dev": "npm run serve -- -p 8080"
}
脚本钩子
脚本钩子类似于hook,当时间触发时,对应的钩子逻辑也应该触发。我们可以在执行一些命令之前,做一些清除和初始化操作。这需要我们自定义一些钩子。
脚本执行顺序
如果 npm 脚本里面需要执行多个任务,那么需要明确它们的执行顺序。
如果是并行执行(即同时的平行执行),可以使用&
符号。
npm run script1.js & npm run script2.js
如果是继发执行(即只有前一个任务成功,才执行下一个任务),可以使用&&
符号。
npm run script1.js && npm run script2.js
这两个符号是 Bash 的功能。此外,还可以使用 node 的任务管理模块:script-runner、npm-run-all、redrun。
NodeCLI
在nodejs中,我们执行js文件,可以通过process.argv
来获取当前命令行传入的参数。
process.argv
属性返回一个数组,其中包含启动的Nodejs进程是传入的命令行参数。第一个元素是process.execPath,第二个元素是正在执行的JavaScript文件的路径。其余元素将是任何其他的命令行参数。
这样可以看出,我们自己解析命令行参数,比较麻烦,所以可以使用commander
来解析。
commander
简化node cli命令行参数解析。
在编写node cli脚本之前,我们可以声明解析脚本的解释器。因为bash解释器并不能直接执行js文件。
#!/usr/bin/env node
// 直接执行该文件时,我们要告诉bash,使用node来执行,而不是bash
inquirer
node命令行交互工具。 由于一些命令,参数过程,用户难以记忆和配置。所以我们可以使用问答的方式,让用户选择,然后进行生成配置文件。例如vue-cli等。
- 灵活的cli交互方式(提供很多的api)。
- 抹平平台间的差异。
chalk
美化终端输出样式。
- 错误提示更加醒目。
- 操作成功,给用户一个正面反馈。
- 用户搜索关键词高亮显示。
const chalk = require('chalk');
const log = console.log;
// Combine styled and normal strings
log(chalk.blue('\nHello') + ' World' + chalk.red('!\n'));
// Compose multiple styles using the chainable API
log(chalk.blue.bgRed.bold('Hello world!\n'));
// Pass in multiple arguments
log(chalk.blue('Hello', 'World!', 'zh', 'llm\n'));
// Nest styles
log(chalk.red('Hello', chalk.underline.bgBlue('world') + '!\n'));
shell
shell是啥?
操作系统和用户交互的接口。一般来说,我们说的shell都是unix shell,被认为是cli。一些命令可以在命令行被执行。
命令的本质是一个程序,这些程序具有发起系统调用(System Call)的能力,编写Shell脚本,其实是在编排这些程序的执行,除此之外,还有Shell语法解释器负责解释一行行的Shell语句。
shell解释器
常见的bash命令
注意:以下介绍的都是基础的常用命令,很多命令即使现在学习了,不使用它,很快就忘记了。我们可以通过man 命令
来查看各个命令的用法。
文件新建
# touch 新建文件
touch index.js
# mkdir 新建文件夹
mkdir project
文件删除
-
rm [文件或者目录]
- -r 删除目录
- -f 强制删除
-
rm -rf [文件或者目录] 递归强制删除所有目录
# rmdir 删除文件夹
rmdir project
# rm 删除文件
rm index.js
rm -rf ./project/index.js # 递归强制删除文件
文件移动
通过mv
对文件进行剪切操作。
# mv 移动文件
mv ./source/a.txt ./target
# 移动并强制覆盖,即剪切文件到指定目录 效果和不加参数的mv一样
mv -f ./source/a.txt ./target
# 移动并不覆盖,同名文件将生效
mv -n ./source/a.txt ./target
我们可以使用mv
来间接给文件进行重命名
# 将index.js重命名为main.js
mv ./index.js ./main.js
通过cp
对文件夹,文件进行复制操作。默认只能拷贝文件,想要拷贝文件夹需要加-r
参数。
# 将main.js移动到src下
cp main.js src/
# 将src移动到src/foo
cp -r src src/foo
查看文件
cat,head,tail
命令
cat ./package.json # 查看文件
head -n 10 yarn.lock # 查看文件前十行
tail -n 10 yarn.lock # 查看文件后十行
head, tail
默认查看10行内容。一般用于查看日志文件。
编辑文件
GNU nano是Linux上最简单的文本编辑器,操作简单,功能也比较初级。对于一些临时和简单的文件编辑操作,我们可以直接使用nano就好。nano
就相当于windows中的记事本,编辑好文章,使用ctrl + x
即可保存退出。
vi/vim,vi是Linux上的一款功能强大的编辑器,vim更是vi的加强版。vim的使用和学习,可以看看这篇文章
进程相关
ps查看当前用户进程。
# ps查看当前用户进程
ps
# 查看所有进程
ps -ax
lsof 查看网络相关内容
lsof -i # 查看打开的网络相关文件
lsof -p 4568 # 查看pid=4568的进程打开的文件
top
命令,查看进程的实时数据。
kill
命令实际上并不是杀死进程,本质是向进程发送信号。例如:kill -s SIGUSRI 34534
实际上可以调试nodejs应用,因为nodejs会在收到SIGUSRI时进入调试模式。优雅退出的原理就是监听SIGTERM信号,并递归地退出子进程。
kill 4568 # SIGTERM 信号
kill -9 4568 # SIGTREM信号,强杀进程
其他
grep
对行进行筛选,awk
对列进行筛选。
# 找到所有正在被监听的端口
lsof -i | grep LISTEN
# 为当前目录下的所有文件添加可执行权限
chmod +x $(ls -al | awk 'NR>1 {print $9}')
查看命令帮助文档
# 命令 --h
ps --h
# 详细的查看命令使用
# man 命令
man ps
bash编程
变量
注意:变量名不能为数字开头,等号左右两边不能有空格。
全局变量
a=1
export b=2
局部变量,使用local
来定义,只能用在一个函数中。
local a=1
变量类型
# String, 可以省略引号
a=abcd
a="abcd"
# Number, 默认右边是一个字符串,所以我们需要使用[],(())包裹
num=$[1+1]
num=$((1+1))
# Array
arr=(a b c d)
arr=(1 2 3 4)
arr[0]=0
环境变量
-
PATH:指定命令的搜索路径
-
HOME:指定用户的主工作目录(即用户登陆到Linux系统中时,默认的目录)HISTSIZE:指保存历史命令记录的条数
-
LOGNAME:指当前用户的登录名
-
HOSTNAME:指主机的名称,许多应用程序如果要用到主机名的话,通常是从这个环境变量中来取得的
-
SHELL:指当前用户用的是哪种Shell
-
LANG/LANGUGE:和语言相关的环境变量,使用多种语言的用户可以修改此环境变量MAIL:指当前用户的邮件存放目录
使用变量时,我们需要在前面加上$
。
echo $SHELL
条件比较符
-z var # 检查变量var是否为空
-d file # 检查file是否存在并是一个目录
-e file # 检查file是否存在
-f file # 检查file是否存在并是一个文件
-r file # 检查file是否存在并可读
-s file # 检查file是否存在并非空
-w file # 检查file是否存在并可写
-x file # 检查file是否存在并可执行
-0 file # 检查file是否存在并属于当前用户
-G file # 检查file是否存在并其默认组与当前用户相同
filel -nt file2 # 检查file1是否比file2新
file1 -ot file2 # 检査filel是否比file2旧
条件语句
IF THEN格式
if condition1
then
command1
elif condition2
then
command2
else
commandN
fi
CASE 格式
case $VAR in
condition1)
command1
;;
condition2)
command2
;;
*)
command3
;;
esac
他们可以结合条件比较符来做一些判断,执行相应的指令。
if [ -f "./a.log" ]; # 中括号两边都需要有空格。否则会报错
then echo "this is file";
else echo "this is not file";
fi;
循环语句
for循环格式
for index in 1 2 3 4;
do
echo "index="$index;
done # 结束标志
for ((i = 0; i < 5; i++));
do
echo $i;
done # 结束标志
while循环格式
while condition
do
statements
done
输出小于等于10的整数
num=1
while [ $num -le 10 ]
do
echo $num
num=$(( $num + 1 ))
done
函数
格式
# function可以省略
[function] name() {
statements
[return value]
}
在函数体中,可以使用$n
来获取第n个实参。
function helloParam() {
echo "hello world"$1;
}
helloParam zh-llm # 直接调用,传递传输直接写在函数名后面即可
shell中运行的每个命令都是用退出状态码(exit status)来告诉shell他完成了处理。退出状态码是一个0-255之间的整数值,在命令结束运行时由命令传给shell。可以在命令执行完毕后立即使用$?
捕获。
echo $?
特殊变量
-
$#
传递到脚本或函数的参数个数。 -
$*
以一个单字符串显示所有向脚本传递的参数。 -
$$
脚本运行的当前进程ID号。 -
$!
后台运行的最后一个进程的ID号。 -
$@
与$*
相同,但是使用时加引号,并在引号中返回每个参数。 -
$-
显示Shell使用的当前选项,与set命令功能相同。 -
$?
显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
重定向
重定向,全称是I/O重定向,默认情况下,Bash程序从终端接收输入,并在终端打印输出(标准输入、标准输出)。如果你想改变输入的来源,或是输出的目的地,那么,就需要使用“重定向”。
输出重定向是指命令的结果不再输出到显示器上,而是输出到其它地方,一般是文件中。这样做的最大好处就是把命令的结果保存起来,当我们需要的时候可以随时查询。
# 以覆盖的方式,把 command 的正确输出结果输出到 file 文件中
command > file
# 以追加的方式,把 command 的正确输出结果输出到 file 文件中
command >> file
比如,将当前输出写入一个文件中
# 他会覆盖a.log中已有的内容
ls -al > a.log
# 将日志追加到最后
ls > a.log
输入重定向就是改变输入的方向,不再使用键盘作为命令输入的来源,而是使用文件作为命令的输入。
# 将 file 文件中的内容作为 command 的输入
command < file
# 将输入重定向到file的部分内容
command << file
将a.log的内容作为str变量的内容输出。
while read str; do
echo $str
done < a.log
交互式编程
echo,类似于js中的console。打印出内容。
# 打印换行
echo "zh"
# 打印并且不换行
echo -n "llm"
read
是读取输入的内容,放入指定的变量。
# 读取输入,存放在变量var中
read var
# 读取输入的第一个字符,存入变量var中
read -n 1 var
echo -n "name?"
read name;
echo -n "name2?"
read nam2;
echo $name$name2;
linux补充学习
参考
转载自:https://juejin.cn/post/7239953755897839673