shell 基本操作小结

1.echoif else fi命令

#!/bin/bash
echo hello;echo there
filename=demo.sh
if [ -e "$filename" ]; then 
    echo "$filename already exists!";cp $filename $filename.bak
else
    echo "$filename does not exist!";
fi;
echo "File test complete!"

运行结果(demo.sh不存在):

hello
there
demo.sh does not exist!
File test complete!

需要注意的是filename=demo.sh等号两边是不能有空格的;if [ -e "$filename" ]中[]左右两侧都是有空格的。

2.shell基本操作

2.1 变量大于,等于,小于

#!/bin/bash
a=1
if [ $a -gt 0 ]; then
    echo "greater than zero!"
else
    echo "no more than zero!"
fi
if [[ $a -lt 0 ]]; then
    echo "less than zero!"
else
    echo "no less than zero!"
fi
if [[ a -eq 1 ]]; then
    echo "equal to 1!"
else
    echo "not equal to 1!"
fi

-gt表示大于;-lt表示小于;-eq表示等于。运行结果为:

greater than zero!
no less than zero!
equal to 1!

2.2 三目运算符(?😃

# ? is 3 operator
b=10
((t=b<20?6:4)) # t = 6
echo "t=$t"
# variable in () is a part region variable
(b=20;echo "b = $b") # b = 20
echo "b = $b" # b = 10

和C,java等语言类似,shell中的?:也是三目运算符。()表示一个建立局部作用域,可以暂时屏蔽全局变量。上式的运行结果为:

t=6
b = 20
b = 10

2.3 数组

2.3.1 数组创建
# () create an array
arr=(1 2 3 5 6)
echo "arr[3] = ${arr[3]}"

输出:

arr[3] = 5
2.3.2 数组长度
# get the length of array
echo "length of arr is ${#arr[*]}" # 5
echo "length of arr is ${#arr[@]}" # 5

输出:

length of arr is 5
length of arr is 5
2.3.3 输出数组元素
# get all content of array
echo "arr:${arr[*]}" # 1 2 3 5 6
# or
echo "arr:${arr[@]}" # 1 2 3 5 6

输出:

arr:1 2 3 5 6
arr:1 2 3 5 6
2.3.4 修改数组元素
# assign a new element to an array
arr[1]=100
echo "arr:${arr[@]}" # 1 100 3 5 6
# if assign index if out of bound,then auto create a new element of array
arr[10]=20 # 1 100 3 5 6 20
echo "arr:${arr[@]}"

输出:

arr:1 100 3 5 6
arr:1 100 3 5 6 20

注意如果赋值索引超出数组长度,相当于是给数组末尾增加一个新元素。

2.3.5 删除数组元素
# delete the element of array
unset arr[1] # delete the arr[1],1 3 5 6 20
echo "arr:${arr[*]}" # 1 3 5 6 20
# clear the whole array
unset arr 
echo "${#arr[@]}" # length 0

输出:

arr:1 3 5 6 20
0

unset 如果跟上数组的索引,是删除该位置的数组元素;如果直接跟数组名,相当于是清空数组。

2.3.6 数组切片
arr=(1 2 4 10)
# slice of array
# ${array_name[*]:start:length},return is a string
echo "${arr[@]:0:3}" # 1 2 4
# assignment
arr1=(${arr[*]:1:2}) # arr1:2 4
echo "${#arr1[@]}"
echo "arr1:${arr1[@]}"

输出:

1 2 4
2
arr1:2 4
2.3.7 数组元素替换
# replace
# ${array_name[@]/origin_element/new_element}
# this operation doesn't change the origin array
# and will return a string that seperated by space
echo "${arr1[*]/2/20}" # 20 4,arr1:2 4
arr1=(${arr1[*]/4/40}) # arr1:2 40
echo "${arr1[*]}" # 2 40

输出:

20 4
2 40

2.4 文件操作

# file operation
if [ ! -w 't.txt' ]; then
	touch t.txt
fi
echo 'test text' > t.txt 
cp t.{txt,back} # cp t.txt to t.back
filename="/home/lyrichu/login"
if [ -r $filename ] # if file is readable
	then 
	echo "$filename is readable!"
else
	echo "$filename is not readable!"
fi

if [ -e $filename ]
	then
	echo "$filename exists!"
else
	echo "$filename doesn't exist!"
fi 

输出:

/home/lyrichu/login is not readable!
/home/lyrichu/login doesn't exist!

上面的代码首先检查t.txt文件是否可写,如果不可写,则重新创建一个文件;然后向t.txt文件写入字符串'test text';接着复制t.txt文件到t.back文件;
然后判断/home/lyrichu/login文件是否可读以及是否存在。

2.5 {}创建一个代码块

# {} create a code block
a=10;echo "a=$a"
{ a=20; } # a = 20
echo "a=$a" # a = 20

输出:

a=10
a=20

2.6 expr 计算表达式的值

val=`expr $a + $b` # a = 20,b = 10
echo "a + b = $val" # a + b = 30

val=`expr $a \* $b` # \* means multiply,a*b = 10*20 = 200
echo "a*b=$val"

# divide
val=`expr $a / $b` # 20/10 = 2
echo "a / b = $val"

# mod
val=`expr $a % 9` # 20 % 9 = 2
echo "$a % 9 = $val" # 20 % 9 = 2

输出:

a + b = 30
a*b=200
a / b = 2
20 % 9 = 2

expr可以计算shell表达式的值,上式分别计算了+,*,/,%运算,注意乘法需要使用\*转义。

2.7 逻辑运算符

if [ $a == $b ]
then echo "a == b!"
fi
if [ $a != $b ] 
	then 
	echo "a != b" 
fi 

# && logit and
if [[ $a -gt 10 && $b -lt 20 ]]
	then
	echo "$a > 10 and $b < 20!"
else
	echo "bad condition!"
fi
# || logit or 
if [[ $a -gt 15 || $b -gt 15 ]]
	then
	echo "a > 15 or b > 15"
else
	echo "a<=15 and b<=15"
fi 

输出:

a != b
20 > 10 and 10 < 20!
a > 15 or b > 15

== 用于比较数字相等;!=用于比较数字不等。&&表示shell中的逻辑与;||表示shell中的逻辑或运算。

2.8 字符串操作

#!/bin/bash
s1="abhsgd"
# 获取字符串长度
echo "length of s1:" ${#s1}
#提取子字符串
# ${string:position},在string中,从position位置开始提取子字符串
echo ${s1:2} # hsgd
# ${string:position:length},string中,从position位置开始提取长度为length的子字符串
echo ${s1:2:2} # hs 
# ${string#substring},从string的开头, 删除最短匹配substring的子串,返回删除子串之后的字符串
echo ${s1#ab} #hsgd
# ${string##substring},从string的开头, 删除最长匹配substring的子串
echo ${s1##abh} # sgd
# ${string%substring},从string的结尾, 删除最短匹配substring的子串
echo ${s1%gd} # absh
# ${string%%substring},从string的结尾, 删除最长匹配substring的子串
echo ${s1%%hsgd} # ab
# ${string/substring/replacement},使用replacement,来代替第一个匹配的substring
echo ${s1/hs/HS} # abHSgd
# ${string//substring/replacement},使用replacement, 代替所有匹配的substring
s2=ahjhjhhshdg
echo ${s2//h/H} # aHjHjHHsHdg
# ${string/#substring/replacement},如果string的前缀匹配substring, 那么就用replacement来代替匹配到的substring
echo ${s2/#ahj/AHJ} # AHJhjhhshdg
# ${string/%substring/replacement},如果string的后缀匹配substring, 那么就用replacement来代替匹配到的substring
echo ${s2/%shdg/SHDG} # ahjhjhhSHDG
## 注:上面replacement可以是正则表达式,比如:
s3=/home/lyrichu/demo.txt 
# 得到文件名
echo ${s3##*/} #demo.txt 
# 得到目录名
echo ${s3%/*} # /home/lyrichu

输出:

length of s1: 6
hsgd
hs
hsgd
sgd
abhs
ab
abHSgd
aHjHjHHsHdg
AHJhjhhshdg
ahjhjhhSHDG
demo.txt
/home/lyrichu

2.9 控制流

2.9.1 if语句
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 "Error!"
fi

# test command
if test $a -lt $b
	then 
	echo "$a < $b!"
else
	echo "$a >= $b!"
fi 

输出:

10 < 20!
10 < 20!

其中test命令用来判断一条语句的真假。

2.9.2 for 语句
# for loop
for i in 1 2 3 4
do
	echo "The value is $i"
done

# for loop of string
for s in This is a string
do
	echo "$s"
done

输出:

The value is 1
The value is 2
The value is 3
The value is 4
This
is
a
string
2.9.3 while 循环
#while loop
i=1
while(( $i<5 ))
do
	echo "$i"
	let "i++"
done

echo "Press CTRL+D to exit!"
echo -n "Who is the most beautiful girl?"
while read MAN
do
	echo "Yes! $MAN is really beautiful!"
done 

输出:

1
2
3
4
Press CTRL+D to exit!
Who is the most beautiful girl?yp
Yes! yp is really beautiful!
2.9.4 case 语句
# case mode
echo "Please input a number between 1 to 4!"
read input
case input in
	1) echo "Your choice is 1!"
	;;
	2) echo "Your choice is 2!"
	;;
	3) echo "Your choice is 3!"
	;;
	4) echo "Your choice is 4!"
	;;
	*) echo "You don't choose a number between 1 and 4!"
	;;
esac 

## break 
while :
do
	echo "PLease input a number between 1 and 5!"
	read n 
	case $n in 
		1|2|3|4|5) echo "Your input number is $n!"
		;;
		*) echo "Your input is not between 1 and 5!"
			break
		;;
	esac 
done

输出:

Please input a number between 1 to 4!
3
Your choice is 3!
PLease input a number between 1 and 5!
5
Your input number is 5!
PLease input a number between 1 and 5!
10
Your input is not between 1 and 5!

2.10 函数

2.10.1 一个简单的没有参数,没有返回值的函数
func1(){ # fuction that does not have parameters
	echo "This is my first function!"
}
# call function
func1

输出:

This is my first function!
2.10.2 带有返回值的函数
func2(){ # function with return
	echo "This is function that has return!"
	return 1
}
# use $? to get the function return value
func2
echo "The return value of func2 is $?"

输出:

This is function that has return!
The return value of func2 is 1

在末尾使用return关键字即可以返回一个值,使用$?来获取函数的返回值。

函数传递参数,获取参数总数,参数值以及第i个参数
# input parameters of function
# $1,$2,... to the first n parameter
func3(){
	n=$# # get the total number of parameters
	echo "There are total $n parameters of func3!"
	echo "The first parameter is:$1"
	echo "The second parameter is $2"
	echo "The tenth parameter is ${10}"
	echo "The all parameters as string is:$*"
}
func3 1 2 3 4 5 6 7 8 9 10 11 12

输出:

There are total 12 parameters of func3!
The first parameter is:1
The second parameter is 2
The tenth parameter is 10
The all parameters as string is:1 2 3 4 5 6 7 8 9 10 11 12

3.一些简单的shell 实例

3.1 计算3个数的最大值

# calculate the max value of 8,4,5
a=5
b=4
c=8
i=$a

if [[ $i -lt $b ]]
    then
    i=$b
fi

if [[ $i -lt $c ]]
    then
    i=$c
fi
echo "The max value of $a,$b,$c is $i"

输出:

The max value of 5,4,8 is 8

3.2 随机猜数

#!/bin/bash
# random generate a number between 1 and 3, and let you to
# guess the number's value,if you are right,then echo "You guess right!"
# else echo "You guess wrong!"
# use while to play the game,input "quit" to quit the game
# $RANDOM generate a number between 0 and 32767
while :
do
    r=$RANDOM
    r=`expr $r % 3 + 1` # between 1 and 3
    echo "Please input a number between 1 and 10(enter quit to quit the game):"
    read g
    if [[ $g = "quit" ]]
        then
        break
    elif [[ $g == $r ]]; then
        echo "You guess right!"
    else
        echo "You guess wrong!"
    fi
done

输出:

Please input a number between 1 and 10(enter quit to quit the game):
2
You guess right!
Please input a number between 1 and 10(enter quit to quit the game):
3
You guess right!
Please input a number between 1 and 10(enter quit to quit the game):
3
You guess wrong!
Please input a number between 1 and 10(enter quit to quit the game):
quit

3.3 求小于100的所有偶数的和

#!/bin/bash
# sum the even number that less than 100
i=2
s=0
while [[ $i -lt 100 ]]; do
    s=`expr $s + $i`
    i=`expr $i + 2`
done
echo "The even number that less than 100's sum is $s"

输出:

The even number that less than 100's sum is 2450

3.4 输出星号(*)金字塔

#!/bin/bash
# output the pyramid of stars
for i in 4 3 2 1 0
do
    j=$i 
    while [[ $j -gt 0 ]]
    do
        echo -n " "
        let "j--"
    done
    j=`expr 9 - 2 \* $i`
    while [[ $j -gt 0 ]]
    do
        echo -n "*"
        let "j--"
    done
    j=$i 
    while [[ $j -gt 0 ]]
    do
        echo -n " "
        let "j--"
    done
    echo ""
done

输出:

    *    
   ***   
  *****  
 ******* 
*********

Reference

1. [linux shell 字符串操作(长度,查找,替换)详解](http://www.cnblogs.com/chengmo/archive/2010/10/02/1841355.html) 2. [linux shell 数组建立及使用技巧](https://www.cnblogs.com/chengmo/archive/2010/09/30/1839632.html) 3. [(实验楼)高级 bash 脚本编程指南](https://www.shiyanlou.com/courses/944)
posted @ 2018-06-21 14:21  lyrichu  阅读(638)  评论(0编辑  收藏  举报