优选主流主机商
任何主机均需规范使用

Shell脚本编程:提升日常工作效率的10个小技巧与实战案例

Shell 脚本在我们日常开发和学习都有举足轻重的地位,比如看一些开源项目,比如项目中的各式各样的脚本,对于促进生产力工具有很大帮助!

1、命令小技巧

1、-x命令进行跟踪调试执行

  1. #!/bin/sh
  2. num1=10
  3. num2=20
  4. if (($num1 <= $num2)); then
  5. echo num1 lesser equal num2
  6. else
  7. echo num1 greater num2
  8. fi

执行:

  1. note git:(master) sh -x /Users/fanhaodong/Desktop/project/test.sh
  2. + num1=10
  3. + num2=20
  4. + (( 10 <= 20 ))
  5. + echo num1 lesser equal num2
  6. num1 lesser equal num2

2、-c命令 (执行命令参数)

  1. note git:(master) sh -c << EOF “
  2. dquote> echo hello world
  3. dquote> echo hello world2
  4. dquote> “
  5. heredoc> EOF
  6. hello world
  7. hello world2

3、使用set变量

  1. #!/bin/sh
  2. # -v Print shell input lines as they are read.
  3. # -x Print commands and their arguments as they are executed.
  4. # -e Exit immediately if a command exits with a non-zero status.
  5. set -ex
  6. echo “hello world”
  7. exit 1

执行

  1. makefile git:(master) sh ./main.sh
  2. + echo ‘hello world’
  3. hello world
  4. + exit 1
  5. makefile git:(master) echo $?
  6. 1

帮助可以看:sh -c “help set”

2、语法小技巧

1、${}和$适用场景

1)$ 可能有语法歧义,所以一般使用${}

  1. #!/bin/sh
  2. s=”my name is s”
  3. echo 输出: $sa
  4. echo 输出: ${s}a
  5. #输出:
  6. #输出: my nameis sa

2、((cmd))

  • 可以替换[-le ] 命令
  1. num1=10
  2. num2=20
  3. if (($num1 <= $num2)); then
  4. echo num1 lesser equal num2
  5. fi

3、cat[>>|>][file]<

如果重定向的操作符是<<-,那么分界符(EOF)所在行的开头部分的制表符(Tab)都将被去除。这可以解决由于脚本中的自然缩进产生的制表符。

  1. test cat > glide.yaml << EOF
  2. heredoc> name: tom
  3. heredoc> age: 10
  4. heredoc> hobby:
  5. heredoc> – football
  6. heredoc> EOF
  7. test cat glide.yaml
  8. name: tom
  9. age: 10
  10. hobby:
  11. – football

4、 单引号,双引号,没有引号的区别

  1. #!/bin/sh
  2. name=”tom”
  3. f1(){
  4. echo “f1 hello world
  5. my nameis $name
  6. }
  7. f2(){
  8. echo ‘f2 hello world
  9. my nameis $name
  10. }
  11. f3(){
  12. echo f3 hello world
  13. my nameis $name
  14. }
  15. f1
  16. f2
  17. f3

输出

  1. makefile git:(master) sh ./main.sh
  2. f1 hello world
  3. my nameis tom
  4. f2 hello world
  5. my nameis $name
  6. f3 hello world
  7. ./main.sh: line 19: my: command not found

可以看到

  • 双引号会自动对变量赋值
  • 单引号不会对变量进行赋值等操作
  • 不加引号对于换行等功能无法实现!只能使用换行符
  1. f3(){
  2. echo f3 hello world \
  3. my nameis $name
  4. }

5、特殊变量

  • $0: 当前脚本的文件名
  • $n : 传递给脚本或函数的参数。n 是一个数字,表示第几个参数。例如,第一个参数是$1,第二个参数是$2。
  • $#: 传递给脚本或函数的参数个数。
  • $*: 传递给脚本或函数的所有参数。
  • $@: 传递给脚本或函数的所有参数(推荐使用这个),当使用”” 双引号引用是$*会变成字符串而不是数组
  • $?: 上个命令的退出状态,或函数的返回值。一般情况下,大部分命令执行成功后会返回 0,失败返回 1。
  • $$: 当前Shell进程ID。对于 Shell 脚本,就是这些脚本所在的进程ID。

6、[[]]和[]标准 以及基本语法规范

具体规范:

  1. #!/bin/sh
  2. name=””
  3. if [[ -z $name ]]; then
  4. echo “is zero”
  5. fi

执行后发现

7、/bin/sh 与 /bin/bash 的区别

/bin/sh 与 /bin/bash 的区别

3、获取命令结果$(cmd)

有两种写法,一种是$()这个并不是所有的shell都支持,但是比较直观, 另外一种是”“” (它可是适用更多的平台)

  1. #!/bin/sh
  2. echo `ls -a /Users/fanhaodong/note`
  3. echo $(ls -a /Users/fanhaodong/note)

输出:

  1. . .. .DS_Store 1714.jpg docker-rocketmq-cluster gridea-home hexo-home note pdf vuepress-starter
  2. . .. .DS_Store 1714.jpg docker-rocketmq-cluster gridea-home hexo-home note pdf vuepress-starter

4、输入输出重定向2>&1

使用

程序中经常有,标准输出,但是还有错误输出,因此需要合并到一个流中

其实Go的程序中正执行脚本的时候可以指定,标准输出和错误输出

  1. command := exec.Command(shell, “-c”, cmd)
  2. command.Stdout = os.Stdout
  3. command.Stderr = os.Stderr

使用的时候:

  • 默认为标准输出重定向,与 1> 相同
  • 2>&1 意思是把 标准错误输出 重定向到 标准输出.
  • &>file 意思是把标准输出和标准错误输出 都重定向到文件file中

