欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  科技

shell 基本操作小结

程序员文章站 2022-03-29 10:37:28
1. 和`if else fi`命令 运行结果(demo.sh不存在): 需要注意的是 等号两边是不能有空格的; 中[]左右两侧都是有空格的。 2.shell基本操作 2.1 变量大于,等于,小于 表示大于; 表示小于; 表示等于。运行结果为: 2.2 三目运算符(?:) 输出: 上面的代码首先检查 ......

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