前言

Linux软件开发,多半离不来shell脚本,可以通过shell脚本去获取或者处理系统中的一些数据,可谓及其方便。

shell简介

shell有图像界面shell和命令行式shell,传统意义上的shell指的是命令行式的shell,以后如果不特别注明,shell是指命令行式的shell。下面将要说的就是命令行式的shell。

然后Linux系统中一般有bash和sh,最开始在Unix系统中流行的是sh,而bash作为sh的改进版本,提供了更加丰富的功能。一般来说,都推荐使用bash作为默认的Shell。所以有的时候用sh执行脚本时报的错,用bash执行就可以了。

其他的shell还有:sh、bash、ksh、rsh、csh等。sh的全名是Bourne Shell。名字中的玻恩就是这个Shell的作者。
而bash的全名是Bourne Again Shell。

shell使用

首先shell脚本的语法,需要知道的是变量都是全局变量

执行shell

执行shell脚本,一般sh + 脚本名即可,如需要传入参数,后面加上即可。
也可以设置成可执行程序,即 chmod +x ./test.sh ,再 ./test.sh 运行即可。
cat + 文件 是显示文件内容

kch@kch:~$ cat test.sh 
#!/bin/sh
echo $#
echo $*
kch@kch:~$ sh test.sh one two three
3
one two three
kch@kch:~$
#   $#: 表示参数的个数,$*: 表示所有参数

shell函数

shell脚本中也可以定义使用函数

kch@kch:~/shell$ cat function.sh 
#!/bin/bash
function(){
	echo $#
	echo $*
}

getStr(){
	if [ -z $1 ];then
		return 1
	fi
	return 0
	#返回返回值,只能是整数
}

function ni hao
getStr 
# $? 获取函数返回值 
echo $?
getStr data
echo $?
kch@kch:~/shell$ sh function.sh 
2
ni hao
1
0
kch@kch:~/shell$

这里 $? 获取函数返回值 , $?也可以获取上一个命令执行结果的返回值,成功则返回0

引入脚本

还是有引入另一个脚本,然后可以调用它的函数,并且使用其中的变量,相当于将另一个脚本复制到了本脚本中。

kch@kch:~/shell$ cat test_2_1.sh 
#!/bin/bash
echo this is test_2_1.sh!
str="test_2_1"
function(){
	echo this is test_2_1 function!
}
kch@kch:~/shell$ cat test_2.sh 
#!/bin/bash
str="test_2"
echo str=$str
#引入脚本
. ./test_2_1.sh
echo str=$str
function
kch@kch:~/shell$ sh test_2.sh 
str=test_2
this is test_2_1.sh!
str=test_2_1
this is test_2_1 function!
kch@kch:~/shell$

执行命令获取返回值

kch@kch:~$ cat test.sh
#!/bin/sh
#date获取时间
time=`date`
echo $time
#wc -l 获取行数
line=`ls | wc -l`
echo $line
kch@kch:~$ date
2021年 12月 09日 星期四 09:17:07 CST
kch@kch:~$ ls | wc -l
35
kch@kch:~$

if条件判断

kch@kch:~$ cat test.sh
#!/bin/sh
if [ -z $1 ];then
#如果为空
echo 传入的参数为空!
elif [ $1 = "test.sh" ];then
	echo 传入参数为当前文件名!
elif [ $1 -eq 0 ];then
#-eq比较数字,传入非数字,会报错
	echo 传入参数等于0!
else
	echo 传入参数是$1!
