shell脚本
shell脚本基础
变量
什么是变量?
变量即可以变化的量
变量名称注意事项
- 只能包含字母、数字、下划线,并且不能以数字开头
- 不应该跟系统中已有的环境变量重名,尽量不要全部使用大写,尽量不要用“_”下划线开头
- 最好做到见名知义
- 不能使用程序中的保留字,例如if、for等
变量类型
- 字符型
- 数值型
- - 整型
- - 浮点型
- 布尔型
变量操作
设置变量
引用变量
撤销变量
bash变量类型
- 环境变量
- 本地变量(局部变量)
- 位置变量
- 特殊变量(bash内置的,用来保存某些特殊数据的变量,也称系统变量)
写脚本的思路
- 先手动部署确立完成思路
- 分类和分析
- 通用性
- 写脚本
- - 开2个终端,一个写脚本,一个测试
- 测试
- 功能写完后立即测试(运行2遍以上确保通用性)
本地变量
VAR_NAME=VALUE //本地变量,作用域为当前shell进程。对当前shell外的其它shell进程,包括 当前shell的父shell、子shell进程均无效 local VAR_NAME=VALUE //局部变量,作用域为当前代码段,常用于函数
环境变量
export VAR_NAME=VALUE //作用域为当前shell进程及其子进程 [root@RedHat ~]# export a=1 [root@RedHat ~]# echo $a 1 //启用bash子进程 [root@RedHat ~]# bash [root@RedHat ~]# echo $a 1 //能看到子进程是能够继承父进程的变量使用的
位置变量
$1 $2 //用来引用脚本的参数 数字代表位置 shift [num] //使用完后退出,后面向前推进 [root@RedHat ~]# cat test.sh #!/bin/bash for i in $*;do echo $1 shift 2 done [root@RedHat ~]# ./test.sh 1 3 5 4 6 9 4 3 5 8 7 6 2 8 1 5 6 4 5 7 2 //脚本里的shift可以理解为向前推,数值为2 就是推两个参数,1推两个(1,3)下一个就是5,以此类推
特殊变量
$# //是传给脚本的参数个数 $0 //是脚本本身的名字 $! //是shell最后运行的后台Process的PID $@ //是传给脚本的所有参数的列表 $* //是以一个单字符串显示所有向脚本传递的参数,与位置变量不同,参数可超过9个 $$ //是脚本运行的当前进程ID号 $? //是显示上条命令的退出状态,0表示没有错误,其他表示有错误
bash内建环境变量
PATH //寻找命令路径 [root@RedHat ~]# echo $PATH /usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin sbinSHELL //查看当前shell [root@RedHat ~]# echo $SHELL /bin/bash UID //查看当前用户uid [root@RedHat ~]# echo $UID 0 HISTSIZE //查看可存储历史记录总大小 [root@RedHat ~]# echo $HISTSIZE 1000 HOME //查看当前用户家目录 [root@RedHat ~]# echo $HOME /root PWD //查看用户当前所在位置 [root@RedHat ~]# echo $PWD /root HISTFILE //查看当前用户历史记录文件储存位置 [root@RedHat ~]# echo $HISTFILE /root/.bash_history PS1 //定义系统提示符的变量 [root@RedHat ~]# echo $PS1 [\u@\h \W]\$
shell脚本编程注意事项
- 指定bash(#! /bin/bash)可能出现默认sh不是bash的情况
- 禁止将未执行的代码直接写入脚本
- 脚本中的命令一定要用绝对路径
- 注意local,bash中如果不在变量前添加local默认是全局变量,添加后只在当前代码段生效
- 使用sheelcheck检查语法
写一个脚本,传递整数给脚本,让脚本分别计算并显示这两个整数的和,差,积,商
[root@RedHat ~]# vim test.sh #!/bin/bash a=$1 b=$2 let c=$a+$b echo a+b="$c" let c=$a-$b echo a-b="$c" let c=$a*$b echo a*b="$c" let c=$a/$b echo a/b="$c"
[root@RedHat ~]# bash -x test.sh 7 3 + a=7 + b=3 + let c=7+3 + echo a+b=10 a+b=10 + let c=7-3 + echo a-b=4 a-b=4 + let 'c=7*3' + echo 'a*b=21' a*b=21 + let c=7/3 + echo a/b=2 a/b=2
写一个脚本,要求如下:
- 创建目录/tmp/scripts
- 切换至此目录中
- 复制/etc/pam.d目录至当前目录,并重命名为test
- 将当前目录的test及其里面的文件和子目录的属主改为redhat
- 将test及其子目录中的文件的其它用户的权限改为没有任何权限
[root@RedHat ~]# vim test1.sh eradd redhat >&/dev/null mkdir /tmp/scripts >&/dev/null if [[ $? -eq 0 ]]; then cd /tmp/scripts && cp -r /etc/pam.d /tmp/scripts/test /usr/bin/chown -R redhat.root /tmp/scripts/test /usr/bin/chmod -R o-rwx /tmp/scripts/ elif [[ $? -ne 0 ]]; then rm -rf /tmp/scripts/* && cp -r /etc/pam.d /tmp/scripts/test /usr/bin/chown -R redhat.root /tmp/scripts/test /usr/bin/chmod -R o-rwx /tmp/scripts fi
写一个脚本,要求如下:
- 显示当前系统日期和时间,而后创建目录/tmp/lstest
- 切换工作目录至/tmp/lstest
- 创建目录a1d,b56e,6test
- 创建空文件xy,x2y,732
- 列出当前目录下以a,x或者6开头的文件或目录
- 列出当前目录下以字母开头,后跟一个任意数字,而后跟任意长度字符的文件或目录
[root@RedHat ~]# vim test2.sh [ -e /tmp/lstest ] if [ $? -eq 0 ];then cd /tmp/lstest/ rm -rf /tmp/lstest/* mkdir a1d b56e 6test touch xy x2y 732 else mkdir /tmp/lstest cd /tmp/lstest mkdir a1d b56e 6test touch xy x2y 732 fi echo "______________________" ls | grep ^[ax6].* echo "以a,x或6开头的文件或目录" echo "______________________" ls | grep -o ^[a-z][0-9].* echo "以字母开头,后跟任意数,而后跟任意长度的目录和文件"