shell脚本
运行方式:
- 给文件x权限,通过文件路径去执行
- 直接运行解释器,将脚本文件作为解释器程序的参数
bash file
退出状态码:echo $?查看:
- 范围为0-255,如果上一条命令执行成功则为0,如果失败为非零。
- 脚本一旦遇到exit命令就会立刻终止。如果没有指定退出状态码,则其码取决于脚本中执行的最后一条命令的状态
配置文件
全局配置:
- /etc/bashrc
- /etc/profile
- /etc/profile.d/*.sh
个人配置
- ~/.bash_profile
- ~/.bashrc
profile类:为交互式shell提供配置
bashrc:为非交互式的shell提供配置
交互式切换:su - username
/etc/profile->/etc/profile.d/*.sh->~/.bash_profile-> /.bashrc->/etc/bashrc
如果想开机自启,可以放在profile.d目录下
非交互式切换:su username
语法
变量
赋值变量时,使用$()或者反引号可以将语句命令赋值给变量
[root@server1 test1]# ip a | grep brd|grep inet|awk '{print $4}'
192.168.226.255
[root@server1 test1]# ip_addr=`ip a | grep brd|grep inet|awk '{print $4}'`
[root@server1 test1]# echo $ip_addr
192.168.226.255
只读变量
[root@server1 test1]# t12='hello world'
[root@server1 test1]# readonly t12
[root@server1 test1]# t12='123'
-bash: t12: 只读变量
当然,当你的变量和句子混在一起的时候,你可以使用${}来帮助解释变量范围,就像这样
#!/bin/sh
var1=" hello world"
echo "I want to say${var1}"
删除变量
[root@server1 test1]# unset ip_addr
[root@server1 test1]# echo $ip_addr
只读变量不能直接删除!
只读变量删除方式:
[root@server1 test1]# cat << EOF|gdb
> attach $$
> call unbind_variable("只读变量名")
> detach
> EOF
如果没有gdb先yum安装一下
变量种类
- 本地变量:仅在当前shell进程有效,其他shell、子shell进程都无效
环境变量:当前shell和子进程有限
- export var="value"
- declare -x var = “value”
- 内置环境变量,如PATH\SHELL
- 局部变量:代码片段生效
- 位置变量:$n,传参用,如$1,$2
特殊变量
- $0:命令本身
- $*:把所有参数当作一个整体
- $@:所有参数
- $#:参数个数
字符串
单引号中的所有字符都会原样输出,而双引号中的变量、转义字符等都可以被解释,单引号中不能有单引号,转义了的也不行
[root@master shtest]# ./test1.sh
I want to say${var1}
[root@master shtest]# cat test1.sh
#!/bin/sh
var1=" hello world"
echo 'I want to say${var1}'
拼接字符串
[root@master shtest]# ./test1.sh
hello worldnihao, hello world
[root@master shtest]# cat test1.sh
#!/bin/sh
var1=" hello world"
var2="nihao,$var1"
echo $var1$var2
输出字符串长度${#}
[root@master shtest]# cat test1.sh
#!/bin/sh
var1=" hello world"
var2="nihao,$var1"
echo ${#var2}
[root@master shtest]# ./test1.sh
18
字符串切片
[root@master shtest]# ./test1.sh
nihao
[root@master shtest]# cat test1.sh
#!/bin/sh
var1=" hello world"
var2="nihao,$var1"
echo ${var2:0:5}
数组
赋值:
array=(v1,v2...)
array[0]=v1
读取:${array[index]}
,索引也可写*和@
数组长度:#array[@]
算数表达式
(1) let var(变量名)=算术表达式 ## 等于号和算数符号左右都不要加空格!
(2) var=$[算术表达式]
(3) var=$((算术表达式))
(4) var=$(expr argl arg2 arg3 …)
条件测试
数值测试
‐gt:是否大于
‐ge:是否大于等于
‐eq:是否等于
‐ne:是否不等于
‐lt:是否小于
‐le:是否小于等于
判断两数是否相等
#!/bin/bash
read -p "please input two number" num1 num2
if [ $num1 -eq $num2 ];then
echo "they are equal"
else
echo "they are different"
fi
字符串测试
==:是否等于
>:是否大于
<:是否小于
!=:是否不等于
=~:左侧字符串是否能够被右侧的PATTERN所匹配
Note:此表达式一般用于[[ ]]中
-z “STRING”:测试字符串是否为空,空则为真,不空则为假
-n “STRING”:测试字符串是否不空,不空则为真,空则为假
文件测试
简单的存在性测试:
-a FILE :文件存在性测试,存在为真,否则为假
存在性及类型测试:
-b FLIE:是否存在且为块设备文件;
-c FILE:是否存在且为字符设备文件;
-d FILE:是否存在且为目录文件;
-f FILE:是否存在且为普通文件;
-h FILE 或 -L FILE : 存在且为符号链接文件;
-p FIEL :是否存在且为命名管道文件;
-S FILE:是否存在且为套接文件;
文件权限测试:
-r FILE:是否存在且可读
-w FILE:是否存在且可写
-x FILE:是否存在可执行 文件特殊权限测试:
-g FILE:是否存在且拥有sgid权限;
-u FILE:是否存在且拥有suid权限;
-k FILE:是否存在且拥有sticky权限;
文件大小测试:
-s FILE:是否存在且非空 文件是否打开:
- fd:fd表示文件描述符是否已经打开且与某终端相关
-N FILE:文件自动上一次读取之后是否被修改过;
-O FILE:当前用户是否为文件的属主;
-G FILE:当前有效用户是否为文件数组;
双目测试:
FILE1 -ef FILE2 :FILE1与FILE2是否指向同一个设备上的相同inode
FILE1 -nt FILE2:FILE1是否新于FILE2
FILE1 -ot FILE2:FILE1是否旧于FILE2
条件组合测试
与:
cmd1 && cmd2
cmd1 -a cmd2
或
cmd1 || cmd2
cmd1 -o cmd2
if
if [ 条件 ];then #中括号当中两边必须加空格
条件
elif [ ];then
条件
else
条件
fi
read交互
read:读取用户输入的数据
-p:输出提示符
read -p "input a number" num1
-a:把内容读入数组
read -a array
-n:限定最大有效输入长度
-r:转义生效
read line 从输入流中读取一行
for
for 变量 in 列表;do
...
done
while
while 条件;do
...
done
函数
function 函数名() #function可不加
{
...
return
}
调试
-x : 在执行时显示参数和命令;
+x:禁止调试
-v:当命令行进行读取时显示输入;
+v:禁止打印输入。
- n:检测脚本中的语法错误
bash -x filename
实例
统计两个文件中除去空白行的行数之和
[root@server1 test1]# cat ti.sh
#!/bin/bash
number1=`grep -v '^$' $1|wc -l`
number2=`grep -v '^$' $2|wc -l`
let all=number1+number2
echo "the count of useful line is $all"
[root@server1 test1]# ./ti.sh /etc/passwd /etc/shadow
the count of useful line is 38
统计在线的地址
#!/bin/bash
for i in {1..255};do
ping -c2 -w2 192.168.226.$i &> /dev/null && echo 192.168.226.$i >> ./list &
done
开机自启显示系统信息,放在/etc/profile.d/
#!/bin/bash
yum install -y net-tools &> /dev/null
kernel=`hostnamectl | grep Kernel| awk -F: '{print $2}'`
system=`hostnamectl | grep System|awk -F: '{print$2}'`
ip=`ifconfig|awk '{if(NR==2)print$2}'`
pubip=`curl -s icanhazip.com`
echo "操作系统为$system"
echo "内核为$kernel"
echo "ip为$ip"
echo "公网ip为$pubip"
评论已关闭