1. shell 介绍
1.1 linux shell介绍
shell 是一个解释器,提供一个给用户内内核发送命令的界面,内核回复shell界面
shell分类:
b shell类: bash(一种) liux标准shell
c shell类 主要在bsd的unix系统中使用,语法和c类似
查看linux支持shell 类型
不同shell切换,切换 sh shell
查看 不同用户对应shell 目录
1.2. 基本输出命令echo
如果使用-e,那么echo支持复杂字符串转化命令
\n | 换行 |
\t | 制表符tab |
echo -e "a\tb\t\nc\td"
echo -e "\e[1;31m abcd \e[0m" 颜色输出
颜色:31m 红色 32m 绿色 33m 黄色 37m白色
2. bash创建
#/bin/bash 头部,必须
./hello.sh: 执行
chmod 755 hello.sh
bash hell.sh: 执行
3. shell 基本功能
history: 历史记录
保存目录: vi ~/.bash_history,关闭终端的时候才写进去把历史记录
history -c: 清空历史命令,避免别人发现
用 上、下箭头 查看历史命令
命令补全:tab
4. 别名:
alias : 查看系统所有别名
alias vi="vim" 设置别名,当前shell生效
要让别名永久生效:
vim ~/.bashrc 写入 alias vi="vim"
5. 快捷键:
ctrl+a : 光标移动命令行开头
ctrl+e : 光标移动命令行尾部
ctrl+u : 剪切
ctrl+k : 粘贴
ctrl+c : 强制终止当前命令
ctrl+d : 退出终端
ctrl+z : 暂停,放入后台
6. 输入|输出重定向
输出重定向,默认输出到终端,重定向到文件中
命令 > 文件 : 覆盖,文件不存在会创建文件
命令 >> 文件: 追加
如果要保存错误命令,需要加2>
命令 2 > a.txt
比如:lst 2>a.txt 只写入错误
lst >> a.txt 2>&1 你不知道命令执行错误还是正确,正确错误写入
lst &>>a.txt
ls &>/dev/null: 丢弃到垃圾箱, 执行结果不要
ls >> true.txt 2>>error.txt : 把正确的写入true.txt 错误写入error.txt
输入重定向:本来从键盘输入,现在输入方向来自文件
wc 然后键盘输入 ctrl+d 结束
-c 统计字节数
-w 统计单词数
-l 统计行数
wc -l < a.txt : 统计a.txt的行数
7. shell 多命令执行
7.1. 多命令的顺序执行
命令1;命令2 命令顺序执行,命令间没有关系
例子:date ; dd if=/dev/zero of=/home/xiaoming/testfile bs=1k count=100000 ; date
计算创建一个100M文件需要时间
7.2. 命令1&& 命令2
命令1正确执行才执行命令2 ,否则不执行命令2
例子1源码安装:./configure && make && make install
7.3. 命令1 || 命令2
命令1执行正确,不执行2,命令1执行错误,才去执行2
ls || echo no :判断一条命令是否正确执行
ls && echo yes || echo no : 判断一条命令是否正确执行
如果 ls 争取执行 ,那么 echo yes
否则 echo yes错误执行, echo no
/dev/null : 写,系统无限大的 垃圾桶
/dev/zero : 读,系统无限大的空洞文件
8. 管道命令|
命令1正确输出给 | 命令2
ls -a | more : 分屏显示
netstat -an |grep 8080 :过滤 端口
grep "root" /etc/passwd grep 文件中搜索符合条件的字符串行
-n : 显示行号
-v :取反, grep -v "root" 不包含root的行
--color=auto : 内容显示颜色
9. 通配符使用[用于匹配文件名]
? 匹配一个字符
* 匹配0个或者多个
[] 任意[]中一个,[abc]代表a或者b或者c, 注意,[]只能匹配一个字符
[-] 范围 [a-z]
[^0-9] 非数字
rm -rf *
ls [0-9].txt : 显示1.txt例如
10. Bash中其他特殊符号:
'': 括起来内存才是整体, $没有特殊含义
"": $有特殊含义
echo '$(date)' : 输出'$(date)'
echo "$(date)" : ""中$有特殊含义,输出日期
执行赋值:
``: ab=`date` [反引号]
$(): 表示内容是命令,首先执行,在赋给变量
abc=$(date)
#: 注释
$: 调用变量
\: 把特殊符号失去意义 echo \$name 输出 $name
10. Bash中变量
变量查看: env
1. PATH=/usr/lib64/qt-3.3/bin:/usr/local/bin:/usr/bin:/bin:/usr/local/sbin:/usr/sbin:/sbin:/home/xiaoming/bin
敲一条命令,查找命令的路径
把自己写的.sh拷贝到以上路径位置中,可以直接执行sh,不推荐
#提示符:root用户
$提示符:普通用户
10.1. 用户自定义变量
变量名称可以有字母、数组、下划线组成,不能数字开头
Bash中变量默认是字符串,Bash变量赋值用=,=两边不能有空隔
name="xiao ming"
age=20
date=$(date +%y%m%d) 格式化日期
size=$(sudo du -sh /var/lib) 统计大小
变量叠加:
name=xiaoming
name=ilove${name}
name="I love $name"
PATH=$PATH:/home/bin 也可以变量叠加,如果后面是字母,那么就${PATH}
echo $name
unset name: 删除变量
10.2 环境变量:
系统默认有定义环境变量:比如$PATH
用户也可以自定义环境变量:只在当前shell[子shell]中有效,永久有效,写入本地
语法:export NDK=""
环境变量文件,linux启动、或者用户登录的时候读取生效:
/etc/profile : 里面有 $PATH变量, 全局
~/.bashrc: 当前用户环境变量
source /etc/profile: ubuntu下不起作用,重启
~/.bash_logout: 用户logout的时候读取执行
10.3.位置参数变量:
用于向脚本中传递参数和数据,变量名不能自定义
${0} : 命令本身
${1-9} : 1-9个参数,10以上 ${10}
$* 把所以参数一个整体
$@ 每个参数都是独立的
$# 参数个
10.4.预定义变量:
变量名不能自定义,变量也是固定的
$? 上一个命令执行正确0 错误非0
$$ 显示当前进程pid
11. 键盘输入
read -p "提示信息"
-t "不输入超时"
-n 指定字符数结束read,默认是enter结束
-s 隐藏数据,比如密码
read -t 30 -p "input your name:" name # 内容存储在name中
echo $name
read -n 1 -t 10 -p "input your set[M/F]" gender ; echo ""
echo $gender
12. Bash数值运算:
aa=1
bb=2
declare -i cc=$aa+$bb
dd=$(expr $aa + $bb) +两边必须有空格
dd=$(($aa+$bb*100)) # 实际开发使用
逻辑运算:
gg=$(( 1&& 1))
gg=$(( 1 || 0))
准备资料用于测试,s.txt用tab分割开:
ID Name gender
3 laoji 610
1 deng 40
2 rao 10
3 li 4000
4 shun 899999
13. Linux正则表达式:用于匹配文件中的字符串
* 前一个字符重复一次或者0次
. 匹配除了换行符的任意一个字符
^ ^hello , 以hello开头的行
$ hello$ , 以hello结尾的行
[] 匹配[]中一个字符 [a-z]
[^]: [^a-z] 任意一个非小写字母
\ : 转义符, 取消特殊字符的函数
\{n\} : [1][3-8][0-9]\{9\}:手机号码 前面的恰好出现n次
\{n,\}: [0-9]\{2,\} 前面数字最少出现2次 012
\{n,m\} : 前面最少出现n次,最多出现m次 [a-z]\{6,8\}: 匹配6到8个小写字母
+ : 必须匹配1次或多次
grep "a*" test.txt : 匹配所有行
grep "aa*" aa.txt : 至少出现一次a的单词,显示的行
grep "a\{1,\}" aa.txt 至少出现一次a的单词
14. linux字符串截取命令cut、grep:
grep -v ^# /etc/inittab: 比如看apache的READ.ME文件,把注释文本过滤掉,显示内容
grep 提取行 cut 提取列
1. cut -f 2 s.txt 提取第2列,默认文件分割符是tab键
2. cut -f 1,2 s.txt 提取第2和第3列
3. 默认是tab分割符号,指定分割符号 ,cut 不能识别空格做为分隔符
cut -d ":" -f 1 /etc/passwd
例子1:取出姓deng的分数:
cat s.txt |grep "deng" | cut -f 1
15. linux 格式化输出printf
printf "hello"
printf '%s\n%i\n' nihao 520
nihao
520
printf '%s\t%s\t%s\n' $(cat s.txt) 等价于 echo
printf:会自动加换行
print: 不会加\n
16. awk命令使用
awk输出只支持printf,默认分割符空格或者tab
语法: awk '条件1{动作1} 条件2{动作2}...'文件名
awk '{printf $1 "\t" $2 "\n"}' s.txt s.txt数据源 $1第一行
案例1:计算磁盘剩余空间,如果不够报警,该文件分割符是空格
df -h |grep "sda1" | awk '{printf " %s\n",$5}' | cut -f 1 -d "%"
案例2:取出用户名和用户ID,指定特殊文件分割符
BEGIN在所以命令执行之前,执行BEGIN
awk 'BEGIN{print "start --- " } {print $2}' s.txt
awk 'BEGIN{FS=":"}{print $1 "\t" $3}' /etc/passwd : 取出用户名和用户ID
FS 指定awk风割符
如果不使用BEGIN
awk 'BEGIN{FS=":"}{print $1 "\t" $3}{print "end.."}' /etc/passwd
所有操作完成之后执行END
案例3: 取出gender 大于 60 用户 s.txt 文件中,做运算
cat s.txt |grep -v Name | awk '$3 >=60 { printf $2 "\n"}'
grep -v Name: 去掉Name列
17. sed命令:
程序文本编辑器,可以对文本进行删除、修改、添加
-i 把修改数据替换文件,而不是屏幕输出
sed '2p' -n s.txt : 输出文件第二行到到控制台
df -h | sed '2p' -n: 输出 df -h的第二行到控制台
sed '2,4d' s.txt: 删除2到4行
sed '5a 5\tzhu\t60' s.txt 5行后追加
sed '2i 3\tjiaba\t610' s.txt -i 2行前插入
sed '2c 3\tlaoji\t610' s.txt -i 2行替换
sed '6s\30\10000\g' s.txt -i 把6行的30替换成10000
sed -e '2s\wubing\dachui\g;2s\610\888\g' s.txt -i -e多个字符替换
18. 其他命令:
sort: 排序
sort -n -t ":" -k 3,3 /etc/passwd
-n: 提取字符串转为数字
-r:反向排序
19 . linux 条件判断 【 shell 中 0为真 1为假 】
19.1 文件是否存在语法:
-d: 目录存在,返回真
-e: 文件存在,返回真
-f: 普通文件,返回真
如何使用:
test -f s.txt
[ -f s.txt ] ==> echo $?
[ -f s.txt ] && echo "yes" || echo "no"
19.2 权限判断:
-r: 文件是否存在,是有有读权限
-w: 文件是否存在,是有有写权限
-x:
问题:所有者、所属组、不同组只有有一个有权限,那么返回yes
如何判断所有者: 用ls 去解析权限字符串
19.3. 数判断: a1 整数1 a2 整数1
a1 -eq a2 相等
-ne !=
-gt >
-lt <
-ge >=
-le <=
[ "$a" -lt "$b" ] && echo "yes" || echo "no"
19.4.字符串判断:
-z 判断字符串是否为空 空位真 [ -z $name] && echo "yes" || echo "no" 有空隔地方必须要有
-n 字符串是否非空
字符串1==字符串2 相等返回真
字符串1!=字符串2 不相等返回真
20 .多重判断:
语法:判断1 -a 判断2 相单于逻辑与 &&
语法:判断1 -o 判断2 相单于逻辑或 ||
!判断 逻辑!
[ "$a==10" -a "&b==20" ] && echo "yes" || echo "no"
21. if语句
21.1.磁盘监控shell
#/bin/bash
rate=$(df -h |grep "sda1" | awk '{printf " %s\n",$5}' | cut -f 1 -d "%")
if [ $rate -ge 80 ]
then
echo "Warning! /dev/sda1 is full must !"
else
echo "safe to sda1"
fi
21.2.判断apache是否启动
sudo apt-get install apache2
yum -y install httpd : centos安装
/etc/init.d/apache2 [ start | stop | restart | status ] : 启动、停止、重启、状态
yum -y install nmap :nmap用于查看某一个软件是否在运行的工具
nmap -sT 192.168.32.129 |grep tcp |grep http | awk '{print $2}' : 返回open,通过扫描软件判断apache是否启动
21.3. elseif 输入文件类型判断, 判断输入文件类型
#!/bin/bash
read -p "please input file name:" file
if [ -z $file ]
then
echo "input is null"
exit 1
elif [ ! -e $file ]
then
echo "$file is no exit"
exit 2
elif [ -d $file ]
then
echo "$file is directory"
elif [ -f $file ]
then
echo "$file is file"
else
echo "$file is an other file"
fi
22. case 使用,输入yes/no
#!/bin/bash
read -p "please input yes/no" -t 30 cho
case $cho in
"yes")
echo "your choose is yes!"
;;
"no")
echo "your choose is no"
;;
"*")
echo "your choose is error!"
;;
esac
23. for循环使用
用法1:
#/bin/bash
for i in 1 2 4 5 6
do
echo $i
done
demo批量解压文件:
#/bin/bash
ls *.tar.gz > ls.log
for i in $(cat ls.log)
do
echo $i
tar -zxf $i &>/dev/null
done
用法2:
#!/bin/bash
s=0
for(( i=0 ;i<=100;i=i+1 ))
do
s=$(($s+$i))
done
echo "the num of ${s}"
demo 批量创建用户:
#!/bin/bash
read -t 30 -p "input name:" name
read -t 30 -p "input num:" num
read -t 30 -p "input password:" pass
if [ -n $name -a -n $num -a -n $pass ]
then
y=$(echo $num | sed 's/^[0-9]*$'//g)
# shell中不能判断一个变量是数字
# 如果有字母,那么使用sed命令用空替换,y是空
if [ -z $y ]
then
for(( i=0 ;i< $num ; i=i+1))
do
useradd $name$i &>/dev/null
# echo $pass | passwd --stdin "$name$i" $>/dev/null
# echo "xiao:123456" | chpasswd
# https://www.cnblogs.com/sogeisetsu/p/11397648.html
echo "$name$i":"$pass" | chpasswd
done
fi
fi
24. while do-while
24.1. while使用
#!/bin/bash
i=0
s=0
while [ $i -le 100 ]
do
s=$(( $s+ $i ))
i=$(( $i +1 ))
done
echo "num is $s";
24.2. do-while
#!/bin/bash
i=0
s=0
until [ $i -gt 100 ] #条件满足退出, use utils but no use while
do
s=$(( $s+ $i ))
i=$(( $i +1 ))
done
echo $s