bash shell 编程练习

时间:2022-02-03 18:33:40

1. 创建可执行文件 t2.sh 并打印 "hello world!"

xiluhua@localhost ~ $ mkdir tscripts
xiluhua@localhost ~ $ cd tscripts/
xiluhua@localhost ~/tscripts $ echo '#!/bin/bash' >> t2.sh
xiluhua@localhost ~/tscripts $ echo 'echo "hello world!"' >>t2.sh 
xiluhua@localhost ~/tscripts $ chmod +x *
xiluhua@localhost ~/tscripts $ ./t2.sh 
hello world!

 2. 运行可执行文件的 3中方法

xiluhua@localhost ~/tscripts $ ./t2.sh 
hello world!
xiluhua@localhost ~/tscripts $ sh t2.sh 
hello world!
xiluhua@localhost ~/tscripts $ /bin/sh t2.sh 
hello world!

 3. 使用变量

xiluhua@localhost ~/tscripts $ name=zhangsan
xiluhua@localhost ~/tscripts $ echo $name
zhangsan
xiluhua@localhost ~/tscripts $ echo ${name}
zhangsan
xiluhua@localhost ~/tscripts $ 

变量名外面的花括号是可选的,可加可不加,加花括号是为了帮助解释器识别变量的边界

4. for 循环打印 java c c++ php scala,体会 ${} 的作用

#!/bin/bash
for skill in java c c++ php scala;do
    echo "I am good at $skill"
done
 
echo "======================================="
for skill in java c c++ php scala;do
    echo "I am good at $skillScript"
done
 
echo "======================================="
for skill in java c c++ php scala;do
    echo "I am good at ${skill}Script"
done

5. 只读变量,unset 不能取消

xiluhua@localhost ~/tscripts $ name=jack
xiluhua@localhost ~/tscripts $ readonly name
xiluhua@localhost ~/tscripts $ echo $name
jack
xiluhua@localhost ~/tscripts $ name=Tom
-bash: name: readonly variable
xiluhua@localhost ~/tscripts $ unset name
-bash: unset: name: cannot unset: readonly variable
xiluhua@localhost ~/tscripts $ 

6. 非只读变量可以取消,取消后打印为空

xiluhua@localhost ~/tscripts $ unname=Jerry
xiluhua@localhost ~/tscripts $ unset unname
xiluhua@localhost ~/tscripts $ echo $unname

 7. 单引号

①. 单引号里的任何字符都原样输出,单引号变量中的变量是无效的;
②. 单引号字符串中不能出现单引号,对单引号使用转义符后也不行
xiluhua@localhost ~ $ name='Leo'
xiluhua@localhost ~ $ echo '$name'
$name
xiluhua@localhost ~ $ echo '$'name'
> 

8. 双引号

①. 双引号里可以有变量
②. 双引号里可以出现转义字符
xiluhua@localhost ~ $ echo "I am $name"
I am Leo
xiluhua@localhost ~ $ echo "\\I am $name \\"
\I am Leo \

9. 拼接字符串

xiluhua@localhost ~ $ echo "He is $name"
He is Leo
xiluhua@localhost ~ $ echo "$name is handsome"!
Leo is handsome!
xiluhua@localhost ~ $ echo "$name is handsome!"
-bash: !": event not found

10. 获取字符串长度

