一、shell学习笔记

1.shell脚本中函数使用

函数定义在前,调用在后,顺序反了就没有效果了。
函数调用为:函数名 参数列表

函数内部通过以下变量访问函数的参数:
shell脚本函数中:
  $0: 这个脚本的名字
  $n: 这个脚本传入的参数值,n取1..9
  $*: 这个脚本所有参数
  $#: 这个脚本参数个数
  $$: 这个脚本运行时的PID
  $!: 执行上一个背景指令的PID
  $?: 执行上一个指令的返回值

举例说:
脚本名称叫test.sh 入参三个: 1 2 3
运行test.sh 1 2 3后
  $*为"1 2 3"(一起被引号包住)
  $@为"1" "2" "3"(分别被包住)注意:"$@"必须被引用.
  $#为3(参数数量)

$* 和 $@ 的区别:
$* 和 $@ 都表示传递给函数或脚本的所有参数,不被双引号(" ")包含时,都以"$1" "$2" … "$n" 的形式输出所有参数。
但是当它们被双引号(" ")包含时,"$*" 会将所有的参数作为一个整体,以"$1 $2 … $n"的形式输出所有参数;"$@" 会将各个参数分开,以"$1" "$2" … "$n" 的形式输出所有参数。
下面的例子可以清楚的看到 $* 和 $@ 的区别:

  1. #!/bin/bash
  2. echo "\$*=" $*
  3. echo "\"\$*\"=" "$*"
  4. echo "\$@=" $@
  5. echo "\"\$@\"=" "$@"
  6. echo "print each param from \$*"
  7. for var in $*
  8. do
  9. echo "$var"
  10. done
  11. echo "print each param from \$@"
  12. for var in $@
  13. do
  14. echo "$var"
  15. done
  16. echo "print each param from \"\$*\""
  17. for var in "$*"
  18. do
  19. echo "$var"
  20. done
  21. echo "print each param from \"\$@\""
  22. for var in "$@"
  23. do
  24. echo "$var"
  25. done

执行 ./test.sh "a" "b" "c" "d",看到下面的结果:

  1. $*= a b c d
  2. "$*"= a b c d
  3. $@= a b c d
  4. "$@"= a b c d
  5. print each param from $*
  6. a
  7. b
  8. c
  9. d
  10. print each param from $@
  11. a
  12. b
  13. c
  14. d
  15. print each param from "$*"
  16. a b c d
  17. print each param from "$@"
  18. a
  19. b
  20. c
  21. d

2. shell脚本中判断上一个命令是否执行成功

shell中使用符号“$?”来显示上一条命令执行的返回值,如果为0则代表执行成功,其他表示失败。
结合if-else语句实现判断上一个命令是否执行成功。

  1. 示例:
  2. if [ $? -ne ]; then
  3. echo "failed"
  4. else
  5. echo "succeed"
  6. fi
  7.  
  8. 或者:
  9. if [ $? -eq ]; then
  10. echo "succeed"
  11. else
  12. echo "failed"
  13. fi

3.shell脚本中的if条件测试

(1)整数变量表达式

if [ int1 -eq int2 ] 如果int1等于int2
if [ int1 -ne int2 ] 如果不等于
if [ int1 -ge int2 ] 如果>=
if [ int1 -gt int2 ] 如果>
if [ int1 -le int2 ] 如果<=
if [ int1 -lt int2 ] 如果<

(2)字符串变量表达式

if [ $a = $b ] 如果string1等于string2 字符串允许使用赋值号做等号(通过‘=’两端是否有空格来判断)
if [ $string1 != $string2 ] 如果string1不等于string2
if [ -n $string ] 如果 string 为非空(非0)空则为真
if [ -z $string ] 如果 string 为空则为真
if [ $sting ] 如果string 非空,返回0 (和-n类似)
if [ STRING1 == STRING2 ] 如果2个字符串相同则为真。
if [ STRING1 != STRING2 ] 如果字符串不相等则为真。
if [ STRING1 < STRING2 ] 如果“STRING1”在当前语言环境中按字典顺序排序“STRING2”之后则为真。
if [ STRING1 > STRING2 ] 如果“STRING1”在当前语言环境中按字典顺序排序“STRING2”之前则为真。

  1. #!/bin/sh
  2.  
  3. a="Liuyifei"
  4. b="Yangying"
  5.  
  6. if [ $a > $b ]
  7. then
  8. echo "a > b"
  9. else
  10. echo "a < b"
  11. fi
  12.  
  13. # 打印:a > b

