[关闭]
@Pigmon 2019-09-02T16:10:02.000000Z 字数 3895 阅读 938

Shell 笔记

Ubuntu


190822

变量赋值等号两边不能有空格,变量命名规则和C语言一样。

  1. your_name="Tom"

变量赋值不加 $ ,使用定义过的变量要加上:

  1. echo $your_name #或者${your_name}

加大括号有助于解释器找到变量名边界,应该一直都加上。

  1. my_name='King'
  2. readonly my_name #为变量加只读属性

删除变量(不能删除只读变量)

  1. unset your_name
  2. echo 'You are ' ${your_name} # 只输出 You are

字符串

单引号和双引号:
单引号字符串不支持变量和转义字符。
单引号字符串可以和变量及其他字符串数字等拼接。

  1. echo 123 'You are' ${your_name}", and I am the ${my_name}"
  2. # 123 You are Tom, and I am the King

字符串长度:

  1. echo ${#my_name} # 4
  1. # 提取子串
  2. string1='2B or not 2B, it is not a question.'
  3. echo ${string1:9:3} # 2B
  1. # 查找子串
  2. echo `expr index "${string1}" 2B` # 1 (不是从0开始)

数组

不支持多维数组,下标从0开始

  1. my_array=('Sex' 'Money' 'Game') # 注意是空格不是逗号
  2. echo ${my_array[1]} # Money
  3. echo ${my_array[@]} # 读取数组全部元素,输出:Sex Money Game
  4. echo 'The length of entire array:' ${#my_array[@]} # 3
  5. echo 'This is also array length:' ${#my_array[*]} # 3
  6. echo 'This is just the length of Game:' ${#my_array[2]} # 4

命令行参数

  1. # 脚本命令行参数,输入:./lesson00.sh 1 2 abc
  2. echo ${0} ${1} ${2} ${3} # ./lesson00.sh 1 2 abc
  3. echo 'Count of parameters:' ${#} # 3
  4. # 所有参数作为一个字符串提取
  5. for param in "$*"; do
  6. echo $param
  7. done
  8. # 每个参数作为一个字符串提取
  9. for param in "$@"; do
  10. echo $param
  11. done
  12. # 只有加双引号才有这个区别
  13. # 输出本进程ID
  14. echo $$
  15. # 后台运行的最后一个进程ID
  16. echo $!
  17. # Shell 使用的当前选项,相当于 set 命令
  18. echo $- # hB
  19. # 最后命令的退出状态,0或错误代码
  20. echo $?

运算符

表达式

Shell 本身不支持数学运算,要使用表达式
expr 为表达式命令,其他还有 awk
运算符两侧不能有空格

  1. sum=`expr 3 + 5` # 表达式要用键盘左上角的反引号扩起来
  2. echo ${sum}
  3. # 注意:运算符两侧要有空格,这样不行:3+5
  4. a=10
  5. b=8
  6. mul=`expr ${a} \* ${b}` # 注意乘号和C不同,要有反斜杠
  7. echo ${mul} # 80

关系运算符

  1. # # 是否相等 == 和 !=
  2. if [ ${a} == ${b} ] # 中括号内侧和运算符两侧必须有空格
  3. then
  4. echo ${a} 'echo to' ${b}
  5. else
  6. echo ${a} 'is not echo to' ${b}
  7. fi
  8. # # 只能用给数字的逻辑运算符
  9. # # -eq -ne -gt -ld -ge -le
  10. if [ ${a} -eq ${b} ]
  11. then
  12. echo ${a} 'echo to' ${b}
  13. else
  14. echo ${a} 'is not echo to' ${b}
  15. fi

逻辑运算符

  1. # if [ $a -le 10 -a $b -ge 1 ] # 或者
  2. if [[ $a -le 10 && $b -ge 1 ]] # 注意这2组[]
  3. then
  4. echo 'OK'
  5. fi
  6. # if [ $a -eq 10 -o $b -eq 10 ] # 或者
  7. # if [[ $a -eq 10 || $b -eq 10 ]] # 或者
  8. if [[ $a == 10 || $b == 10 ]]
  9. then
  10. echo 'OK'
  11. fi
  12. if [ ! $a == $b ]
  13. then
  14. echo 'OK'
  15. fi
  16. result=$[$a != $b] # 等号两边不能有空格;中括号内可以无空格?
  17. echo $result # 1

字符串逻辑运算

  1. str1='abc'
  2. str2='efg'
  3. str3='abc'
  4. if [ $str1 = $str3 ] # 注意不是 ==
  5. then
  6. echo $str1 'eque to' $str3
  7. fi
  8. if [ $str1 != $str2 ]
  9. then
  10. echo $str1 'not eque to' $str2
  11. fi
  12. if [ -z $str1 ]
  13. then
  14. echo $str1 'len is 0'
  15. fi
  16. if [ -n $str1 ]
  17. then
  18. echo $str1 'len is not 0'
  19. fi
  20. if [ $str1 ]
  21. then
  22. echo $str1 'is not empty'
  23. fi

文件逻辑操作

  1. file="/home/pigmon/Workspace/ShellLesson/lesson00.sh"
  2. if [ -e $file ]
  3. then
  4. echo 'File exists.'
  5. fi
  6. # -s 文件不空
  7. # -r -w -x 可读,可写,可执行
  8. # -d 是否是目录

标准输出

echo

  1. echo -e "Line 1.\n"
  2. echo "Line 2."
  3. echo -e "Line 3.\c" # \c 代表不换行
  4. echo "Line 4."
  5. echo `date`

输出:
Line 1.

Line 2.
Line 3.Line 4.
2019年 08月 22日 星期四 13:52:52 CST

printf

比 echo 可移植性更好,跟C的printf很接近。
与C语言区别:

没有小括号
%后面跟一个减号‘-’代表左对齐,不跟减号代表右对齐
格式描述字符串可以用单引号或者无引号
以及如下:

  1. printf "%-10s %-8s %-4.2f\n" 郭靖 66.1234
  2. # 郭靖 男 66.12
  3. # 格式只指定了一个参数,但多出的参数仍然会按照该格式输出,format-string 被重用
  4. printf "%s\n" abc def
  5. # 如果没有 arguments,那么 %s 用NULL代替,%d 用 0 代替
  6. printf "%s and %d \n"

test 命令

  1. if test $a != $b
  2. then
  3. echo Not eque
  4. fi

流程控制

循环也支持 break 和 continue

if elif else

  1. exp1=$[2*3] # 这里*前面不用/
  2. exp2=$[1+5] # 而且这里操作符两边又不能有空格了
  3. if test $[exp1] -eq $[exp2] # 这里必须有[]
  4. then
  5. echo 'Eque'
  6. elif test $[exp1] -gt $[exp2]
  7. then
  8. echo 'Greater'
  9. else
  10. echo 'Less'
  11. fi

for

  1. for num in 1 2 3 4 5
  2. do
  3. printf "%d," $num
  4. done
  5. echo ""
  6. for str in I am the King!
  7. do
  8. echo $str
  9. done

while

  1. num=10
  2. while (( $num <= 15 ))
  3. do
  4. printf "%d," $num
  5. let "num++"
  6. done
  7. echo ""

until

  1. a=0
  2. until [ ! $a -lt 10 ]
  3. do
  4. printf "%d," $a
  5. a=`expr $a + 1`
  6. done
  7. echo ""

case

  1. echo '输入 1 到 4 之间的数字:'
  2. echo '你输入的数字为:'
  3. read aNum
  4. case $aNum in
  5. 1) echo '你选择了 1'
  6. ;;
  7. 2) echo '你选择了 2'
  8. ;;
  9. 3) echo '你选择了 3'
  10. ;;
  11. 4) echo '你选择了 4'
  12. ;;
  13. *) echo '你没有输入 1 到 4 之间的数字'
  14. ;;
  15. esac
  16. # case 后面别忘了 in
  17. # 条件后面是 )
  18. # 符合条件,执行至 ;; 为止
  19. # *) 相当于 default
  20. # 结尾是反过来的case:esac

