shell命令
1.shell是什么?
shell是命令解释器,用于解释用户对操作系统的操作
shell有很多,看cat /etc/shells
centos默认使用的shell是bash
2.Linux的启动过程
BIOS引导介质-MBR(硬盘引导)-BootLoader(grub)-kernel(内核启动)-systemd(系统初始化, systemd为1号进程,centos6位init)-shell
3.shell脚本的格式
cd /usr/local;bash filename.sh, 使用;可以连续执行两条命令
开头加#!/bin/bash,原因:如果是用的sh执行,那么#忽略,表示用bash执行,如果是用bash执行,那么#是注释,忽略首行
4.执行执行方式:
bash filename.sh(不需要可执行权限,产生一个新进程)
./filename.sh(需要执行权限,产生一个新的进程)
source filename.sh(在当前进程执行,变量,cd等在当前进程都生效,执行cd后当前目录会改变)
. *.sh(=source *.sh)
5.管道
管道和信号一样,越是进程通信的方式之一
匿名管道(管道符)是shell变成经常用到的通信工具
管道符是“|”,将前一个命令执行的结果传递给后面的命令
ps | cat
echo 123 | ps
6.重定向
< 输入重定向: read var < /path/to/a/file(read var,输入123,然后echo $var,会看到123)
> 输出覆盖重定向(不要用于系统文件,会把系统文件覆盖)
>> 输出追加重定向
2> 错误重定向
&> 正常却和错误重定向,相当于 > filename.log 2>&1
想要把正确日志和错误日志放到不同的文件,使用> filename.log 2> error.log
还有一种向文件中追加内容的方式, 表示用cat < cat >> filename.log < 123 EOF 7.变量 变量的定义:字母、数字、下划线,不以数字开头,shell中变量不区分类型,弱对象 =左右侧不能使用空格,不然a= 1,a=会被当成一条命令 变量名=变量值: a=123 使用let赋值(避免大量使用,性能低,因为shell是一种解释性的语言): let a=10+20 将命令赋值给变量: l=ls 将命令结果赋值给变量: a=$(ls /etc)或a=`ls /etc` 变量值有空格等特殊字符可以包含在 “" 或 '’ 中,特殊的,想在变量中使用’或“,分别使用”或’括起来 8.变量引用及作用范围 变量引用:${变量名} ,{}可以省略,但是a=123$a4,必须用a=123${变量名}4 变量的作用范围:默认只对当前终端或shell生效,比如在终端定义a=2,再输入bash,相当于开了一个新的bash,定义a=1,然后exit,echo $a,结果是2 示例: a=“123” vim test.sh(内容echo $a) bash test.sh(结果为空,因为用的是子进程) ./test.sh(结果为空,因为用的是子进程) source test.sh(结果为123,用的是当前进程) . ./test.sh(结果为123,用的是当前进程) export a(将a变量导出到子进程) unset a(将a变量从子进程中删除) 9.环境变量、预定义变量、位置变量 环境变量:每个shell打开都可以获得到的变量(所有的环境变量都经过了export) set命令: env命令:查看所有的环境变量 $? $$ $0:上次命令执行结果、当前进程号、当前文件名 $PATH:命令的搜索路径,cd,vim等都去这个变量集合中搜索 $PS1:修改当前提示的终端,可以百度下 位置变量: $1 $2 $3…${n}:第几个参数,大于等于10,加{} 10.环境变量位置 分为全部用户可用: /etc/profile /etc/profile.d/ /etc/bashrc 当前用户可用: ~/.bash_profile ~/.bashrc 特殊的: 每次修改上述文件后,当前终端不会立即被记载,需要使用source来刷新 login shell:su - root(推荐使用,profile也会被加载) no login shell:su root(只有bashrc会被加载) 11.数组 定义数组: IPTS=( 10.0.0.1 10.0.0.2 10.0.0.3 ) 显示数组的所有元素: echo ${IPTS[@]} 显示数组元素个数: echo ${#IPTS[@]} 显示数组第一个元素 echo ${IPTS[0]} 12.转义和引用 转义:\ 引用:"、'和`,比如想输出“,可以用”a\”b“, 输出结果是a”b,在对变量的引用中,""是不完全引用,会对变量进行解释,''为完全引用,会显示如$a而不是a的值. `代表执行命令,与$()相同 注释:# ; :连接两个命令, 如cd /usr/local ; sh filename.sh 13.运算符 =:算数赋值和字符串赋值 unset:取消对变量的赋值 =除了作为赋值运算符,还可以进行判断相等 expr:expr 4 + 5,表达式计算,必须有空格,只支持整数 数字常量: let 变量名=变量值 变量值以0开头为八进制 变量值以0x开头为十六进制 (()) 是let的简化,如(( a++ )), (( a = 10 )), echo $((10 + 10)) 14.特殊符号大全 ()括号: 单个圆括号会产生一个子shell,如( xyz= 123 ),比如在终端输入( xyz= 123 ),然后echo $xyz,啥也看不到 数组初始化也是() []、[[]]: 单独使用方括号是测试(test)或数组元素功能: 比如在终端输入[ 5 -gt 6 ],然后echo $?,结果为1 比如判断是否是root用户,[ $UID = 0 ] 或 [ $USER = root ] 两个方括号表示测试表达式,可以用运算符了,如[[ 5 > 6 ]],等价与(( 5 > 6 )) <>尖括号:重定向符号,输入输出 {}花括号: 输出范围 echo {0..9},注意是两个. 文件赋值 cp /etc/passwd{,.bak},等价与cp /etc/passwd /etc/passwd.bak,两个后缀之间用,隔开,没有不写 && || ! 逻辑运算符: (( 5 > 6 && 4 > 2 )) ;; case分隔符 : 空指令 . 和source命令相同 ~ 家目录 , 分割目录 通配符: *匹配任意个,?匹配一个字符 $ 取值符号 | 管道符 & 后台运行 _ 空格 15.if判断 if [ 测试条件成立 ] 或 结果返回值为0 then 执行自己的命令 fi 结束 简化写法: [ 测试条件 ] && 执行命令 16.if else 判断 if [ 测试条件成立 ] 或 结果返回值为0 then 执行命令 elif [ 测试条件2 ] then 执行命令 else 测试条件不成立,执行命令 fi 结束 17.case select分支判断 最后的*相当于default case $变量 in "case0"|"case1" ) 命令 ;; "case2" ) 命令 ;; * ) 命令 ;; esac 18.for循环 语法: for 参数 in 列表 do 执行命令 done 结束一次循环 示例1,打印0到9:for ele in {0..9}; do echo $ele; done; 示例2,打印当前目录的所有文件名:for ele in $(ls); do echo $ele; done; 特殊的,列表中包含多个变量,用空格分割 对文本处理,要使用文本查看命令取出文本内容 默认逐行处理,如果文本出现空格会当做多行处理 19.C语言风格的for循环 常在awk中使用 for((变量初始化;循环判断条件;变量变化)) do 执行命令 done 示例1,打印0-9:for((i=0;i<10;i++)); do echo $i; done 20.while循环和until循环 while循环: while test条件 do 执行命令 done until循环: 与while循环正好相反,直到test条件成立之前一直运行 until test条件 do 执行命令 done 示例1,打印0-9:a=0; while [ $a -lt 10 ]; do echo $a; (( a++ )); done 21.continue和break,和其他语言相同 22.使用循环处理命令行参数 写一个sh,内容如下: #!/bin/bash for ele in $@; do echo $ele; done 也可以 while [ $# -ge 1 ]; do echo $1; shift; done; (shift的意思为参数左移,a b c 变成 b c) 23.自定义函数 将通用功能写成函数,写到一个sh文件中,比如func.sh, 在需要使用的地方source func.sh,就引入了这个函数,可以在当前脚本中直接使用,func.sh示例: function test() { cd /usr/local echo $(ls) echo $@ #打印所有参数 } #执行test, 可以向方法传递参数 test a b c testFunc.sh示例: #!/bin/bash source ./func.sh test 1 2 3 24.local变量 我们经常会用i变量名,如果使用的是当前进程,可能会被其他脚本修改,使用前先把声明为局部变量 local i 25.系统函数库 系统自建了函数库,可以在脚本中引用:less /etc/init.d/functions 26.脚本控制 脚本优先级控制: 可以用nice和renice调整脚本优先级 避免出现“不可控的”死循环 死循环导致cpu占用过高 死循环导致死机 示例,fork炸弹:func() { func | func& }; func, 会发现炸了 ulimit -a 查看当前设备的各种限制,普通用户有最大进程数限制,退出当前用户就完事了 27.信号捕获 trap "echo sig 15" 15: 表示捕获了15号信号后,执行echo sig 15 (一般监听器,比如while : ;do :; done, 使监听器一直运行) 作用:一般用来捕获信号做额外操作,比如启动了一个备份脚本,不希望被kill掉,那么就捕获15,就可以了 kill pid 默认发15号信号给应用程序 ctrl + c 发送2号信号给应用程序 kill -9 pid 9号信号不可阻塞(不可捕获) 28.一次性执行任务 at命令: 比如at 03:00 (回车) echo hello > /usr/local/at.log(回车), 然后按ctrl + d提交任务 atq查看任务列表 29.周期性计划任务 crontab -l 查看所有计划任务 crontab -e 编辑计划任务 anacontab:延时计划任务,保证因重启错过了执行,也能被执行一次 30.脚本文件加锁 flock 锁文件: flock -xn "/tmp/f.lock" -c "/root/a.sh" 这样的话,/root/a.sh只能被执行一次