(3)文件表达式

①判断文件(夹)是否存在
[ -a FILE ] 如果 FILE 存在则为真。
[ -d FILE ] 如果 FILE 存在且是一个目录则为真。
[ -e FILE ] 如果 FILE 存在则为真。
[ -g FILE ] 如果 FILE 存在且已经设置了SGID则为真。
[ -k FILE ] 如果 FILE 存在且已经设置了粘制位则为真。
[ -u FILE ] 如果 FILE 存在且设置了SUID (set user ID)则为真。
[ -O FILE ] 如果 FILE 存在且属有效用户ID则为真。
[ -G FILE ] 如果 FILE 存在且属有效用户组则为真。
[ -s FILE ] 如果 FILE 存在且大小不为0则为真。

②文件权限检查
[ -w FILE ] 如果 FILE 如果 FILE 存在且是可写的则为真。
[ -x FILE ] 如果 FILE 存在且是可执行的则为真。
[ -r FILE ] 如果 FILE 存在且是可读的则为真。
[ -s FILE ] 如果 FILE 存在且是非空白文件则为真。

③判断两个文件的新旧
[ FILE1 -nt FILE2 ] 如果 FILE1 比 FILE2 新,或者 FILE1 存在且 FILE2 不存在则为真。
[ FILE1 -ot FILE2 ] 如果 FILE1 比 FILE2 旧,或者 FILE2 存在且 FILE1 不存在则为真。

②判断文件是否为特殊文件
[ -f FILE ] 如果 FILE 存在且是一个普通文件则为真。
[ -b FILE ] 如果 FILE 存在且是一个块设备文件则为真。
[ -c FILE ] 如果 FILE 存在且是一个字符设备文件则为真。
[ -S FILE ] 如果 FILE 存在且是一个套接字文件则为真。
[ -p FILE ] 如果 FILE 存在且是一个名管道则为真。
[ -L FILE ] 如果 FILE 存在且是一个符号连接则为真。
[ -h FILE ] 如果 FILE 存在且是一个符号连接则为真。

③其它
[ -t FD ] 如果文件描述符 FD 打开且指向一个终端则为真。
[ -N FILE ] 如果 FILE 存在且已经被修改则为真。
[ FILE1 -ef FILE2 ] 如果 FILE1 和 FILE2 指向相同的设备和节点号则为真,主要判断两个文件是否均指向同一个inode,就是判断是否为同一个文件,可用于判断硬连接。

(4) 多重判断条件(test -r file -a -w file)

[ -r FILE1 -a -w FILE1] 如果 FILE1 可读且可写则为真,-a表示且。
[ -r FILE1 -o -w FILE1] 如果 FILE1 可读或可写则为真,-o表示或。
[ -! -x FILE1] 如果 FILE1 不具有可执行权限则为真,-!表示取反。

(5)变量与值的判断
if [ "$VAR" = "y" -o "$VAR" = "Y" ] 如果变量 VAR 的的值是"y"或"Y"则为真。

(6)运算符的使用
① "==", " = ", "!="运算符

  1. #!/bin/bash
  2.  
  3. a=
  4. b=
  5.  
  6. if [ $a == $b ] #或if [ $a = $b ]
  7. then
  8. echo "a=b"
  9. fi
  10. if [ $a != $b ]
  11. then
  12. echo "a!=b"
  13. else
  14. : # 表示什么也不做
  15. fi

4.使用sh执行和source执行脚本的区别

(1)sh script.sh、./script.sh、bash script.sh 方式执行脚本:
sh script.sh、./script.sh、bash script.sh 方式执行脚本是等效的,会在当前shell进程下生成一个子shell进程,在子shell中执行script.sh脚本。
脚本执行完毕,退出子shell,回到当前shell。

(2)source script.sh 和 . script.sh 方式执行脚本:
source script.sh 和 . script.sh 方式执行脚本是等效的,会在当前shell上下文中执行脚本,不会生成新的进程。脚本执行完毕,回到当前shell。
就相当于在命令行中逐条执行script.sh中的指令。