xiluhua@localhost ~ $ echo ${#name}
3

11. 提取字符串

xiluhua@localhost ~ $ echo ${name:0:2}
Le

12. 查找子字符串

xiluhua@localhost ~ $ expr index $name e
2

13. 数组

bash支持一维数组(不支持多维数组),并且没有限定数组的大小。
类似与C语言,数组元素的下标由0开始编号。获取数组中的元素要利用下标,下标可以是整数或算术表达式,其值应大于或等于0。

14. 声明数组并打印一

xiluhua@localhost ~ $ arr=(a b c)
xiluhua@localhost ~ $ echo $arr
a
xiluhua@localhost ~ $ echo ${arr[0]}
a
xiluhua@localhost ~ $ echo ${arr[2]}
c
xiluhua@localhost ~ $ echo ${arr[@]}
a b c

15. 声明数组并打印二

xiluhua@localhost ~ $ arr=()
xiluhua@localhost ~ $ echo ${arr[@]}
 
xiluhua@localhost ~ $ arr[0]=x
xiluhua@localhost ~ $ echo ${arr[0]}
x
xiluhua@localhost ~ $ arr[1]=y
xiluhua@localhost ~ $ arr[2]=z
xiluhua@localhost ~ $ echo ${arr[@]}  # 打印数组全部内容
x y z
xiluhua@localhost ~ $ echo ${arr[*]}  # 打印数组全部内容
x y z

 

16.  获取数组长度

xiluhua@localhost ~ $ echo ${#arr[@]}
3

17. 获取数组单个元素的长度

xiluhua@localhost ~ $ arr[3]=yes
xiluhua@localhost ~ $ echo ${arr[3]}
yes
xiluhua@localhost ~ $ echo ${#arr[3]}
3

18. shell 传递参数

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
echo 'args 0,file name: '$0
echo 'args 1: '$1
echo 'args 2: '$2
echo 'args 3: '$3

19. 特殊字符

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
echo 'shell exercise'
echo 'first arg: '$1
echo 'args total number: '$#
echo 'args are: '$*
echo 'current process id: '$$
echo 'the last proess id run in the background: '$!
echo 'args are: '$@
echo 'shell options: '$-
echo 'command run status: '$?

20. $* 与$@ 的区别

相同点:都是引用所有参数。
不同点:只有在双引号中体现出来。假设在脚本运行时写了三个参数 123,,
        "*"   等价于 "1 2 3"(传递了一个参数),
        "@"   等价于 "1" "2" "3"(传递了三个参数)

21. $* 与$@ 的区别实例

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
 
echo '--- $* DEMO ---'
for i in "$*";do
    echo 'i: '$i
done
 
echo '--- $@ DEMO ---'
for i in "$@";do
    echo 'i: '$i
done

 22. 新建可执行文件

sbash='#!/bin/bash'
sauth='# auth: xiluhua'
sdate="# date: $(date +%Y-%m-%d)"
shead="$sbash\n$sauth\n$sdate"

 

23. expr

原生bash不支持简单的数学运算,但是可以通过其他命令来实现,例如 awk 和 expr,expr 最常用。

expr 是一款表达式计算工具,使用它能完成表达式的求值操作。

  • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
  • 完整的表达式要被 ` ` 包含,注意这个字符不是常用的单引号,在 Esc 键下边。

例如,两个数相加(注意使用的是反引号 ` 而不是单引号 '):

xiluhua@localhost ~/tscripts $ expr 2 + 2
4
xiluhua@localhost ~/tscripts $ sum=`expr 2 + 2`
xiluhua@localhost ~/tscripts $ echo $sum
4

 

24. expr 加减乘除运算

xiluhua@localhost ~/tscripts $ a=20
xiluhua@localhost ~/tscripts $ b=10
xiluhua@localhost ~/tscripts $ sum=`expr $a + $b`
xiluhua@localhost ~/tscripts $ echo $sum
30
xiluhua@localhost ~/tscripts $ diff=`expr $a - $b`
xiluhua@localhost ~/tscripts $ echo $diff
10
xiluhua@localhost ~/tscripts $ prod=`expr $a \* $b`
xiluhua@localhost ~/tscripts $ echo $prod
200
xiluhua@localhost ~/tscripts $ odd=`expr $a / $b`
xiluhua@localhost ~/tscripts $ echo $odd
2

25. expr 和算术运算符实例

注意:乘号(*)前边必须加反斜杠(\)才能实现乘法运算;

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
 
a=20
b=10
 
echo '--- expr DEMO ---'
echo 'a=20'
echo 'b=10'
sum=`expr $a + $b`
dif=`expr $a - $b`
pro=`expr $a \* $b`
odd=`expr $a / $b`
 
echo 'sum: '$sum
echo 'dif: '$dif
echo 'pro: '$pro
echo 'odd: '$odd
 
if [ $a == $b ]
then
        echo 'a equal b'
fi
 
if [ $a != $b ]
then
        echo a "don't equal b"
fi

26. 逻辑运算符

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
a=20
b=10
 
echo '--- bool operators DEMO ---'
echo 'a=20'
echo 'b=10'
 
if [ $a != $b ]
then
        echo 'a !equal b'
else
        echo 'a equal b'
fi
 
if [ $a -gt $b -a $a -lt 30 ]
then
        echo 'a gt 10 but lt 30'
else
        echo '! ag 10 but lt 30'
fi
 
if [ $b -eq 10 -o $b -gt 9 ]
then
        echo 'b ge 9'
else
        echo '!b ge 9'
fi

26. 字符串运算符

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
a=abc
b=efg
c=''
 
echo "--- string DEMO ---"
echo "a=abc"
echo "b=efg"
 
if [ $a = $b ]
then
        echo "a eq b"
else
        echo "a !eq b"
fi
 
if [ $a != $b ]
then
    echo "a !eq b"
else
    echo "a eq b"
fi
 
if [ -z $a ]
then
        echo "a's length is 0"
else
        echo "a's length is ${#a}"
fi
 
if [ -z $c ]
then
    echo "c's length is 0"
else
    echo "c's length is ${#c}"
fi
 
if [ -n $a ]
then
    echo "a's length is ${#a}"
else
    echo "a's length is 0"
fi
 
if [ -n $c ]
then
    echo "c's length is ${#c}"
else
    echo "c's length is 0"
fi
 
if [ $a ]
then
    echo "a's length is ${#a}"
else
    echo "a's length is 0"
fi
 
if [ $c ]
then
    echo "c's length is ${#c}"
else
    echo "c's length is 0"
fi

 27. 关系运算符

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
 
file='/home/xiluhua/tscripts'
 
echo '--- file test operators DEMO ---'
echo $file
 
if [ -e $file ]
then
        echo "$file is exist"
else
        echo "$file is !exist"
fi
 
if [ -d $file ]
then
        echo "$file is a directory"
fi
 
if [ -f $file ]
then
        echo "$file is a file"
fi
 
if [ -s $file ]
then
        echo "$file is empty"
fi
 
if [ -r $file ]
then
        echo "$file is readable"
else
        echo "$file is !readable"
fi
 
if [ -w $file ]
then
        echo "$file is writable"
else
        echo "$file is !writable"
fi
 
if [ -x $file ]
then
        echo "$file is excecutable"
else
        echo "$file is !excecutable"
fi

 28. echo 显示转义字符

echo "\"It is a test\""

 29. echo 开启换行

xiluhua@localhost ~/tscripts $ echo -e "Tom \n is from China"
Tom 
 is from China

30. echo 不开启换行

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
echo -e "Tom is from China, \c"
echo "he is programmer."

31. printf

#!/bin/bash
# auth: xiluhua
# date: 2017-01-14
printf "%-10s %-8s %-10s\n" name gender weight[kg]
printf "%-10s %-8s %-4.2f\n" Jack male 68.1234
printf "%-10s %-8s %-4.2f\n" Tom male 78.6512
printf "%-10s %-8s %-4.2f\n" Susan female 80

 32. printf

%s %c %d %f都是格式替代符
%-10s 指一个宽度为10个字符(-表示左对齐,没有则表示右对齐),任何字符都会被显示在10个字符宽的字符内,如果不足则自动以空格填充,超过也会将内容全部显示出来。
%-4.2f 指格式化为小数,其中.2指保留2位小数。

 33. while (1)

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
n1=$1
 
echo '--- while DEMO ---'
echo 'n1=$n1'
 
while (( $n1 <= 5 ))
do
        echo $n1
        n1=`expr $n1 + 1`  # 等同于 let 'n1++'
done

34. while (2)

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
while true
do 
        read -p 'please input a film: ' film
        if [ -z $film ]
        then
                echo > /dev/null
        else
                if [ $film = 'q' ]
                then 
                        exit
                fi
 
                if [ $film = 'ironman' ]
                then
                        echo $film' is a good film!'
                        exit 0;
                else
                        echo 'this film is not good enough'
                fi
        fi
done

35. until

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
n1=$1
 
if [ -z $n1 ]
then
        n1=1
fi
 
echo 'n1='$1
 
until test $[n1] -gt 2
do 
        echo $n1
        let 'n1++'
done

36. case (1)

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
while true
do
    read -p 'please enter a num:' n1
    case $n1 in
        1|2|3|4|5) echo 'u enter:'$n1
        ;;
        *) echo 'game over!'
        break
    esac
done

37. case (2)

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
while true
do
    read -p 'please enter a num:' n1
    case $n1 in
        1|2|3|4|5) echo 'u enter:'$n1
        ;;
        *) continue
    esac
done

 38. funtion

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
first(){
    echo 'i am handsome!'
}
 
first

39. function 传参

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
second(){
    echo 'first args:'$1
    echo 'second args:'$2
}
 
second 1 2

40. 重定向

标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

41. 输出错误重定向

xiluhua@localhost ~/t2scripts $ cat echo 2>>err.log
xiluhua@localhost ~/t2scripts $ less err.log 
cat: echo: No such file or directory

42. 2&>1

 find /etc -name passwd 2>&1 | less > e.log

43. 将标准输出重定向到一个文件的同时并在屏幕上显示

格式:<command> 2>&1 | tee <logfile>

xiluhua@localhost ~/t2scripts $ id das 2>&1 |tee logfile
id: das: No such user
xiluhua@localhost ~/t2scripts $ less logfile
id: das: No such user
logfile (END) 

44. Here Document

xiluhua@localhost ~/t2scripts $ wc -l << EOF
> 1
> 2
> 3
> EOF
3

 45. function 引用

#!/bin/bash
# auth: xiluhua
# date: 2017-01-15
 
. ./t21.sh
 
second 3 4

 46. 为变量设定默认值

[ -z "$name" ] && name="obama"

 47. 测试脚本语法

bash -n scripts.sh

 48. 1加到100

#!/bin/bash
# auth: xiluhua
# date: 2017-03-19
declare -i sum=0
 
for i in {1..100};do
    sum=$[$sum+$i]
    if [ $i -eq 100 ];then
        echo $sum
    fi  
done