# 跑通第一个在`Ubuntu`上的`Shell Script` ## 什么是Shell Script? 通常以`.sh`结尾,该文件中包含了`UNIX`的命令。在`Ubuntu`中,默认的`Shell`是`Bash`。 可以在文件的开头注明是否以`shell script`运行。 ``` #!/bin/bash 头一行也被称为shebang, 用来告诉Ubuntu kernel使用哪个解释器,这里表示使用Bash #!/bin/sh 表示使用Dash解释器 ``` 什么是`Bash`? 默认的命令行解释器。 ``` 查看Bash: echo $SHELL ``` 什么是`Shell`? 用来执行命令的宏处理器`macro processor`。当打`Linux`控制台,默认就包含`Shell`。输入一些简单的命令,`Shell`默认借助`Bash`解释器,解释并执行命令。 ``` date cal pwd ls ``` 什么是`Script`或`Scripting`? 其实可以理解成批处理命令。用来执行多个命令。 ## 第一个批处理命令脚本 ``` 创建批处理文件:nano task.sh #!/bin/bash date cal pwd ls 给予该文件权限:sudo chmod +x task.sh 执行批处理:./task.sh ``` # 文件名和权限 ``` 查看文件类型:file task.sh 复制脚本文件:cp task.sh 0_xyz 查看复制文件:file 0_xyz 查看复制文件内容:nano 0_xyz ``` # 脚本执行方式 ``` 创建脚本文件:echo date > date.sh 打印脚本文件内容:cat date.sh 尝试执行脚本文件:./date.sh(执行不成功) 尝试另外一种执行脚本文件的方式:bash date.sh(执行成功) 编辑脚本文件:nano date.sh #!/bin/bash date 更改脚本文件的权限:chmod +x date.sh 使用第一种方式执行脚本文件:./date.sh ``` # 相对位置和绝对位置 ``` 来到根目录:cd / 查看根目录:pwd 进入home目录:cd home 返回上一级: cd .. 查看根目录内容:ls 目录结构为: home/lenovo etc 进入etc目录:cd etc 从etc目录进入home/lenovo目录:cd ../home/lenovo 返回上一个目录:cd - 再返回上一个目录:cd - 后退两级返回根目录:cd ../../ 返回linux开机默认目录:cd ``` # `Hello World`脚本 ``` 创建并打开文件:nano hello-world.sh #!/bin/bash echo "Hello World" 赋予权限:chmod +x hello-world.sh 执行脚本:bash hello-world.sh ``` # 查看帮助文件 ``` man ls q ls --help ls -l ls -l hello-world.sh ``` # 备份脚本 ``` 创建tmp目录:mkdir tmp 把home/lenovo目录备份:tar -czf /tmp/myhome_directory.tar.gz /home/lenovo 列出刚刚创建的备份文件:ls -l /tmp/myhome_directory.tar.gz 删除备份文件:rm /tmp/myhome_directory.tar.gz 使用which bash创建批处理文件:which bash > back.sh 在back.sh文件中输入另外一行内容:echo 'tar -czf /tmp/myhome_directory.tar.gz /home/lenovo/' >> backup.sh 打开并编辑:nano backup.sh 赋予权限:chmod +x bakcup.sh 运行:bash backup.sh ``` # 变量 ``` 创建脚本文件:nano welcome.sh #!/bin/bash greeting="Welcome" user=$(whoami) day=$(date +%A) echo "$greeting back $user! Today is $day, which is the best day of the entire week!" echo "Your Bash shell version is: $BASH_VERSION. Enjoy!" 赋予权限:chmod +x welcome.sh 执行:bash welcome.sh ``` 备份文件使用变量: ``` #!/bin/bash # This bash script is used to backup a user's home directory to /tmp/. user=$(whoami) input=/home/$user output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz tar -czf $output $input echo "Backup of $input completed! Details about the output backup file:" ls -l $output 运行:bash backup.sh ``` # 输入、输出、错误导向 ``` 标准错误输出stderr: ls -l foobar 创建文件:touch foobar 标准输出stdout:ls -l foobar 把信息输出到一个文件:ls barfoo > stdout.txt 把错误信息输出到一个文件:ls barfoo 2> stdout.txt 把信息和错误信息输出到一个文件:ls barfoo &> stdoutandstderr.txt 控制台打印文件内容:cat stdout ``` 使用错误导向忽略错误提示。/dev/null可以看作是一个保存错误信息的容器、 ``` nano backup.sh #!/bin/bash # This bash script is used to backup a user's home directory to /tmp/. user=$(whoami) input=/home/$user output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz tar -czf $output $input 2> /dev/null echo "Backup of $input completed! Details about the output backup file:" ls -l $output 执行脚本:bash backup.sh ``` 输入文件,从一个文件中获取信息。 ``` 在控制台打开并编辑内容:cat > file1.txt 按ctrl+d完成编辑 从file1.txt中读取文件内容:cat < file1.txt ``` # 功能 ``` 创建脚本:nano function.sh #!/bin/bash function user_details { echo "User Name: $(whoami)" echo "Home Directory: $HOME" } user_details 赋予权限:chmod +x function.sh 执行脚本:bash function.sh ``` 更改备份脚本 ``` #!/bin/bash # This bash script is used to backup a user's home directory to /tmp/. user=$(whoami) input=/home/$user output=/tmp/${user}_home_$(date +%Y-%m-%d_%H%M%S).tar.gz # The function total_files reports a total number of files for a given directory. function total_files { find $1 -type f | wc -l } # The function total_directories reports a total number of directories # for a given directory. function total_directories { find $1 -type d | wc -l } tar -czf $output $input 2> /dev/null echo -n "Files to be included:" total_files $input echo -n "Directories to be included:" total_directories $input echo "Backup of $input completed!" echo "Details about the output backup file:" ls -l $output ``` # 数字和字符串比较 | 描述 | 数字比较 | 字符串比较 | | -------- | -------- | ---------- | | 小于 | -lt | < | | 大于 | -gt | > | | 等于 | -eq | = | | 不等于 | -nq | != | | 小于等于 | -le | N/A | | 大于等于 | -ge | N/A | 比较数字 ``` a=1 b=2 [ $a -lt $b ] echo $? ``` 比较字符串 ``` [ "apples" = "oranges" ] echo $? ``` 放在脚本中比较 ``` nano comparison.sh #!/bin/bash string_a="UNIX" string_b="GNU" echo "Are $string_a and $string_b strings equal?" [ $string_a = $string_b ] echo $? num_a=100 num_b=100 echo "Is $num_a equal to $num_b ?" [ $num_a -eq $num_b ] echo $? 赋予权限:chmod +x comparison.sh 执行脚本:bash comparison.sh ``` # 条件语句 `if/then/else`语句 ``` 创建脚本:nano if_else.sh #!/bin/bash num_a=100 num_b=200 if [ $num_a -lt $num_b ]; then echo "$num_a is less than $num_b!" fi 赋予权限:chmod +x if_else.sh 执行脚本:bash if_else.sh 更改脚本: #!/bin/bash num_a=400 num_b=200 if [ $num_a -lt $num_b ]; then echo "$num_a is less than $num_b!" else echo "$num_a is greater than $num_b!" fi 执行脚本:bash less_than.sh ``` # 占位符参数 ``` 创建脚本文件:nano param.sh #!/bin/bash echo $1 $2 $4 echo $# echo $* 赋予权限:chmod +x param.sh 执行脚本:bash param.sh hello bash scripting world ``` # 循环 `for`循环 ``` 创建文件:nano items.txt hello hi world 在控制台打印文件内容:cat items.txt 创建脚本文件:nano for.sh #!/bin/bash for i in $( cat items.txt ); do echo -n $i | wc -c; done 赋予权限:chmod +x for.sh 执行脚本:bash for.sh ``` `while`循环 ``` 创建脚本:nano while.sh #!/bin/bash counter=0 while [ $counter -lt 3 ]; do let counter+=1; echo $counter done; 赋予权限:chmod +x while.sh 执行脚本:bash while.sh ``` `until`循环 ``` 创建脚本文件:nano until.sh #!/bin/bash counter=6 until [ $counter -lt 3 ]; do let counter-=1 echo $counter done 赋予权限:chmod +x until.sh 运行脚本:bash until.sh ``` # 算术 ``` a=$(( 12 + 5 )) echo a expr 2 + 2 let a=2+2 echo $a echo '8.5 / 2.3' | bc ```