(3)exec方式
使用exec command方式,会用command进程替换当前shell进程,并且保持PID不变。执行完毕,直接退出,不回到之前的shell环境。

测试Demo1: 对比sh和source执行下面脚本打印进程号,可以使用htop工具查看进程树。
#!/bin/sh
while [ 1 = 1 ]; do
  echo $$
  sleep 1
done

前两种方式对环境变量的获取
# name = zhangshan
# $ cat test.sh
#!/bin/sh
echo $name
若是使用source执行,变量name对脚本test.sh可见,因为在同一个进程中执行的,若是使用sh test.sh执行,则变量name对脚本test.sh不可见,
因为不在同一个进程中。在一个脚本中执行另一个脚本也是类似情况。

5.shell中对/dev/null 和 /dev/zero的使用

  ①/dev/null : /dev/null,称空设备,是一个特殊的设备文件,它丢弃一切写入其中的数据(但报告写入操作成功),读取它则会立即得到一个EOF。Unix行话中,/dev/null 被称为位桶(bit bucket)或者黑洞(black hole)。空设备通常被用于丢弃不需要的输出流,或作为用于输入流的空文件。这些操作通常由重定向完成。
   # cat /dev/null > /var/log/messages 清除文件的内容而不删除文件本身
   # : > /var/log/messages 有同样的效果,但不会产生新的进程。(内建的)
   # ln -s /dev/null test.c 往test.c中写任何内容都不会得到保存

  ②/dev/zero : /dev/zero 是一个特殊的文件,当你读它的时候,它会提供无限的空字符(NULL, ASCII NUL, 0x00)。其中的一个典型用法是用它提供的字符流来覆盖信息,另一个常见用法是产生一个特定大小的空白文件。

6.使用 echo $? 查看上条命令的退出码:0为命令正常执行,1-255为有出错。
  # dd if=/dev/zero of=/dev/sdb bs=4M 来给整个U盘清零。

7.echo $$ 打印运行当前脚本的进程的PID

8.要求以root身份来运行

  1. ROOT_UID=     # Root 用户的 $UID 是 .
  2. E_WRONG_USER=     # 不是 root?
  3. if [ "$UID" -ne "$ROOT_UID" ]
  4. then
  5.   echo; echo "You must be root to run this script."; echo
  6.   exit $E_WRONG_USER
  7. fi
  8.  
  9. 或者:
  10.  
  11. E_NON_ROOT_USER= # 必须用root来运行.
  12.  
  13. ROOTUSER_NAME=root
  14. username=`id -nu`
  15. if [ "$username" != "$ROOTUSER_NAME" ]
  16. then
  17.   echo "Must be root to run ""`basename $0`""."
  18.   exit $E_NON_ROOT_USER
  19. fi

9.单引号、双引号和反引号的区别

(1)单引号 ( '' )

当shell碰到第一个单引号时,它忽略掉其后直到右引号的所有特殊字符

(2)双引号 ( " " )
双引号作用与单引号类似,区别是它没有那么严格。单引号告诉shell忽略所有特殊字符,而双引号只要求忽略大多数特殊字符,
具体说,括在双引号中的三种特殊字符不被忽略:$,\,` ,即双引号会解释字符串的特别意思,而单引号直接使用字符串.如果使用
双引号将字符串赋给变量并反馈它,实际上与直接反馈变量并无差别。
如果要查询包含空格的字符串,经常会用到双引号。
# x=*
# echo $x
hello.sh menus.sh misc.sh phonebook tshift.sh
# echo '$x'
$x
# echo "$x"
*
这个例子可以看出无引号、单引号和双引号之间的区别。
在最后一种情况中,双引号告诉shell在引号内照样进行变量名替换,所以shell把$x替换为*,因为双引号中不做文件名替换,所以
就把*作为要显示的值传递给echo。
对于第一种情况需要进一步说明,shell在给变量赋值时不进行文件名替换(这从第三种情况中也能看出来),各步骤发生的精确次序如下:
shell扫描命令行,把x的值设为星号*;
shell再次扫描命令行,碰到星号*,把它替换成当前目录下的文件清单;
shell启动执行echo命令,把文件清单作为参数传递给echo.
这个赋值的先后次序非常重要:shell先作变量替换,然后作文件名替换,最后把这行处理为参数

(3)反引号(``)
命令替换是指shell能够将一个命令的标准输出插在一个命令行中任何位置。
shell中有两种方法作命令替换:把shell命令用反引号或者$(...)结构括起来,其中,$(...)格式受到POSIX标准支持,也利于嵌套。
# echo The date and time is `date`
The date and time is 三 6月 15 06:10:35 CST 2005
# echo Your current working directory is $(pwd)
Your current working directory is /home/howard/script

10.反斜杠 backslash-escaped( \ )
反斜杠一般用作转义字符,或称逃脱字符,linux如果echo要让转义字符发生作用,就要使用-e选项,且转义字符要使用双引号
echo -e "\n"

反斜杠的另一种作用,就是当反斜杠用于一行的最后一个字符时,shell把行尾的反斜杠作为续行,这种结构在分几行输入长命令时经常使用。

总结:
单引号:把里面的所有内容当作字符串
双引号:把除了$,\,` ,这三个字符以外的字符当作字符串,值进行变量字符串值替换,不进行变量含义替换
反引号:将一个命令的标准输出插在一个命令行中任何位置