函数

  1. # # ---------------------------
  2. fun1()
  3. {
  4. echo "A most simple function."
  5. }
  6. fun1 # A most simple function.
  7. # # ---------------------------
  8. fun2()
  9. {
  10. echo "A function with return value."
  11. ret=`expr 3 + 5`
  12. return $ret
  13. }
  14. fun2 # A function with return value.
  15. echo $? # 8 捕捉最后一个输出
  16. echo $? # 0 代表上一个命令没有出错
  17. # 说明如果函数调用和$?之间插入任何语句,都会丢失返回值。
  18. # # ---------------------------
  19. fun3()
  20. {
  21. echo 'Count of params is:' $#
  22. echo 'The 1st parameter is:' ${1}
  23. }
  24. fun3 param1 2
  25. # Count of params is: 2
  26. # The 1st parameter is: param1
  27. # 注意如果参数个数超过9就必须加{},如${10}

输入输出重定向

文件描述符,0-stdin, 1-stdout, 2-stderr

输出重定向

刷新:

  1. $ command1 > file1

追加

  1. $ command1 >> file1

输入重定向

  1. $ command1 < file1

同时重定向输入输出

  1. command1 < infile > outfile

特定流重定向

将stderr重定向

  1. command1 2 >> file1

将stdout, stderr全部重定向(不写描述符是不是就这个效果?)

  1. $ command >> file 2>&1

stdin, stdout 重定向

  1. $ command < infile1 > outfile1

屏蔽输出

  1. $ command > /dev/null

文件引用(包含)

通过 . 或者 source 进行引用
例如:
include.sh

  1. #!/bin/bash
  2. my_name='The King'

src.sh

  1. #!/bin/bash
  2. # source ./include.sh # 或者
  3. . ./include.sh
  4. echo 'I am '$my_name # I am The King
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注