shell编程 - part02

434 阅读3分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第30天,点击查看活动详

编写shell脚本的规范和习惯

规范

  • 脚本存放目录需要统一
  • shell脚本的结尾一.sh结尾
  • 脚本开头要有解释器,比如#!/bin/bash或者#!/usr/bin/env/bash
  • 脚本开头加上时间 作者 联系邮箱 脚本作用等信息
# Author test 2022-08-29 version01 desc:xxx
  • 关键代码需要加上注释

好习惯

  • 成对的括号尽量一次性写出来,防止遗漏,比如{} [] '' ""
  • 括号的保留空格习惯,中括号两端需要留有空格,否则会报错。如果不知道{} () []到底哪种括号需要两端保留空格,可以都保留空格进行编写代码,这样可以有效避免因空格导致的各种错误。
  • 流程控制语句一次性书写完成再添加内容
  • 代码缩进提高可读性

变量

  • 从键盘读取值赋值给变量名:实现交互性脚本,参数来源于键盘,read命令
read -p "提示信息,随便写" 变量名  # 将键盘上输入的内容赋值给变量名
[root@VM-4-2-centos ~]# read -p "please input cmd >>> " cmd
please input cmd >>> test
[root@VM-4-2-centos ~]# echo $cmd
testread -t3 -p "提示信息" 变量名   # -t表示时间,3s不输入的话该命令无效
read -n2 -p "提示信息" 变量名   # -n表示最多接受2个字符,可以改成其他数字# 案例:输入用户名和密码判断是否正确
test.sh
​
user="shell"
passwd="123"
read -p "input your user> " user
read -p "input your pwd> " pwd
# []表示判断 -a表示and关系
[ $username == $user -a $passwd == $pwd] && echo "login" || echo "error"
  • 位置参数:$n
运行脚本文件时,脚本文件后面跟的参数会被传递到脚本文件中
以空格为分隔父,脚本文件属于第0个参数,以此类推
脚本 参数 其实就等价于 命令 参数
[root@VM-4-2-centos ~]# cat a.sh 
echo $0
echo $1
echo $2
echo ${11}  # 超过两位数,需要使用{}进行分隔
[root@VM-4-2-centos ~]# ./a.sh start0 start1 start2
./a.sh
start0
start1
  • 定义变量
变量名=变量值  # 注意等号左右不能有空格a=1
  • 获取变量
$变量名 # 获取变量名
${变量名}  # 获取变量名,类似于python中的f'{变量名}',格式化输出
​
[root@VM-4-2-centos ~]# a=30
[root@VM-4-2-centos ~]# echo $a
30
[root@VM-4-2-centos ~]# echo $a%
30%
[root@VM-4-2-centos ~]# echo $aRMB  # 不能正常使用,所以使用{}
​
[root@VM-4-2-centos ~]# echo ${a}RMB
30RMB
  • 修改变量
重新赋值就可以修改变量的值
[root@VM-4-2-centos ~]# a=1
[root@VM-4-2-centos ~]# echo $a
1
[root@VM-4-2-centos ~]# a=100
[root@VM-4-2-centos ~]# echo $a
100
  • 删除变量
unset 变量名
[root@VM-4-2-centos ~]# a=10
[root@VM-4-2-centos ~]# echo $a
10
[root@VM-4-2-centos ~]# unset a
[root@VM-4-2-centos ~]# echo $a
  • 数据类型
整形
age=18
​
浮点型
salary=53.7
​
字符串类型,如果想让字符串中包含特殊字符,就是用单引号,普通字符串使用单引号和双引号都可以
name='shell'
name="bash"
  • 求变量的长度

三种方式:${#变量名}echo ${变量名}|wc -Lawk

[root@VM-4-2-centos ~]# age=11
[root@VM-4-2-centos ~]# echo ${#age}  
2
[root@VM-4-2-centos ~]# echo $age | wc -L
2
[root@VM-4-2-centos ~]# echo $age | awk "{print length}"
3
  • 切片
[root@Centos7 day02]# msg="hello world"
[root@Centos7 day02]# echo ${msg}
hello world
[root@Centos7 day02]# echo ${msg:4}  # 从4号索引开始
o world
[root@Centos7 day02]# echo ${msg:4:3} # 从4号索引开始,连续3个
o w
[root@Centos7 day02]# echo ${msg::3}  # 从0号索引开始连续3个
hel
  • 截断
# 1、删除左边的
[root@Centos7 day02]# url="www.sina.com.cn"
[root@Centos7 day02]# echo ${url#www.}  # #代表从左边开始进行删除
sina.com.cn
[root@Centos7 day02]# echo ${url#*.}  # #代表从左开始删除,一直删除到.结束,一个#表示非贪婪匹配,只匹配到第一个.
sina.com.cn
[root@Centos7 day02]# echo ${url##*.}  # #代表从左开始删除,一直删除到.结束,2个#表示贪婪匹配,匹配到所有的.都删除
cn
​
# 2、删除右边的,%表示从右往左删除,其余和#相同
[root@Centos7 day02]# url="www.sina.com.cn"
[root@Centos7 day02]# echo ${url%.cn}
www.sina.com
[root@Centos7 day02]# echo ${url%.*}
www.sina.com
[root@Centos7 day02]# echo ${url%%.*}
www
[root@Centos7 day02]# echo ${url%%w*}
​
[root@Centos7 day02]# echo ${url%w*}
ww
​
​
# 3、示例
[root@www ~]# hostname
www.oldboy.com
[root@www ~]# echo $HOSTNAME
www.oldboy.com
[root@www ~]# echo ${HOSTNAME%%.*}
www
[root@www ~]# echo ${HOSTNAME#www.}
oldboy.com
​
  • 变量的代替
# 变量值的替换,/表示替换 /替换的内容
[root@www ~]# url="www.sina.com.cn"
[root@www ~]# echo ${url/./} # 将第一个.替换
wwwsina.com.cn
[root@www ~]# echo ${url//./}  # 全部替换
wwwsinacomcn
[root@www ~]# echo ${url//./|}
www|sina|com|cn
​
# 应用
[root@www test]# ls
shell_2020_01_linux.txt  shell_2020_03_linux.txt  shell_2020_05_linux.txt
shell_2020_02_linux.txt  shell_2020_04_linux.txt
[root@www test]# 
[root@www test]# echo `ls /test/`
shell_2020_01_linux.txt shell_2020_02_linux.txt shell_2020_03_linux.txt shell_2020_04_linux.txt shell_2020_05_linux.txt
[root@www test]# for fname in `ls /test/`
> do
>     echo $fname
> done
shell_2020_01_linux.txt
shell_2020_02_linux.txt
shell_2020_03_linux.txt
shell_2020_04_linux.txt
shell_2020_05_linux.txt
[root@www test]# for fname in `ls /test/`; do mv $fname ${fname/_linux/}; done
[root@www test]# ls 
shell_2020_01.txt  shell_2020_02.txt  shell_2020_03.txt  shell_2020_04.txt  shell_2020_05.txt
​