11.shell中的export命令

功能说明:设置或显示环境变量。
语  法:export [-fnp][变量名称]=[变量设置值]
参  数:
 -f  代表[变量名称]中为函数名称。
 -n  删除指定的变量。变量实际上并未删除,只是不会输出到后续指令的执行环境中。
 -p  列出所有的shell赋予程序的环境变量
注意:
1、执行脚本时是在一个子shell环境运行的,脚本执行完后该子shell自动退出;
2、一个shell中的系统环境变量才会被复制到子shell中(用export定义的变量);
3、一个shell中的系统环境变量只对该shell或者它的子shell有效,该shell结束时变量消失(并不能返回到父shell中)。
4、不用export定义的变量只对该shell有效,对子shell也是无效的。

补充说明:
1.在shell中执行程序时,shell会提供一组环境变量。export可新增,修改或删除环境变量,供后续执行的程序使用。export的效力仅及于该此登陆操作。
2.export把自己的参数创建为一个环境变量,而这个环境变量可以被当前程序调用的其他脚本和程序看见,被导出变量构成从该shell衍生的任何子进程的环境变量

3. export 也是 bash 的一个内置命令。它主要是用来将父 shell 里的变量导出供子 shell 使用。它有如下特征:
(1) 用 export 导出的变量放在“导出变量列表”中,它可以被子 shell (子 shell 的子 shell 也是如此)拷贝并使用。
(2) 被 export 出来的变量虽然可以被子 shell 使用,但它也只是一个拷贝,而不会影响到父 shell 中的值以及其它子 shell 中的值。

但反过来,父shell再次更改此变量时,子 shell 再去读时,读到的是新值,而不是原来的值。

若子shell想要影响父shell,可以通过有名管道进行通信,类似进程间通信。

12.shell中的语句

(1) for语句

  1. #!/bin/sh
  2.  
  3. for file in $(ls /home/sfl/mytest/shell_test |grep sh)
  4. do
  5. echo $file
  6. done
  7.  
  8. for i in #输出10次
  9. do
  10. echo $i
  11. done
  12.  
  13. for i in "0 1 2 3 4 5 6 7 8 9" #只循环1次,“”中的是一个变量
  14. do
  15. echo $i
  16. done

(2) until语句

  1. END_CONDITION=end
  2.  
  3. until [ "$var1" = "$END_CONDITION" ]
  4. do
  5. echo "Input variable #1 "
  6. echo "($END_CONDITION to exit)"
  7. read var1
  8. echo "variable #1 = $var1"
  9. echo
  10. done
  11.  
  12. exit

(3) if语句

  1. #!/bin/bash
  2.  
  3. echo "Input a number #1 "
  4. read num #从命令行中获取一个参数给num
  5. echo "variable #1 = $num"
  6. if [ $num -lt ]
  7. then
  8. echo "you are not pass"
  9. elif [ $num -lt ] && [ $num -ge ] #多个条件的判断
  10. then
  11. echo "pass"
  12. elif [[ $num -lt && $num -ge ]] #如果放在一起,要注意是双方括号,不要写成[ $num -lt && $num -ge ]
  13. then
  14. echo "good"
  15. elif (( $num <= )) && (( $num >= )) #对于有语言基础的人来说,这种写法让人觉得很舒服,不要忘了是双小括号
  16. then
  17. echo "very good"
  18. else
  19. echo "num is wrong"
  20. fi #if要有结束标签的,根XML很像,不闭合,就报错
  21. exit

