shell编程

111 阅读1分钟

shell变量

1. 自定义变量

只能用于当前shell,用=声明,包括字符、整型、浮点、日期类型

2. 环境变量

当前shell及子shell可用,使用exportdeclare -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.运算符

  1. 引号
#单引号(')不解析
'hello${name}'
#双引号(")解析$,\,`三种
"hello${name}"
#反引号(`)解析代码
`ls ${path}`##or
`ls -a`
  1. 括号
res=$((1+1))#(())算数运算
$(ls -a)#()执行命令
  1. 命令连接
cmd1&&cmd2
cmd1||cmd2
cmd1;cmd2 #cmd1,cmd2串行执行
  1. 后台运行
node server.js & #后台运行,但是关闭shell还是会关掉
nohup node server.js & #真正的后台运行

管道|,前面的结果作为后面的输入

# 右边要能接受标准输入,如grep
# lsmv无法接受标准输入,需要用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截至,并将之前的输入内容输入给左边

判断

  1. 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"
  1. []或[[] []类似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

启动

  1. 文件名 ./shell.sh
  2. 解释器 bash ./shell.sh
  3. source source ./shell.sh

执行过程

shell展开

  1. 大括号
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
  1. 波浪号~ ~ => $HOME
  2. 参数展开${}
#间接
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 插件

前端集成

  1. node中exec、spawn调用shell
const {exec} = require('child_process');
exec('ls',['-l'],(err,stdout,stderr)=>{
	if(err){
		console.err(err);
	}
	stdout&&console.log(stdout)
})
  1. 在shell中调用node .sh中
#! /bin/bash
set -e
node ./exec.js
echo "success"
  1. 借助zx等库融合shell与js 提供调用的方法有chalk、sleep、fetch、question