shell学习
echo
输出带颜色
echo -e "\e[1;31m this is my red print"
# 输出后所有文字变色,可修改回来
echo -e "\e[1;31m this is my red print \e[1;0m"
变量
未使用变量代码
test.sh
#!/usr/bin/bash
ping -c1 127.0.0.1 &>/dev/null && echo "127.0.0.1 is up" || echo "127.0.0.1 is down"
如果要修改127.0.0.1 ,需要修改三个地方,很麻烦
使用变量
#!/usr/bin/bash
ip= "127.0.0.2"
ping -c1 $ip &>/dev/null && echo "$ip is up" || echo "$ip is down"
变形,方便理解 && || 符号
#!/usr/bin/bash
ip="127.0.0.2"
if ping -c1 $ip &>/dev/null ;then
echo "$ip is up"
else
echo "$ip is down"
fi
if 条件拓展
#!/usr/bin/bash
ip="127.0.0.2"
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ]
then
echo "$ip is up"
else
echo "$ip is down"
fi
$? 代表上一个命令的运行结果
注意空格 [ $? -eq 0 ]
变量从控制台读取
#!/usr/bin/bash
# echo "请输入ip"
read -p "请输入ip: " ip
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ]
then
echo "$ip is up"
else
echo "$ip is down"
fi
命令形式传入参数
#!/usr/bin/bash
# echo "请输入ip"
ping -c1 $1 &>/dev/null
if [ $? -eq 0 ]
then
echo "$1 is up"
else
echo "$1 is down"
fi
保存脚本后执行命令
./pingtest.sh 172.0.0.1
#或者
sh pingtest.sh 172.0.0.1小知识 bash文件如果指定了执行器如上述 #!/usr/bin/bash 就可以直接使用 ./pingtest.sh 否则需要指定执行器 bash sh是bash的缩写
变量作用域
ip=172.0.0.1
# 新建一个bash
vi t1.sh
#!/usr/bin/bash
echo $ip
#保存shell文件并执行
sh t1.sh
#此时什么也不能输出,因为shell脚本没有该变量
#使用export
export ip=172.0.0.1
变量修改作用域方式二(建议)
env.sh
#!/usr/bin/bash
name="lilei"
age=12
export name age
biz.sh
#!/usr/bin/bash
echo $name
echo $age
使用
source env.sh
sh biz.sh
变形
biz.sh
#!/usr/bin/bash
. ./env.sh
echo $name
echo $age
sh biz.sh
位置变量
$1 $2 $3 … ${10}
预定义变量
$0 脚本名 带路径
$* 所有的位置参数
$@ 所有的参数
$# 参数个数
$$ 当前进程的PID
$! 上一个后台进程 的PID
$? 上一个命令的返回值 0表示成功
使用文件内容作为参数
文件:11.text
127.0.0.1
127.0.0.2
ping1.sh
#!/usr/bin/bash
#如果用户没有添加参数
if [ $# -eq 0 ];then
echo "usage: `basename $0` file"
exit
fi
if [ ! -f $1 ];then
echo "error $1 is not file"
exit
fi
for ip in `cat $1`
do
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo " $ip is ok"
else "$ip is down"
fi
done
变量运算
符号 `` = $() 意思是先执行
expr
$(())
$[]
let
t1=12
t2=2
expr $t1 + $t2
t3=`expr $t1 + $t2`
t3=$(expr $t1 + $t2)
# expr 运算符涉及转义 如*
t3=$(expr $t1 \* $t2)
t3=$(($t1+$t2))
t3=$((t1+t2))
# 推荐使用$[]
t3=$[t1+t2]
#幂操作
t3=$[t1**t2]
let t3=$t1+$t2
#
使用案例:查看内存占用情况
#!/usr/bin/bash used.sh
use_m=$(free -m|grep '^Mem:'|awk '{print $3}')
total_m=$(free -m|grep '^Mem:'|awk '{print $2}')
#percent_c=$[use_m/total_m]
percent_c=$[use_m*100/total_m]
echo "current memory use percent is ${percent_c}%"
#调试执行
sh -vx used.sh
使用案例:循环执行目标次数任务
#!/usr/bin/bash ping01.sh
ip=127.0.0.1
i=1
while [ $i -le 5]
do
ping -c1 $ip &>/dev/null
if [ $? -eq 0 ];then
echo "$ip is up"
fi
let i++
done
#调试执行
sh -vx used.sh
变量删除
#从前向后删
%从后向前删
两者使用完全一样,一下案例可用%替换
name="niu niu qi chong tian"
echo ${name#niu}
#niu qi chong tian
echo ${name#*iu}
#niu qi chong tian
echo ${name##*iu}
#qi chong tian
() (()) $() $(()) {} ${} [] [[]] $[] 符号意义
- () 表示在子shell中执行
- (()) 数值比较 运算 c风格执行判断 如: if ((1>2));then echo “111” ;fi
- $() 命令替换 同 ``
- $(()) 运算 echo $((1+2))
- {} 数组 touch file{1…3}
- ${} 变量的引用,可适当操作
- [] 条件测试 用法参考 man test
- [[]] 功能包含[] ,支持正则 [[ =~ ]],自行研究
- $[] 整数运算 $[2*10] $[2**10]
条件测试 test [] [[]]
- 文件测试
当前用户
[ -e dir|file ] 存在目录或者文件
[ -d dir ] 存在目录
[ -f file ] 存在文件
[ -r file ] 有读取权限
[ -x file ] 有执行权限
[ -w file ] 有写权限
[ -L file] 是链接
- 数值比较 [ 整数1 操作符 整数2 ]
[ 1 -gt 10 ] 大于
[ 1 -lt 10 ] 小于
[ 1 -eq 10 ] 等于
[ 1 -ge 10 ] 大于等于
[ 1 -le 10 ] 小于等于
[ 1 -ne 10 ] 不等于
case 语法
case 变量 in
模式1)
命令1
;;
模式2)
命令2
;;
*)
无匹配名利
esac
case删除用户
#!/usr/bin/bash
read -p "please input username: " user
id $user &>/dev/null
if [ $? -eq 0 ];then
echo "no such user: $user"
exit 1
fi
read -p "are you sure?[y/n]:" action
if [ "$action" != "y" -o "$action" != "Y" ];then
exit 2
fi
userdel -r $user
for while
let sum = $sum + $i
#!/usr/bin/bash
i=1
while [ $i -le 100 ]
do
let sum = $sum + $i
done
echo “sum:$sum”
#!/usr/bin/bash
i=1
until [ $i -gt 100 ]
do
let sum = $sum +
i
d
o
n
e
e
c
h
o
"
s
u
m
:
i done echo "sum:
idoneecho"sum:sum"
fd = file derection
打开一个文件
exec 6<> /file11 # 6是文件描述符
关闭一个文件 释放文件句柄
当一个文件的FD未被释放,删除源文件也不回影响FD,可以恢复文件
echo “111” >> /proc/$$/6
exec 6<$-
查看进程下的打开文件
ll /proc/$$/fd
管道
ps -ef|grep java
管道是一个零时文件
tty 查看终端编号
创建一个管道,可跨终端
mkfifo /tmp/fifo1
file /tmp/fifo1 #查看文件类型
终端1
grep ‘sda’ /tmp/fifo1
终端2
ll /dev > /tmp/fifo1
正则表达式
^ 行首 ^abc 以a开头
$ 以结尾 abc$ c
. 一个任意字符
- 0个或者以上 abc*
[]
[-]
[^] 不是如 [^a-z] 不是 a-z的一个字符
\ 转义
< 词首 如 i like you <like>
> 词尾
- 1到多次
? 0-1
x{m} m次
x{m,} m以上的次数
x{m,n} m-n次
查找目标以及输出后两行
grep -B2 ‘root’ /etc/passwd
查找目标以及输出前两行
grep -C2 ‘root’ /etc/passwd
流编辑器 sed
sed -r ‘’ 1.text
sed -r ‘2d’ 1.text 删除第二行
sed -r ‘2,3d’ 1.text 删除低二、三行
sed -r ‘/root/d’ 1.text 删除有root的行
sed -r ‘1~2d’ 1.text 从1行开始,每隔两行删除
sed -r ‘0~2d’ 1.text 从0行开始,每隔两行删除
命令 | 功能 | 案例 |
---|---|---|
a | 在当前行后添加一行 | sed -r ‘/root/a tianjia’ 1.text |
c | 用新文本修改(替换)当前行中的文本 | |
d | 删除行 | sed -r ‘3{h,d}’ 1.text |
i | 在当前行之前插入文本 | |
l | 列出非打印字符 | |
p | 打印行 | |
n | 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理 | |
q | 结束或者退出sed | |
! | 对所选行以外的所有行应用命令 |
命令 | 功能 | 案例 |
---|---|---|
s | 用一个字符替换另外一个 | 3,5s/(.)/\1/ 3,5s/./#&/ &表示匹配到的内容 %s/root/&1/ %所有 |
c | 用新文本修改(替换)当前行中的文本 | |
d | 删除行 | |
i | 在当前行之前插入文本 | |
l | 列出非打印字符 | |
p | 打印行 | |
n | 读入下一输入行,并从下一条命令而不是第一条命令开始对其的处理 | |
q | 结束或者退出sed | |
! | 对所选行以外的所有行应用命令 |
持续更新中