(4) case语句

  1. #!/bin/sh
  2.  
  3. #useage:./shell_case.sh start/stop/restart
  4.  
  5. case $ in
  6. start)
  7. echo "start ok"
  8. ;; #注意一点,要注意是双分号
  9. stop)
  10. echo "stop ok"
  11. ;;
  12. restart)
  13. echo "restart ok"
  14. ;;
  15. *)
  16. echo "no param"
  17. ;;
  18. esac #注意闭合标签
  19.  
  20. exit

(5) while语句

  1. #!/system/bin/sh
  2. i=
  3. while true
  4. do
  5. let i++
  6. echo "============= i=$i ===============" >> tmp.txt
  7. sleep 0.1
  8. done

# nohup /system/bin/sh while.sh & //使用nohup,拔掉adb线也可以运行
[1] 7047
杀掉:
fg
Ctrl+C

  1. #!/system/bin/sh
  2. i=
  3. while true
  4. do
  5. let i++
  6. echo "============= i=$i ===============" > tmp.txt #数据条数是一直递增的!!
  7. sleep 0.1
  8. done
  9.  
  10. #-----------------------------------------------------------------
  11.  
  12. #!/system/bin/sh
  13. i=
  14. while true
  15. do
  16. let i++
  17. echo "============= i=$i ==============="
  18. sleep 0.1
  19. done > 1tmp.txt #数据条数也是一直递增的

14.shell中的函数

(1) shell中函数定义

  1. function_name ()
  2. {
  3. ...
  4. }
  5. 或者:
  6. function function_name()
  7. {
  8. ...
  9. }

(2) 函数调用

  1. function_name parm1 parm2

(3) 函数的返回值

