基础知识
Shell 教程(主参考)
Shell
代码
#! /bin/zsh
# 【输出】
echo "hello world"
# 【变量】
file="我是变量"
# 【使用变量】
echo $file
echo ${file}
# 【重新定义变量】
emp="变量初始值"
echo ${emp}
emp="变量重新赋值"
echo ${emp}
# 【只读变量】
readonly ech="我是只读变量"
echo ${ech}
# ech="重新赋值只读变量"
# tip:会报错
echo ${ech}
quit="我是另一个只读变量"
readonly quit
echo ${quit}
# quit="重新赋值另一个只读变量"
# tip:会报错
echo ${quit}
# 【删除变量】
sat="普通变量"
unset sat
# tip:实际不会有任何输出
echo ${sat}
# tip:不能删除只读变量
readonly sat
# tip:会报错
# unset sat
# 【shell 字符串】
# 双引号:可以使用转义字符,可以使用变量
# 单引号:不可以使用转义字符,不可以使用变量
str='单引号字符串'
yourname="双引号字符串 + "${str}""
echo ${yourname}
double="字符串拼接"
astr="双引号 ${double} "
bstr="双引号 "${double}" "
echo ${astr}
echo ${bstr}
single='单引号拼接'
cstr='单引号 '${single}''
dstr='单引号 ${single}'
echo ${cstr}
echo ${dstr}
# 获取字符串长度
estr="获取字符串长度"
echo ${#estr}
# 提取子字符串
fstr="abcdefg"
echo ${fstr:2:3}
# 【shell 数组】
array=(1 2 3 4)
echo ${array[1]}
array[5]=5
echo ${array[5]}
array[6]="five"
echo ${array[6]}
# 获取数组中所有元素
echo ${array[@]}
echo ${array[*]}
# 获取数组元素个数
echo ${#array[@]}
echo ${#array[*]}
# 取得数组单个元素的长度
echo ${#array[6]}
# 【shell 传递参数】
# shell支持执行脚本时向脚本内传递参数,脚本内获取参数的格式为:$n。n 代表一个数字,1 为执行脚本的第一个参数,2 为执行脚本的第二个参数
echo "执行的文件名:$0"
echo "第一个参数为:$1"
echo "第二个参数为:$2"
echo "第三个参数为:$3"
echo "第三个参数为:$4"
echo "传递到脚本的参数个数:$#"
echo "传递到脚本的所有参数:$@"
echo "传递到脚本的所有参数:$*"
echo "脚本运行的当前进程ID号:$$"
echo "后台运行的最后一个进程的ID号:$!"
echo "显示Shell使用的当前选项:$-"
echo "显示最后命令的退出状态,0表示没有错误,其他任何值表明有错误。:$?"
# $* 与 $@ 区别:
for i in $*
do
echo ${i}
done
for kk in $@
do
echo ${kk}
done
# 【echo命令】
# 显示普通字符串:
echo "hello world"
echo hello world
# 显示转义字符
echo ""hello""
echo "hello"
# 显示变量
oneVar="显示变量"
echo "${oneVar}"
# 显示换行
echo "OK!
"
echo "换行"
# 显示不换行
echo "ok! c"
echo "不换行"
# 显示结果定向至文件,会生成文件myfile
echo "It is a test" > myfile
# 原样输出字符串,不进行转义或取变量(用单引号)
echo '${oneVar} "'
# 显示命令执行结果
echo `date`
# 显示命令执行结果,定向至文件,会生成文件datefile
echo `date` > datefile
# 【read 命令】
# 从标准输入中读取一行,并把输入行的每个字段的值指定给 shell 变量
# read name
# echo ${name}
# 【printf 命令】
# printf format-string(格式) [arguments...](参数)
printf "%-10s %-8s %-4s
" 姓名 性别 体重kg
printf "%-10s %-8s %-4.2f
" 郭靖 男 66.1234
printf "%-10s %-8s %-4.2f
" 杨过 男 48.6543
printf "%-10s %-8s %-4.2f
" 郭芙 女 47.9876
# format-string为双引号
printf "%d %4s
" 1 双引号
# format-string为单引号
printf '%d %4s
' 2 单引号
# 没有引号也可以输出
printf %s"
" 没有引号
# 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
printf "%s
" abc abc
printf "%s %s %s
" a b c d e f g h i j
# 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
printf "%s and %d
"
# 其他
printf "a string, no processing:<%s>
" "A
B"
printf "a string, no processing:<%b>
" "A
B"
#不换行
printf "www.runoob.com a"
# 【shell 运算符】
# 算数运算符
# 使用expr,expr沒有乘幂
a=10
b=20
var=`expr ${a} + ${b}`
echo ${var}
echo `expr ${a} + ${b}`
echo `expr ${a} - ${b}`
echo `expr ${a} * ${b}`
echo `expr ${a} / ${b}`
echo `expr ${a} % ${b}`
c=$b
echo ${c}
# 使用$(( ))
echo $(($a+$b))
echo $(( $a - $b ))
echo $(( $a * $b ))
echo $(( $a / $b ))
echo $(( $a % $b ))
echo $(( $a ** $b))
echo $(( $a == $b ))
echo $(( $a != $b ))
# 使用$[]
echo $[$a+$b]
echo $[ $a - $b ]
echo $[ $a * $b ]
echo $[ $a / $b ]
echo $[ $a % $b ]
echo $[ $a ** $b ]
echo $[ $a == $b ]
echo $[ $a != $b ]
# 关系运算符
# 关系运算符只支持数字,不支持字符串,除非字符串的值是数字
# -eq 检测两个数是否相等,相等返回 true
if [ $a -eq $b ]
then
echo "$a -eq $b : a 等于 b"
else
echo "$a -eq $b: a 不等于 b"
fi
# -ne 检测两个数是否不相等,不相等返回 true
if [ $a -ne $b ]
then
echo "$a -ne $b : a 不等于 b"
else
echo "$a -ne $b : a 等于 b"
fi
# -gt 检测左边的数是否大于右边的,如果是,则返回 true
if [ $a -gt $b ]
then
echo "$a -gt $b : a 大于 b"
else
echo "$a -gt $b: a 不大于 b"
fi
# -lt 检测左边的数是否小于右边的,如果是,则返回 true
if [ $a -lt $b ]
then
echo "$a -lt $b: a 小于 b"
else
echo "$a -lt $b: a 不小于 b"
fi
# -ge 检测左边的数是否大于等于右边的,如果是,则返回 true
if [ $a -ge $b ]
then
echo "$a -ge $b: a 大于或等于 b"
else
echo "$a -ge $b: a 小于 b"
fi
# -le 检测左边的数是否小于等于右边的,如果是,则返回 true
if [ $a -le $b ]
then
echo "$a -le $b: a 小于或等于 b"
else
echo "$a -le $b: a 大于 b"
fi
# 布尔运算符
# ! 非运算,表达式为 true 则返回 false,否则返回 true
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a == $b: a 等于 b"
fi
# -o 或运算,有一个表达式为 true 则返回 true
if [ $a -gt 5 -o $b -lt 10 ]
then
echo "$a 大于 5 或者 $b 小于 10: 返回true"
else
echo "$a 大于 5 或者 $b 小于 10: 返回false"
fi
# -a 与运算,两个表达式都为 true 才返回 true
if [ $a -lt 100 -a $b -gt 15 ]
then
echo "$a 小于 100 且 $b 大于 15 : 返回 true"
else
echo "$a 小于 100 且 $b 大于 15 : 返回 false"
fi
# 逻辑运算符
# && 逻辑的 AND
if [[ $a -lt 100 && $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
# || 逻辑的 OR
if [[ $a -lt 100 || $b -gt 100 ]]
then
echo "返回 true"
else
echo "返回 false"
fi
# 字符串运算符
a="abc"
b="def"
# = 检测两个字符串是否相等,相等返回 true
if [ $a = $b]
then
echo "$a = $b : a 等于 b"
else
echo "$a = $b: a 不等于 b"
fi
# != 检测两个字符串是否不相等,不相等返回 true
if [ $a != $b ]
then
echo "$a != $b : a 不等于 b"
else
echo "$a != $b: a 等于 b"
fi
# -z 检测字符串长度是否为0,为0返回 true
if [ -z $a ]
then
echo "$a长度为 0"
else
echo "$a长度不为 0"
fi
# -n 检测字符串长度是否不为 0,不为 0 返回 true
if [ -n $a ]
then
echo "$a长度不为 0"
else
echo "$a长度为 0"
fi
# $ 检测字符串是否为空,不为空返回 true
if [ $a ]
then
echo "$a : 字符串不为空"
else
echo "$a : 字符串为空"
fi
# 文件测试运算符
file="/var/www/runoob/test.sh"
if [ -r $file ]
then
echo "文件可读"
else
echo "文件不可读"
fi
if [ -w $file ]
then
echo "文件可写"
else
echo "文件不可写"
fi
if [ -x $file ]
then
echo "文件可执行"
else
echo "文件不可执行"
fi
if [ -f $file ]
then
echo "文件为普通文件"
else
echo "文件为特殊文件"
fi
if [ -d $file ]
then
echo "文件是个目录"
else
echo "文件不是个目录"
fi
if [ -s $file ]
then
echo "文件不为空"
else
echo "文件为空"
fi
if [ -e $file ]
then
echo "文件存在"
else
echo "文件不存在"
fi
# 【test命令】
# Shell中的 test 命令用于检查某个条件是否成立,它可以进行数值、字符和文件三个方面的测试
# 数值测试
num1=40
num2=40
if test $num1 -eq $num2
then
echo "$num1等于$num2"
else
echo "$num1不等于$num2"
fi
# 字符串测试
num1="ru1noob"
num2="runoob"
if test $num1 = $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
if test $num1 != $num2
then
echo '两个字符串相等!'
else
echo '两个字符串不相等!'
fi
# 文件测试
cd /bin
if test -e ./zsh
then
echo '文件已存在!'
else
echo '文件不存在!'
fi
# 另外,Shell 还提供了与( -a )、或( -o )、非( ! )三个逻辑操作符用于将测试条件连接起来,其优先级为: ! 最高, -a 次之, -o 最低
cd /bin
if test -e ./notFile -o -e ./bash
then
echo '至少有一个文件存在!'
else
echo '两个文件都不存在'
fi
# 【shell 流程控制】
# if else
a=10
b=20
if [ $a = $b ]
then
echo "a 等于 b"
elif [ $a -gt $b ]
then
echo "a 大于 b"
elif [ $a -lt $b ]
then
echo "a 小于 b"
else
echo "没有符合的条件"
fi
# for循环
for i in `ls /etc`
echo $i
for j in $(ls)
echo ${j}
for skill in Ada Coffe Action Java;
do
echo "I am good at ${skill}Script"
done
for loop in 1 2 3 4 5
do
echo "The value is: $loop"
done
# while 语句
# int=1
# while(( $int <= 5 )
# do
# echo $int
# let "int++"
# done
# until 循环
a=0
until [ ! $a -lt 10 ]
do
echo $a
let "a++"
# a=`expr $a + 1`
done
# case esac语句
echo '输入 1 到 4 之间的数字:'
echo '你输入的数字为:'
read aNum
case $aNum in
1) echo '你选择了 1'
;;
2) echo '你选择了 2'
;;
3) echo '你选择了 3'
;;
4) echo '你选择了 4'
;;
*) echo '你没有输入 1 到 4 之间的数字'
;;
esac
# 【函数】
# 注意:所有函数在使用前必须定义。这意味着必须将函数放在脚本开始部分,直至shell解释器首次发现它时,才可以使用。调用函数仅使用其函数名即可
demoFun(){
echo "这是我的第一个 shell 函数!"
}
echo "-----函数开始执行-----"
demoFun
echo "-----函数执行完毕-----"
# 函数返回值在调用该函数后通过 $? 来获得
funWithReturn(){
echo "这个函数会对输入的两个数字进行相加运算..."
echo "输入第一个数字: "
read aNum
echo "输入第二个数字: "
read anotherNum
echo "两个数字分别为 $aNum 和 $anotherNum !"
return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
# 函数参数
# 在Shell中,调用函数时可以向其传递参数。在函数体内部,通过 $n 的形式来获取参数的值,例如,$1表示第一个参数,$2表示第二个参数...
# $10 不能获取第十个参数,获取第十个参数需要${10}。当n>=10时,需要使用${n}来获取参数。
funWithParam(){
echo "第一个参数为 $1 !"
echo "第二个参数为 $2 !"
echo "第十个参数为 $10 !"
echo "第十个参数为 ${10} !"
echo "第十一个参数为 ${11} !"
echo "参数总数有 $# 个!"
echo "作为一个字符串输出所有参数 $* !"
}
funWithParam 1 2 3 4 5 6 7 8 9 34 73
# 【输出重定向】
# command > file 将输出重定向到 file
who > users
# command >> file 将输出以追加的方式重定向到 file
who >> users
# 统计 users 文件的行数,从file中读取内容
wc -l users
# command < file 将输入重定向到 file
wc -l < users
# 同时替换输入和输出,执行wc -l ,从文件users读取内容,然后将输出写入到outfile中。
wc -l < users > outfile
实战
file=`git diff-index --cached HEAD --name-only --diff-filter ACMR | grep -v mockData | grep -v dep | egrep '(.js|.vue|.jsx)$'` if [ "$file" ];then ./node_modules/eslint/bin/eslint.js --fix $file else echo 'there is no js files to eslint check!' fi
命令
1、比较树与工作树或索引
git diff-index
2、例如,假设您已经在您的工作目录上工作,更新了索引中的一些文件并准备好提交(已add,未commit)。你想看看到底什么你要提交,而无需编写一个新的树对象,并比较这种方式,要做到这一点,你只是做
git diff-index --cached HEAD
3、要查看所有修改过的文件和新文件
--diff-filter=ACMR
参数
--name-only:仅显示已更改文件的名称
--diff-filter=[ACDMRTUXB*]:Select only files that are
- A Added
- C Copied
- D Deleted
- M Modified
- R Renamed
- T have their type (mode) changed
- U Unmerged
- X Unknown
- B have had their pairing Broken
- * All-or-none
从准备要提交的文件中筛选出添加、复制