shell变量
1. 自定义变量
只能用于当前shell,用=声明,包括字符、整型、浮点、日期类型
2. 环境变量
当前shell及子shell可用,使用export、declare -x来声明
#key=value,注意没有空格
page_size=1
page_num=2
#命令也可以作为值
_ls=ls
#命令执行结果
file_list=$(ls -a)
#默认当字符串
total=page_size*page_num ##incorrect
#声明变量为整型
let total=page_size*page_num ##or
declare -i total=page_size*page_num ##-i整型,-a为数组
#导出环境变量
export total ##or
declare -x total ##-x环境变量,-r只读,-p指定类型
3. 系统环境变量
所有shell启动时加载
echo $HOME ##主目录 /home/yourname
echo $USER ##用户 yourname
echo $PS1
echo $PATH ##shell执行时的查找路径
修改配置文件后需要使用source ~./bashrc重新加载,让修改生效
4.运算符
- 引号
#单引号(')不解析
'hello${name}'
#双引号(")解析$,\,`三种
"hello${name}"
#反引号(`)解析代码
`ls ${path}`##or
`ls -a`
- 括号
res=$((1+1))#(())算数运算
$(ls -a)#()执行命令
- 命令连接
cmd1&&cmd2
cmd1||cmd2
cmd1;cmd2 #cmd1,cmd2串行执行
- 后台运行
node server.js & #后台运行,但是关闭shell还是会关掉
nohup node server.js & #真正的后台运行
管道|,前面的结果作为后面的输入
# 右边要能接受标准输入,如grep
# ls、mv无法接受标准输入,需要用xargs转化为参数列表
find . -maxdepth 1 -name "*.sh" |xargs ls -l
# 管道忽略stderr,错误会报错
## set -o pipefail可以设置管道错误退出
重定向
#输出
> #覆盖写入文件,or 1>,一般省略1
>> #追加
2> #错误输入写入文件
&> #正确错误统一写入
##例如
ls -l >> list.txt 2>&1 #错误写入&1即传入的文件目录list.txt
#输入
<
<<
##例如
wc -l <<EOF ##遇到EOF截至,并将之前的输入内容输入给左边
判断
- test
#整数
test $v1 -eq $v2 #等于
test $v1 -lt $v2 #小于
test $v1 -gt $v2 #大于
#字符串
test -z $str_a
test -n $str_a
test $str_a=$str_b
#文件
test -e /dmt && echo "exist"
test -f /usr/bin/npm && echo "file exist"
- []或[[] []类似test,>,<,=只能比较字符串
[[ $name == "hello" ]] ##incorrect
[[ "$name" == "hello" ]] ##true
而[[]]更丰富,整型比较支持>,<,=,字符串比较还能支持=~正则
分支
1. if
level=0
if [ -n "$level" ]; then #是否非空
if [ "$level"==0 ]; then
profix=ERROR
elif [ "$level"==1 ]; then
profix=INFO
else
echo "hhh"
fi
fi
echo "${profix}"
read -p "please input y/n:" yn
if [ "$yn"=="y" -o "$yn"=="Y" ]; then
echo "ok"
fi ##or
if [ "$yn"=="y" ]||[ "$yn"=="Y" ]; then
echo "ok too"
fi
2. case
case $name in
"nick")
echo "nick"
;;
"jack")
echo "jack"
;;
*)
echo "default"
;;
esac
循环
1. while
while consition ; do do-something ; done
2. until
while consition ; do do-something ; done #condition退出条件
3. for
for val in a b c
do
echo $val
done
for((i=0;i<10;i++))
do
echo $i
done
函数
funcName(){do-something} #or
function funcName(){do-something}
funcName #调用
funcName "hhh" #参数
在函数里内部$0,$1...类似shell,用于获取参数
return不是返回,仅函数状态,echo或prinf用于输出
在外面content=$(func)或func获取结果
模块化
source './path'
常用命令
# 对cat搜索筛选
cat cloudfun.log | grep -n "ERROR"
# 排序,根据指定分隔符切割后的第三列
cat cloudfun.log | grep -n "ERROR" | sort -t " " -k 3
# 前before四行,后after四行,-c可以统计次数
grep "ERROR" cloudfun.log -A3 -B4
# 看尾部10行,看头部用head
tail -n 10 cloudfun.log
tail -n 10 -f cloudfun.log #会等待输入
tail -f -n 10 cloudfun.log #也就是会追加内容
# 统计出现次数,行数、单词数、字符数
wc -lwm
执行
shell文件一般以.sh结尾,也可以没有 在第一行指定命令解释器
#! /bin/bash
启动
- 文件名
./shell.sh - 解释器
bash ./shell.sh - source
source ./shell.sh
执行过程
shell展开
- 大括号
a{b,c,d}e #abe ace ade
{1...5}#1 2 3 4 5
{1...5...2}#1 3 5 ##增量2
{a...d}#a b c d
- 波浪号~
~ => $HOME - 参数展开${}
#间接
hhh="str"
str="hello"
echo ${hhh}#str
echo ${!hhh}#hello
echo ${#hhh}#3,长度
echo ${hhc:-word}#为空替换为word但没有赋值给hhc,结果str(设hhc为空)
echo ${hhc:=word}#为空替换为word并赋值给hhc,结果word(设hhc为空)
echo ${hhc:+hello}#不为空替换,结果hello(设hhc为word)
调试
log
echo\printf
set
set -u#不存在的变量会报错停止执行
set -x#运行前,先打印命令语句
set -e#报错就终止
set -o pipefail
如:
#! /bin/sh
set -uex -o pipefail
echo "hello world"
vscode 插件
前端集成
- node中exec、spawn调用shell
const {exec} = require('child_process');
exec('ls',['-l'],(err,stdout,stderr)=>{
if(err){
console.err(err);
}
stdout&&console.log(stdout)
})
- 在shell中调用node .sh中
#! /bin/bash
set -e
node ./exec.js
echo "success"
- 借助zx等库融合shell与js 提供调用的方法有chalk、sleep、fetch、question