(1)return来返回某个0-255之间的整数值(在Shell中,return语句只能返回某个0-255之间的整数值)。
(2)在函数中将要返回的数据写入到标准输出(stout),通常这个操作是使用echo语句来完成的,然后在调用程序中将函数的执行结果赋值给一个变量。

  1. #! /bin/bash
  2.  
  3. function sum()
  4. {
  5. ret=$(( $ + $ ))
  6. return $ret
  7. }
  8.  
  9. sum #若是sum , 执行结果就是1,回滚了。
  10.  
  11. echo $?
  1. #! /bin/bash
  2.  
  3. function length()
  4. {
  5. str=$
  6. result=
  7. if [ "$str" != "" ] ; then
  8. result=${#str}
  9. fi
  10. echo "$result"
  11. }
  12.  
  13. len=$(length "abc123")
  14.  
  15. echo "The string's length is $len " #执行结果:The string's length is 6

注意:“$@”表示向一个函数传参的列表,eg:

  1. #! /bin/bash
  2.  
  3. length()
  4. {
  5. echo "$@"
  6. }
  7.  
  8. length aaaaaaa bbbbbb cccccc dddd mmmm ddd nnnn
  9.  
  10. # $ ./return.sh
  11. # aaaaaaa bbbbbb cccccc dddd mmmm ddd nnnn

15.算数运算符
  原生bash不支持简单的数学运算,但是可以通过其他的命令实现,例如awk和expr,expr最常用expr是一款表达式计算工具,使用它能完成表达式的求值操作。表达式和运算符之间要有空格,例如2+2是不对的,必须写成2 + 2,完整的表达式要被反引号括住。

四则运算符实例:

  1. #!/bin/bash
  2.  
  3. a=
  4. b=
  5.  
  6. val=`expr $a + $b`
  7. echo "a+b:$val"
  8.  
  9. val=`expr $a - $b`
  10. echo "a-b:$val"
  11.  
  12. val=`expr $a \* $b`
  13. echo "a*b :$val"
  14.  
  15. val=`expr $b / $a`
  16. echo "b / a:$val"
  17.  
  18. val=`expr $b % $a`
  19. echo "b % a:$val"
  20.  
  21. if [ $a == $b ]
  22. then
  23. echo "a=b"
  24. fi
  25. if [ $a != $b ]
  26. then
  27. echo "a!=b"
  28. fi
  29.  
  30. 执行结果:
  31. # ./test.sh
  32. a+b:
  33. a-b:-
  34. a*b :
  35. b / a:
  36. b % a:
  37. a!=b

关系运算符使用:

  1. #!/bin/bash
  2. a=
  3. b=
  4.  
  5. if [ $a != $b ]
  6. then
  7. echo "$a !=$b:a != b"
  8. else
  9. echo "$a !=$b:a = b"
  10. fi
  11.  
  12. if [ $a -lt -a $b -gt ]
  13. then
  14. echo "$a 小于 100 且 $b 大于 15 : 返回 true"
  15. else
  16. echo "$a 小于 100 且 $b 大于 15 : 返回 false"
  17. fi
  18.  
  19. if [ $a -lt -o $b -gt ]
  20. then
  21. echo "$a 小于 100 或 $b 大于 100 : 返回 true"
  22. else
  23. echo "$a 小于 100 或 $b 大于 100 : 返回 false"
  24. fi
  25.  
  26. if [ $a -lt -o $b -gt ]
  27. then
  28. echo "$a 小于 5 或 $b 大于 100 : 返回 true"
  29. else
  30. echo "$a 小于 5 或 $b 大于 100 : 返回 false"
  31. fi
  32.  
  33. 试验结果
  34. # ./test.sh
  35. !=:a != b
  36. 小于 大于 : 返回 true
  37. 小于 大于 : 返回 true
  38. 小于 大于 : 返回 false
  1. j=
  2. j=`expr $j + `
  3. echo $j ==>output:
  1. #! /bin/bash
  2. #
  3. read -p '请输入数:' a //输入
  4. read -p '请输入数:' b
  5. echo '$a+$b=' $(( a + b )) //输出
  6. echo '$a-$b=' $(( a - b ))
  7. echo '$a*$b=' $(( a * b ))
  8. echo '$a/$b=' $(( a / b ))
  9. echo '$a%$b=' $(( a % b ))

16. shell中的注释

1. 单行注释使用“#”

2. 多行注释如下

  1. $ cat test.sh
  2. #!/bin/sh
  3.  
  4. :<<EOF
  5. echo "========= 1 ========="
  6. echo "========= 2 ========="
  7. echo "========= 3 ========="
  8. EOF
  9.  
  10. echo "========= 4 ========="
  11. $ ./test.sh
  12. ========= =========

17. 在一个脚本中 source的子shell脚本中可以使用父shell脚本中定义的变量,父shell中./直接执行的子shell脚本中是不可以访问父shell脚本中定义的变量的。

18. Shell脚本中利用##* %%* 进行变量处理

假设我们定义了一个变量为:file=/dir1/dir2/dir3/my.file.txt 可以用${ }分别替换得到不同的值:

  1. ${file#*/}:删掉第一个/ 及其左边的字符串:dir1/dir2/dir3/my.file.txt
  2. ${file##*/}:删掉最后一个/ 及其左边的字符串:my.file.txt
  3. ${file#*.}:删掉第一个. 及其左边的字符串:file.txt
  4. ${file##*.}:删掉最后一个. 及其左边的字符串:txt
  5. ${file%/*}:删掉最后一个 / 及其右边的字符串:/dir1/dir2/dir3
  6. ${file%%/*}:删掉第一个/ 及其右边的字符串:(空值)
  7. ${file%.*}:删掉最后一个 . 及其右边的字符串:/dir1/dir2/dir3/my.file
  8. ${file%%.*}:删掉第一个 . 及其右边的字符串:/dir1/dir2/dir3/my

例子:

  1. #!/bin/sh
  2.  
  3. val=/dir1/dir2/dir3/my.test.txt
  4.  
  5. echo ${val#*/} # dir1/dir2/dir3/my.test.txt
  6. echo ${val##*/} # my.test.txt
  7. echo ${val#*.} # test.txt
  8. echo ${val##*.} # txt
  9. echo ${val%/*} # /dir1/dir2/dir3
  10. echo ${val%%/*} #
  11. echo ${val%.*} # /dir1/dir2/dir3/my.test
  12. echo ${val%%.*} # /dir1/dir2/dir3/my

参考: https://www.jianshu.com/p/86111df650de

18. shell脚本中的全局变量与局部变量

(1) Shell脚本中定义的变量是global的,其作用域从被定义的地方开始,到shell结束或被显示删除的地方为止。
(2) Shell函数中定义的变量默认也是global的,其作用域从“函数被调用时执行变量定义的地方”开始,到shell结束或被显示删除处为止。若想在函数内部定义局部变量,使用local关键字修饰,此时其作用域局限于函数内。
(3) 如果同名,Shell函数定义的local变量会屏蔽脚本定义的global变量。

  1. #!/bin/bash
  2.  
  3. test_func1()
  4. {
  5. echo $v1
  6. v1=
  7. }
  8. v1=
  9. test_func1
  10. echo $v1
  11. #---------------------
  12.  
  13. test_func2()
  14. {
  15. v2=
  16. }
  17. test_func2
  18. echo $v2
  19. #---------------------
  20.  
  21. test_func3()
  22. {
  23. local v3=
  24. }
  25. test_func3
  26. echo $v3
  27. #---------------------
  28.  
  29. test_func4()
  30. {
  31. echo $v4
  32. local v4=
  33. echo $v4
  34. }
  35. v4=
  36. test_func4
  37. echo $v4
  38.  
  39. $ ./4local.sh

19.使用数组

  1. #!/bin/sh
  2.  
  3. #eas_small_big_toggle
  4. test_case=(
  5. ls
  6. lsusb
  7. )
  8.  
  9. echo > ./eas_test_pass.txt
  10. echo > ./eas_test_fail.txt
  11.  
  12. function loop_running()
  13. {
  14. for line in ${test_case[@]} #使用数组
  15. do
  16. echo "start test case: $line"
  17. count=
  18. pass_count=
  19. fail_count=
  20.  
  21. while [ $count -lt $ ]
  22. do
  23. $line > ./tmp.txt >& #执行命令
  24.  
  25. if [[ `cat ./tmp.txt | grep "passed" | tr -cd "[0-9]"`"" -eq "" ]]
  26. then
  27. let ++pass_count
  28. cat ./tmp.txt >> ./eas_test_pass.txt
  29. else
  30. let ++fail_count
  31. cat ./tmp.txt >> ./eas_test_fail.txt
  32. fi
  33.  
  34. let ++count
  35. sleep 0.2
  36. done
  37. #echo "\033[33m$line test passed: $pass_count, failed: $fail_count \033[0m"
  38. echo -e ""
  39. done
  40.  
  41. return
  42. }
  43.  
  44. loop_running $

二、shell脚本工具

1. dump sysfs文件状态

  1. #!/system/bin/sh
  2.  
  3. function read_dir(){
  4. path=$
  5. for file in `ls $path`
  6. do
  7. path_name=$path"/"$file
  8. if [ -h $path_name ]; then # ignore link
  9. return
  10. fi
  11.  
  12. if [ -d $path_name ]; then
  13. read_dir $path_name
  14. elif [ -r $path_name -a -f $path_name ]; then
  15. echo $path_name": "`cat $path_name`
  16. else
  17. echo "$path_name is none"
  18. fi
  19. done
  20. }
  21.  
  22. sleep # set according to scene
  23.  
  24. read_dir $

相关资料:

Linux C编程一站式学习: https://akaedu.github.io/book/ch33s03.html#id2884876

shell学习笔记汇总的更多相关文章

  1. NGUI学习笔记汇总

    NGUI学习笔记汇总,适用于NGUI2.x,NGUI3.x 一.NGUI的直接用法 1. Attach a Collider:表示为NGUI的某些物体添加碰撞器,如果界面是用NGUI做的,只能这样添加 ...

  2. SHELL学习笔记----IF条件判断,判断条件

    SHELL学习笔记----IF条件判断,判断条件 前言: 无论什么编程语言都离不开条件判断.SHELL也不例外.  if list then           do something here   ...

  3. shell学习笔记

    shell学习笔记 .查看/etc/shells,看看有几个可用的Shell . 曾经用过的命令存在.bash_history中,但是~/.bash_history记录的是前一次登录前记录的所有指令, ...

  4. [转帖][Bash Shell] Shell学习笔记

    [Bash Shell] Shell学习笔记 http://www.cnblogs.com/maybe2030/p/5022595.html  阅读目录 编译型语言 解释型语言 5.1 作为可执行程序 ...

  5. shell 学习笔记2-shell-test

    一.字符串测试表达式 前面一篇介绍:什么是shell,shell变量请参考: shell 学习笔记1-什么是shell,shell变量 1.字符串测试表达式参数 字符串需要用""引 ...

  6. 【笔记目录2】【jessetalk 】ASP.NET Core快速入门_学习笔记汇总

    当前标签: ASP.NET Core快速入门 共2页: 上一页 1 2  任务27:Middleware管道介绍 GASA 2019-02-12 20:07 阅读:15 评论:0 任务26:dotne ...

  7. SHELL学习笔记三

    SHELL学习笔记一 SHELL学习笔记二 SHELL学习笔记三 for 命令 读取列表中的复杂值 从变量读取列表 从命令读取值 更改字段分隔符 用通配符读取目录 which 使用多个测试命令 unt ...

  8. 前端学习笔记汇总(之merge方法)

    学习笔记 关于Jquery的merge方法 话不多说,先上图 使用jquery时,其智能提示如上,大概意思就是合并first和second两个数组,得到的结果是first+(second去重后的结果) ...

  9. DeepLearning.ai学习笔记汇总

    第一章 神经网络与深度学习(Neural Network & Deeplearning) DeepLearning.ai学习笔记(一)神经网络和深度学习--Week3浅层神经网络 DeepLe ...

随机推荐

  1. Sasha and a Very Easy Test CodeForces - 1109E (数学,线段树)

    大意: 给定n元素序列, q个操作: (1)区间乘 (2)单点除(保证整除) (3)区间求和对m取模 要求回答所有操作(3)的结果 主要是除法难办, 假设单点除$x$, $x$中与$m$互素的素因子可 ...

  2. hihoCoder-1087 Hamiltonian Cycle (记忆化搜索)

    描述 Given a directed graph containing n vertice (numbered from 1 to n) and m edges. Can you tell us h ...

  3. dp入门求最大公共子序列

    #include "bits/stdc++.h" using namespace std; ],b[]; ][]; int main() { cin >> a > ...

  4. MVC ——设置启动 URL

    Visual Studio 会以一种有助的尝试,根据当前正在编辑的视图,让浏览器请求一个 URL.但这是一个不稳定的特性. 为了对浏览器的请求设置一个固定的 URL,可以从 Visual Studio ...

  5. SSH 反向代理

    SSH反向代理 被控制端没有NAT或者没有静态公网IP,把本端一台服务器映射到外网给远端SSH进来,建立SSH反向隧道. 先映射本端机器到外网  nat server 2222to22 protoco ...

  6. spring cloud 学习(一)初学SpringCloud

    初学SpringCloud 前言 在SpringBoot的坑还没填完的情况下,我又迫不及待地开新坑了.主要是寒假即将结束了,到时又得忙于各种各样的事情……留个坑给自己应该就会惦记着它,再慢慢地补上…… ...

  7. Jquery中bind(), live(), on(), delegate()四种注册事件的优缺点,建议使用on()

    jquery中注册的事件,注册事件很容易理解偏差,叫法不一样.我第一反应就是如何添加事件,使用onclick之类的,暂时不讨论js注册事件的方法. 也看到园内前辈写过相关的帖子,但不是很详细,我找到了 ...

  8. Android开发——1轻松战胜开发环境

    写在前头的话:鄙人乃2016年本科毕业的程序yuan一枚,大学阶段从未学过安卓,java也是一知半解,回想这一年半的开发生涯真的是相当悲壮.你要是问我喜欢开发吗,当然确定一定以及肯定地告诉你不喜欢啊! ...

  9. 关于send message 函数

    Windows是一个消息驱动模式的系统,SendMessage 是应用程序和应用程序之间进行消息传递的主要手段之一.由于 SendMessage 函数的参数选项过于繁多,因此很有必要作一个汇总,分门别 ...

  10. 安装sybase服务器并连接数据库

    一. 安装sybase服务器(根据安装指南安装) win32位的系统安装1550_winx86_32+补丁包eBF18157 win64位的系统安装ase157_winx64_安装包 如果不创建服务器 ...