例如:

  1. command >out.file 2>&1&

command >out.file是将command的标准输出重定向到out.file文件,即输出内容不打印到屏幕上,而是输出到out.file文件中。2>&1 是将标准出错重定向到标准输出,这里的标准输出已经重定向到了out.file文件,即将标准出错也输出到out.file文件中。最后一个&,是让该命令在后台执行。

5、If语句

if 其实就是test 命令

1、格式

1) 换行写

  1. if [ condition ]; then
  2. # body
  3. elif [ condition ]; then
  4. # body
  5. else
  6. # body
  7. fi

2)非换行写

  1. if [ -f “/Users/fanhaodong/note/note/Makefile1” ]; then echo 111 ; echo 222 ;elif [ -f “/Users/fanhaodong/note/note/README.md” ]; then echo 333 ; echo 4444 ; else echo 555 ; echo 666 ; fi

2、结果获取/判断

结果输出0 ,表示为真,可以通过$? 来获取结果

3、例如调试条件

  1. note git:(master) test “abc”!=”def”
  2. note git:(master) echo $?
  3. 0

4、测试文件是否存在

  • 如果你要判断一个文件是否存在,只需要-e 即可,输出0 表示文件存在 (不在判断类型的时候推荐使用这个)
  • 如果你要判断一个文件是否为文件夹,并且判断是否存在,只需要-d 即可
  • 如果你要判断一个文件是否为常规文件 ,并且判断是否存在,只需要-f 即可
  • -L filename 如果 filename为符号链接,则为真
  1. [root@019066c0cd63 ~]# ls -al
  2. lrwxrwxrwx 1 root root 5 Mar 1 09:49 c.txt -> a.txt
  3. [root@019066c0cd63 ~]# [ -L “./c.txt” ]
  4. [root@019066c0cd63 ~]# echo $?
  5. 0
  • -r filename 如果 filename可读,则为真
  • -w filename 如果 filename可写,则为真
  • -x filename 如果 filename可执行,则为真
  • -s filename 如果文件长度不为0,则为真
  • -h filename 如果文件是软链接,则为真
  1. note git:(master) [ -f “/Users/fanhaodong/note/note/Makefile” ]
  2. note git:(master) echo $?
  3. 0
  4. note git:(master) [ -f “/Users/fanhaodong/note/note/Makefile1” ]
  5. note git:(master) echo $?
  6. 1

5、字符串操作

字符串推荐加”” 进行定义

1) 判断字符串是否为空-z (zero)么

  1. #!/bin/sh
  2. str=””
  3. if [ -z “${str}” ]; then
  4. echo str is empty
  5. fi
  6. # str is empty

2)判断两个字符串是否相同

  1. #!/bin/sh
  2. str1=”str”
  3. str2=”str2″
  4. if [ “$str1” = “$str2” ]; then
  5. echo str1 is equal str2
  6. else
  7. echo str1 isnot equal str2
  8. fi
  9. # str1 isnot equal str2

4、测试一个命令是否存在command -v $#

  1. #!/bin/sh
  2. cmd=go
  3. if [ `command -v $cmd` ]; then
  4. echo $cmd command is exists
  5. else
  6. echo $cmd command not exists
  7. fi
  8. # go command is exists

5、获取字符串长度${#var}

  1. #!/bin/sh
  2. str=”hello “
  3. str1=hello
  4. echo str 的长度是 ${#str}
  5. echo str1 的长度是 ${#str1}
  6. #str 的长度是 8
  7. #str1 的长度是 5

6、数字比较

  • -eq 等于
  • -ne 不等于
  • -gt 大于
  • -ge 大于等于
  • -lt 小于
  • -le 小于等于
  1. #!/bin/sh
  2. num1=10
  3. num2=20
  4. if (($num1 <= $num2)); then
  5. echo num1 lesser equal num2
  6. fi
  7. if [ $num1 -le $num2 ]; then
  8. echo num1 lesser equal num2
  9. fi
  10. # num1 lesser equal num2
  11. # num1 lesser equal num2

7、shell脚本中if判断’-a’ – ‘-z’含义

6、for循环

1、forin; do;;done

  1. #!/bin/bash
  2. for item in {1..5}; do echo “$item”; done
  3. [Running] /bin/bash “/Users/fanhaodong/note/note/Linux/shell/file.sh”
  4. 1
  5. 2
  6. 3
  7. 4
  8. 5

2、for((x=0; x<10; x++));do;; done

  1. for((x=0; x<10; x++));do echo “$x” ;done

7、awk

1、例子

demo

  1. [root@19096dee708b data]# cat demo.txt
  2. 11 22
  3. 111
  4. 22 33

脚本

  1. [root@19096dee708b data]# awk -F ‘:”BEGIN {print “start”} /:/ {printf “do1 $1=%s $2=%s\n”,$1,$2} {print “do2 ..”} END {print “e nd”}’ demo.txt
  2. start
  3. do1 $1=11 $2=22
  4. do2 ..
  5. do2 ..
  6. do1 $1=22 $2=33
  7. do2 ..
  8. e nd

2、格式

  1. awk -arg1 x1 -arg2 x2 ‘BEGIN {开始执行脚本} 条件 {过程1} {过程2} END{循环体执行完后最后执行}’
  1. 其中条件执行正则表达式、判断等
  2. 还支持一些内置函数 , 一些内置变量!
  3. 过程中支持if函数

8、sed

首先gun的sed函数和mac的set是有些不同的!具体看:

  • https://superuser@com/questions/307165/newlines-in-sed-on-mac-os-x
未经允许不得转载:搬瓦工中文网 » Shell脚本编程:提升日常工作效率的10个小技巧与实战案例