#shell 脚本编程
编程基础
程序L:指令+数据
程序编程风格:
过程式:以指令为中心,数据服务于指令
对象式:以数据为中心,指令服务于数据
编程逻辑处理方式
顺序执行
循环执行
选择执行
格式要求:首行shebang机制
#!/bin/bash
#!/usr/python
shell脚本的用途:
自动化常用命令
执行系统管理和故障排除
创建简单的应用程序
处理文本或文件
创建一个脚本
第一步
#!/bin/bash
#注释
第二部
授权执行权限
执行脚本的方法:
./hello.sh #当前路径执行脚本
bash hello.sh #指定解释器来执行脚本
/etc/hello.sh #绝对路径执行脚本
cat hello.sh | bash #这种方法可以将一个脚本文件放在一个所有机器访问到的机器上,不用下载,直接用自己的bash运行这个脚本
shell 脚本排错
bash -n #检查语法是否错误
bash -x #显示脚本执行的过程步骤
变量类型
局部变量:anme=1 工作范围在当前的shell使用
全局变量:export name 定义号局部变量以后用export将name 改为全局变量 ,全局变量可以给子进程使用,子进程不能将更改后的变量传回父变量
环境变量
变量声明、复制:
export name=VALUE
declare -x name=VALUE
变量引用:$name,${name}
显示所有环境变量:
env
printenv
export
declare -x
删除变量:
unset name
bash内建的环境变量:
$PATH #环境变量路径
$SHELL #查看当前shell
$USER #查看当前用户
$UID #当前用户号
$HOME #当前家目录
$PWD #当前路径
$SHLVL #查看当前shell 嵌套几次
$LANG #检查语言
$MAIL
$HOSTNAME #查看当前名称
$HISTSIZE #
只读变量
声明只读变量:
readonly name
declare -r name
查看只读变量
eadonly -p name
位置变量:
$1,$2,...:对应第一、第二、等参数、shift[n]换位置
$0:命令本身
$*:传递给脚本的所有参数,全部参数合为一个字符串
$@:传递给脚本的所有参数,每个参数为独立字符串
$#:传递给脚本的参数的个数
$@$*只在被双引号抱起来的时候才会有差异
set-- 清空所有位置变量参数
() # 开启一个子shell 不应响其他 例如:(cd /etc/hello ;rm -rf *) 结果是不会改变当前路径还执行了命令
{} # 不开启子shell 影响全局
默认情况不填写括号,就按照大括号来做
x=1;echo "pid=$$";(echo "subpid=$$";echo "subx=$x";x=2;echo "subx2=$x");echo x=$x
()小括号如上命令显示可以可以继承父shell 中的变量,也可更改此变量作用于此shell,但无法更改父shell变量
basename #取消路径,只显示文件名称
scp 远程文件推送 命令格式 scp [文件名] root@192.168.1.1:/root
创建用户初始口令 passwd --stdin magedu
useradd $user
echo "123456" | passwd --stdin $user
#以上命令是创建用户并为用户创建初始口令
shift 向前推进参数,总参数个数每次减去指定数量从左减
shift [0-9] 后面跟数字指定步长
econ $? 进程使用退出状态来报告前一条命令执行的成功或者失败、
#0为成功 ,1-255代表失败
let [变量]=[数值]+[数值] 表示算数运算,(数值也可以是变量)
变量=$[数值+数值] 与上述方法的结果相同,表达方式不同而已
test 条件判断语句
[ $a -gt $b ] = test $a -gt $b #此为两种方法,效果相同,下方还有扩展方式
str1=aaa
str2=bbb
test $str1 = $str2
# test 字符串比较,若相同则为真,若不同则为假
test -z $str1
#判断字符串是否为空
test 命令
-b<文件>:如果文件为一个块特殊文件,则为真;
-c<文件>:如果文件为一个字符特殊文件,则为真;
-d<文件>:如果文件为一个目录,则为真;
-e<文件>:如果文件存在,则为真;
-f<文件>:如果文件为一个普通文件,则为真;
-g<文件>:如果设置了文件的SGID位,则为真;
-G<文件>:如果文件存在且归该组所有,则为真;
-k<文件>:如果设置了文件的粘着位,则为真;
-O<文件>:如果文件存在并且归该用户所有,则为真;
-p<文件>:如果文件为一个命名管道,则为真;
-r<文件>:如果文件可读,则为真;
-s<文件>:如果文件的长度不为零,则为真;
-S<文件>:如果文件为一个套接字特殊文件,则为真;
-u<文件>:如果设置了文件的SUID位,则为真;
-w<文件>:如果文件可写,则为真;
-x<文件>:如果文件可执行,则为真。
-a 逻辑与
脚本的逻辑运算
&& 短路与,当前面为真则继续执行
|| 当前面为真,则不再执行后面,若前面为假继续执行后面
& 与
| 或
! 非
-eq 等于
-ne 不等于
-gt 大于
-ge 大于等于
-lt 小于
-le 小于等于
[[ ]]:条件判断语句
[[ 0 =~ [0-9]?] ]:条件判断语句 左侧条件满足右侧正则表达式用【【】】
[[ && || ]] 再双中括号中逻辑与 逻辑或用&&||表示
$i:i是个变量,$i代表读取变量i的值
=~:正则匹配,用来判断其左侧的参数是否符合右边copy的要求
[[ ! ]] 加叹号取反的意
^:以什么开头
^[0-9]:以数字开头
^[0-9]+:以数字开头,且数字有1到多个——加号表示1到多个
$:以什么结尾
^[0-9]+$:以1到多个数字开头,且结尾。——意即:只能有数字,不能有其他字符
&&:左边的zhidao条件满足,右边的命令才会执行。
echo 1:屏显1(在屏幕上显示,也叫打印)
#shell 脚本基础命令
1.命令历史记忆功能 上下健、!number (!123) 、!string(!his) 、!$ 执行最后一条命令
2. ctrl+r 通过关键字查找历史命令
ctrl+d logout 同等效应
ctrl+s 锁定屏幕输出
ctrl+q 解锁屏幕
ctrl+a 将光标移至命令行的第一位
ctrl+e 将光标移至命令行的最后一位
ctrl+k 命令行中以当前光标位置删除后面的命令
ctrl+y 撤销ctrl+k 删除的操作
ps aux 查看当前进程
screen的作用
会话恢复:
只要Screen本身没有终止,在其内部运行的会话都可以恢复。这一点对于远程登录的用户特别有用——即使网络连接中断,用户也不会失去对已经打开的命令行会话的控制。只要再次登录到主机上执行screen -r就可以恢复会话的运行。同样在暂时离开的时候,也可以执行分离命令detach,在保证里面的程序正常运行的情况下让Screen挂起(切换到后台)。这一点和图形界面下的VNC很相似。
多窗口:
在Screen环境下,所有的会话都独立的运行,并拥有各自的编号、输入、输出和窗口缓存。用户可以通过快捷键在不同的窗口下切换,并可以自由的重定向各个窗口的输入和输出。Screen实现了基本的文本操作,如复制粘贴等;还提供了类似滚动条的功能,可以查看窗口状况的历史记录。窗口还可以被分区和命名,还可以监视后台窗口的活动。 会话共享 Screen可以让一个或多个用户从不同终端多次登录一个会话,
并共享会话的所有特性(比如可以看到完全相同的输出)。它同时提供了窗口访问权限的机制,可以对窗口进行密码保护。
yum -y install screen # 安装screen 这个工具
screen -S [name] # 制定以后操作的任务名称
screen -list # 查看当前screen 列表中用哪些之前的操作任务以及编号
screen -r [编号] # 回到之前操作最后一步继续完成任务
jobs 查看当前后台任务
ctrl+z 将当前前台任务挂载到后台但是状态为停止状态
bg [任务编号] 将任务放到后台运行
fg [任务编号] 将任务恢复前台运行
/usr/bin/bash <<-chen # 将chen 与chen 之间的命令交给/usr/bin/bash 执行
echo "hello"
chen
/usr/bin/bash <<-chen >filename # 将chen 与chen 之间的命令交给/usr/bin/bash 执行,输出结果放入flename这个文件
echo "hello"
chen
ip a |tee test |grep inet # 管道输出截流,此意思为ip a 内容覆盖到test 文件中去,然后在屏幕输出结果抓取inet 不是文件中抓取
ip a |tee -a test |grep inet # 管道输出截流,此意思为ip a 内容**追加到test 文件中去,然后在屏幕输出结果抓取inet 不是文件中抓取
命令排序
;多条命令在一个命令行执行以分号分隔。
&& 逻辑与 ,前一命令执行成功后面才会执行
|| 逻辑或 , 迁移命令如果执行成功就不会执行后面命令
&> 将屏幕的输出结果重定向输出给某个文件
echo 带颜色
echo -e "\e[1;31mthis is [0m"
if 控制语句
if 条件 ;then
[做什么]
else
[做什么]
fi
read 赋值变量
read #从键盘上读入数据类似于python中的input
read -p "pleas input " #-p 提示
read -t 5 -P "pleas input "
read -n 2 只读取键盘输入的两个值
read -p "请输入个人信息" name age sed .... #在脚本中可以以空格分割为read定义多个变量
实例: #!/bin/bash
read -p "sss" name age seq
echo "$name,$age,$seq"
位置变量:
$1,$2,...:对应第一、第二、等参数、shift[n]换位置
$0:命令本身
$*:传递给脚本的所有参数,全部参数合为一个字符串
$@:传递给脚本的所有参数,每个参数为独立字符串
$#:传递给脚本的参数的个数
$@$*只在被双引号抱起来的时候才会有差异
set-- 清空所有位置变量参数
多个脚本引用在同一shell 中 的变量
以 . 的方式执行脚本让脚本中的变量在当前shell 中生效
变量
#变量可以以多种方式赋值
name="tian"
name='$aux'
name=`date`
name="$name is good" #将变量加字符串赋值给变量
变量的运算
$name=10
$name2=20
expr $name + $name2 # 注意中间的空格
echo $((name+name2)) # 此运算不能单独执行需要在前面加上echo 或是变量赋值
sum=$((name+nam2)) #$[] 此种运算*不用加转意
echo $[name+name2] # 此运算不能单独执行需要在前面加上echo 或是变量赋值
sum=$[name+name2] #$[] 此种运算*不用加转意
let num=$name+$name1;echo num #通过赋值变量进行运算
let i++ #用于脚本中while 循环中每次自增1
运算符号
+ - \* / % # 乘号前需要加\ 转意
while 使用方法
while true
do
done
for 遍历使用方法
for i in {1..5}
do
done
变量的内容删除和替换
#注意删除并不是删除原有变量的值,而是将提取的值再删除原有变量不变
删除:
name=www.baidu.com
echo ${name#www.} # 将变量内容从左向右删除掉www.
[root@192 ~]# echo ${name#www.}
baidu.com
echo ${name##www.} # ##贪婪模式,匹配最远符合的全部删除
[root@192 ~]# echo ${name##*.}
com
echo ${name%.*} #将变量内容从右向左删除点最近的.及以后的内容
此句中*为通配符任意字符任意长度
[root@192 ~]# echo ${name%.*}
www.baidu
echo ${name%%.*} # %% 贪婪模式,匹配最远符合的全部删除
[root@192 ~]# echo ${name%%.*}
www
索引:
echo ${name:0:5} #此意指从0位开始取,总数取5位字符
[root@192 ~]# echo ${name:0:5}
www.b
echo ${name:5} #写起始位置不写总数,就直接取到最后的值
[root@192 ~]# echo ${name:5}
aidu.com
替换:
echo ${name/www/chen} #将name变量中的www 换成chen
[root@192 ~]# echo ${name/www/5}
5.baidu.com
echo ${name/w/W} #将单个字符替换也是可以,默认只替换一个
[root@192 ~]# echo ${name/w/W}
Www.baidu.com
echo ${name//w/W} #原字符前加//就是贪婪模式匹配全部替换
[root@192 ~]# echo ${name//w/W}
WWW.baidu.com
扩展
#原有变量的值不会改变,只是单独提取一次值再进行操作替换
echo ${name-aaaa} # - 若变量有值则不会用aaaa替代原来的值空值也不会替代,若变量没定义过就会被aaaa 替代
echo ${name:-aaaa} # :- 若变量有值则不会将aaaa替代原来的值,若变量是控制或者是没定义过的值就会被aaaa替代,此命令可以用来测试一个变量值是否为空
echo ${name:+aaaa} # :+ 若变量有值则会将aaaa替代原来的值,若变量是控制或者是没定义过的值就不会被aaaa替代
echo ${name+aaaa} # + 若变量有值则会用aaaa替代原来的值空值也会替代,若变量没定义过就不会被aaaa 替代
echo ${name?aaaa} # + 若变量有值则不会用aaaa替代原来的值空值也不会替代,若变量没定义过就会报错 ####此命令可以用来测试一个变量是否定义过,原有变量值是多少
字符串比较
提示:使用双引号
[ "$name" -eq root]
ip r del defaulet via*.*.*.* # 临时删除网关
脚本并发
while :
do
{
user=ppp$i
}&
wait
done
echo “ok”
su [user] yu su [-user]
运维小技巧:
1. 随机更改字体颜色
COLOR=$[RANDOM%7+31];echo -e "\e[1;${COLOR}maa\e[0m"
随机生成密码
cat /dev/urandom | tr -dc A-Za-z0-9_ | head -c10 | sed 's/[ \r\b]//g'
2.#crontab 周期管理工具’ -
-e 编辑一个周期任务
-u 指定用户
-l 显示周期任务
* * * * *
分 时 日 月 周
实例: */1 * * * * date >> /root/bin/bash
解释: 每分钟执行一次data 命令 追加到后面文件中
实例: 30 19 * * * date >> /root/bin/bash
解释: 每天的19点30分执行data命令 追加到后面文件中
实例: 30 1,3,5 * * * date >> /root/bin/bash
解释: 每天的1点3点5点 执行data命令 追加到后面的文件中
实例: 10 1 * * 6,0 date >> /root/bin/bash
解释: 每周六周日1点10分执行data 追加到后面文件中
实例: 0,30 18-24 * * * date >> /root/bin/bash
解释: 每天的18点至24点 相隔30分钟执行data 追加到后面文件中
shell 技术笔记
最新推荐文章于 2022-03-02 10:26:35 发布