fi
kch@kch:~$ sh test.sh 
传入的参数为空!
kch@kch:~$ sh test.sh test.sh
传入参数为当前文件名!
kch@kch:~$ sh test.sh 0
传入参数等于0!
kch@kch:~$ sh test.sh data
test.sh: 7: [: Illegal number: data
传入参数是data!
kch@kch:~$

for循环

kch@kch:~/shell$ cat test.sh 
#!/bin/bash
#查看当前目录下的文件
data=`ls`
for tmp in $data
do
        echo item:$tmp
done
#这样也可以
echo 第二种:
for tmp in `ls`
do
        echo item:$tmp
done
#数字范围
for number in `seq 5 10`
do
        echo $number
done
#数组
array=(A B C)
echo array[0]:${array[0]}
for tmp in ${array[*]}
do
        echo $tmp
done
kch@kch:~/shell$ bash test.sh 
item:one.sh
item:test.sh
item:two.sh
第二种:
item:one.sh
item:test.sh
item:two.sh
5
6
7
8
9
10
array[0]:A
A
B
C
kch@kch:~/shell$

while循环

kch@kch:~/shell$ cat file 
1 hello world!
2 hello world!
3 hello world!
kch@kch:~/shell$ cat test.sh 
#!/bin/bash
#读取文件
while read line
do
    echo $line
done < file
#条件循环
min=5
max=10
while [ $min -le $max ]
do
    echo $min
    #加法计算
    min=`expr $min + 1`
done   
kch@kch:~/shell$ sh test.sh 
1 hello world!
2 hello world!
3 hello world!
5
6
7
8
9
10
kch@kch:~/shell$

算术运算符

kch@kch:~/shell$ cat test.sh 
#!/bin/bash
a=20
b=15
#加法
value=`expr $a + $b`
echo a + b = $value
#减法
value=`expr $a - $b`
echo a - b = $value
#乘法
value=`expr $a \* $b`
echo a \* b = $value
#取整
value=`expr $a / $b`
echo a / b = $value
#取余
value=`expr $a % $b`
echo a % b = $value
kch@kch:~/shell$ sh test.sh 
a + b = 35
a - b = 5
a * b = 300
a / b = 1
a % b = 5
kch@kch:~/shell$

关系运算符

关系运算符只支持数字,不支持字符串,除非字符串的值是数字。

-eq    检测两个数是否相等,相等返回 true。                   [ $a -eq $b ] 返回 false。
-ne    检测两个数是否不相等,不相等返回 true。                [ $a -ne $b ] 返回 true。
-gt    检测左边的数是否大于右边的,如果是,则返回 true。        [ $a -gt $b ] 返回 false。
-lt    检测左边的数是否小于右边的,如果是,则返回 true。        [ $a -lt $b ] 返回 true。
-ge    检测左边的数是否大于等于右边的,如果是,则返回 true。     [ $a -ge $b ] 返回 false。
-le    检测左边的数是否小于等于右边的,如果是,则返回 true。     [ $a -le $b ] 返回 true。

布尔运算符

!       非运算,表达式为 true 则返回 false,否则返回 true。     [ ! false ] 返回 true。
-o      或运算,有一个表达式为 true 则返回 true。              [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a      与运算,两个表达式都为 true 才返回 true。              [ $a -lt 20 -a $b -gt 100 ] 返回 false。

逻辑运算符

&& 	逻辑的 AND 	[[ $a -lt 100 && $b -gt 100 ]] 返回 false
|| 	逻辑的 OR 	[[ $a -lt 100 || $b -gt 100 ]] 返回 true

字符串运算符

= 	检测两个字符串是否相等,相等返回 true。 	    [ $a = $b ] 返回 false。
!= 	检测两个字符串是否不相等,不相等返回 true。 	[ $a != $b ] 返回 true。
-z 	检测字符串长度是否为0,为0返回 true。 	    [ -z $a ] 返回 false。
-n 	检测字符串长度是否不为 0,不为 0 返回 true。 	[ -n "$a" ] 返回 true。
$ 	检测字符串是否为空,不为空返回 true。 	    [ $a ] 返回 true。

例子

kch@kch:~/shell$ cat test_1.sh 
#!/bin/bash
a=15
b=20
#如果a不等于b
if [ $a != $b ];then
	echo true
fi
#如果a大于10或者b大于100
#法一
if [ $a -gt 10 -o $b -gt 100 ];then
	echo true
fi
#法二
if [ $a -gt 10 ] ||  [ $b -gt 100 ];then
	echo true
fi
#如果a大于10且b大于15
#法一
if [ $a -gt 10 -a $b -gt 15 ];then
	echo true
fi
#法二
if [ $a -gt 10 ] && [ $b -gt 15 ];then
	echo true
fi

str1="hello"
str2="hello"
str3=""
#检测字符串是否相等
if [ $str1 = $str2 ];then
	echo true
fi
#检测字符串长度是否为0,再取反判断
if [ ! -z $str3 ];then 
	echo true
fi
#检测字符串是否为空
if [ $str3 ];then
	echo true
fi
#检测字符串长度不为0
if [ -n $str1 ];then
	echo true
fi

kch@kch:~/shell$ sh test_1.sh 
true
true
true
true
true
true
true
kch@kch:~/shell$

Linux下常用命令

shell脚本执行的时候 会fork一个子进程 所有操作都在子进程进行 如果涉及到一些在脚本里设置环境变量的东西 脚本结束了 环境变量也就消失了。 在shell脚本中可直接执行一些命令,相当于在终端中执行,可以获取一些系统数据信息。下面是一下常用的命令,每一种命令都很多用法,不同参数不同用法,这里直接举一些常用的例子。

grep命令

grep常用于搜索或者筛选字符串

grep"he" -r显示文件名 -n显示行号
grep -v “he” 反向搜索

kch@kch:~/shell$ cat 1.txt 
hello
kch@kch:~/shell$ cat 2.txt 
name:angel  age:20 sex:girl
name:king   age:22 sex:boy
name:kak    age:23 sex:boy
kch@kch:~/shell$ cat 3.txt 
xx hello
kch@kch:~/shell$ grep -rn angel
2.txt:1:name:angel  age:20 sex:girl
kch@kch:~/shell$ grep -vrn  angel
1.txt:1:hello
3.txt:1:xx hello
2.txt:2:name:king   age:22 sex:boy
2.txt:3:name:kak    age:23 sex:boy
kch@kch:~/shell$ cat 2.txt | grep -rn angel
2.txt:1:name:angel  age:20 sex:girl
kch@kch:~/shell$

sed命令

sed命令比较常用于对字符串替换,删除等操作。

sed -i ‘1,4s/old/new/g’ 1.txt 替换文件1.txt 1-4行的字符串old为new
sed -i ‘1,2d’ 1.txt 删除1-2行
sed -i ‘/ni/d’ 1.txt 删除包含"ni"字符的行

kch@kch:~/shell$ cat 1.txt 
hello
hello
hello
hello
hello
kch@kch:~/shell$ sed -i '1,4s/hello/nihao/g' 1.txt 
kch@kch:~/shell$ cat 1.txt 
nihao
nihao
nihao
nihao
hello
kch@kch:~/shell$ sed -i '1,2d' 1.txt 
kch@kch:~/shell$ cat 1.txt 
nihao
nihao
hello
kch@kch:~/shell$ sed -i '/ni/d' 1.txt 
kch@kch:~/shell$ cat 1.txt 
hello
kch@kch:~/shell$

awk命令

awk常用于字符串分割操作

awk -F “:” ‘{print $1}’

kch@kch:~/shell$ cat 2.txt 
name:angel  age:20 sex:girl
name:king   age:22 sex:boy
name:kak    age:23 sex:boy
kch@kch:~/shell$ cat 2.txt |awk -F " " '{print $1}'
name:angel
name:king
name:kak
kch@kch:~/shell$ cat 2.txt |awk -F " " '{print $2}'
age:20
age:22
age:23
kch@kch:~/shell$ cat 2.txt |awk -F " " '{print $1 $2}'
name:angelage:20
name:kingage:22
name:kakage:23
kch@kch:~/shell$ cat 2.txt |awk -F " " '{print $1}'|awk -F ":" '{print $2}'
angel
king
kak
kch@kch:~/shell$

Linux命令还有很多,需要的时候,网上查一查就好了。