系统命令
# cat EFO cat >> file << EOF neirong EOF # 清空 >file 清空文件 [root@Poppy conf]# sed -i '/^#.*$/d' joker 删除#开头的行 [root@Poppy conf]# sed -i '/^$/d' joker 删除空行,回车的空行 # 一行显示几个字段,空格就是分隔符,-n指定几个 xargs -n 1 < file # echo xx 1>a.txt 2>b.txt b.txt里面包含了错误 # echo xx 1>a.txt 2>&1 正确错误的输出都保存到a.txt上 2>&1 2表示错误的输出跟1的输出一样存入a.txt # echo xx &>a.txt 正确错误的输出都保存到a.txt上等同于上面 # \cp -rf 删除 /usr/bin/cp -rf # alias 终端alias查看系统的别名 /反写线就是屏蔽别名,-i就是提示覆盖,移动等 设置别名 alias cp='cp -i' alias mv='mv -i' # unalias unalias cp 取消设置好的别名 cp /tmp /mnt 不提示了 # seq 2 10 2-10 seq -s ' ' 10 打印1-10,空格隔开,-s指定分隔符,默认是/n seq 2 2 10 间隔2的2-10 seq 100 >ett.txt 1-100 # sed -n '20,30'p ett.txt -n的作用取消默认输出,如果没有-n打印的还是1-100 p是打印 sed -n '$'p ett.txt 最后一行,行尾 # awk '19<NR && NR<31' ett.txt NR是行号的意思 # grep 20 -A 10 ett.txt 匹配第20行内容之后,如下 -B 除了显示匹配的一行外,并显示该行之前的num行 -A 除了显示匹配的一行外,并显示该行之后的num行 -C 除了显示匹配的一行外,并显示该行之前后各num行 # sed 's#old#new#g' file.txt 默认打印输出 -i 改变文件内容 -e 允许多项编辑 # tr 替换 -d 删除 echo "HELLO WORLD" | tr 'A-Z' 'a-z' hello world echo "hello 123 world 456" | tr -d '0-9' hello world # ;命令分隔符 pwd;pwd # {} 生成一个序列 echo {1..10} seq -s ' ' 10 echo {a..z} mkdir /data/{22,33}/joker -p ~ 当前用户的家目录 - 当前目录的上一次目录,也就是切过来的目录 cd - ! 取反 find /data -type f ! -name 'test.sh' -o 或者 find /data -type f -name 'test.sh' -o -name 'a' -a 并且 find /data -type f -name 'test.sh' -a -name 'a' # && 并且 在shell脚本中,&&脚本中
# 单引号与双引号
单引号里面是什么就是什么
echo "date" 显示date字符串
echo "`date`" 显示时间
echo "$(date)" 显示时间
echo '`date`' 显示`date`字符串
# {}
echo oldboy{1,2,3}
echo oldboy{1..5}
echo oldboy{a..f}
cp a.txt{,.bak}
mkdir /data/{1,2}/data -p
高级命令
# find 查找文件 -type 指定文件类型 f 文件 d 目录 -mtime 安装文件的修改时间查找文件 +n第n天以前 -n第n天内 n第n天 -name 按照文件的名称查找文件 # find . -type f -name '*.txt' 可以用通配符 # 可以取反 find . -type f ! -name '*.txt' # exec用法 find . -type f -name 'file.txt' -exec mv {} /tmp/ \; {} 代表前面找出的文件,代表file.txt \; 有一些特殊的含义,不光linux,uninx都可以这样用,是一种格式 ------------------------------------------------------ # xargs用法 find . -type f -name 'file.txt'|xargs -i mv {} /tmp/ # 其他方法 mv 'find . -type f -name "file.txt"' /tmp/ xargs # xargs 从标准输入(管道或输入重定向)获取数据,并将数据转化成命令行的参数 # 输入重定向 xargs < file.txt 将多行内容转变为一行 -n 参数,指定每个命令行最多的参数个数 xargs -n < file.txt -i 参数,把前面找的文件名与{}关联起来,如果不用-i是无法关联的 find . -type f -name 'file.txt'|xargs -i mv {} /tmp/ -I 参数,同-i,比-i多使用() find . -type f -name 'file.txt'|xargs -I mv() /tmp/ ------------------------------------------------------- # date 命令 # 输出当前时间 date +"%Y-%m-%d %H:%M:%S" # 2018-06-08 14:05:08 -d<字符串>:显示字符串所指的日期与时间。字符串前后必须加上双引号; date -d "1 day ago" +"%Y-%m-%d" 2018-06-07 ago是昨天 date -d "1 day" +"%Y-%m-%d" 2018-06-09 不加参数是明天 以下使用数字表示前后多少天的加减 date +%Y%m%d #显示前天年月日 date -d "+1 day" +%F #显示前一天的日期 %F就是%Y-%m-%d date -d "-1 day" +%F #显示后一天的日期 date -d "-1 month" +F #显示上一月的日期 date -d "+1 month" +F #显示下一月的日期 date -d "-1 year" +F #显示前一年的日期 date -d "+1 year" +F #显示下一年的日期 # 设置时间 -s<字符串>:根据字符串来设置日期与时间。字符串前后必须加上双引号; date -s 01:01:01 #设置具体时间,不会对日期做更改 date -s "01:01:01 2012-05-23" #这样可以设置全部时间 date -s "01:01:01 20120523" #这样可以设置全部时间 date -s "2012-05-23 01:01:01" #这样可以设置全部时间 date -s "20120523 01:01:01" #这样可以设置全部时间 ------------------------------------------------------- # ln 命令 ln 源文件 目标文件 创建硬链接 ln -s 源文件 目标文件 创建链接 # readlink 查看软链接的源文件是什么 ------------------------------------------------------- # rename 重命名 [root@Poppy joker]# touch a.txt [root@Poppy joker]# rename "txt" "jpg" a.txt [root@Poppy joker]# ls a.jpg ------------------------------------------------------- # ls --time-style ls -l --time-style=long-iso 时间格式化的标准 [root@Poppy joker]# ls -l --time-style=long-iso total 736 drwxr-xr-x 3 rsync rsync 4096 2018-06-20 15:19 gameserver1 [root@Poppy joker]# ls -lhi --time-style=long-iso total 736K 1703938 drwxr-xr-x 3 rsync rsync 4.0K 2018-06-20 15:19 gameserver1 ------------------------------------------------------- # basename 只保留最后以/为分隔符的最后一段,无论你是目录还是文件 [root@Poppy joker]# basename /joker/gameserver1 gameserver1 # dirname 只保留最后以/为分隔符的第一段,无论你是目录还是文件 [root@Poppy joker]# dirname /joker/gameserver1 /joker ------------------------------------------------------- # file 查看文件类型 [root@Poppy joker]# file a a: ASCII text [root@Poppy joker]# file /bin/ls /bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=3d705971a4c4544545cb78fd890d27bf792af6d4, stripped [root@Poppy joker]# file /var/log/wtmp /var/log/wtmp: data ------------------------------------------------------- # tree 显示目录结构 [root@Poppy joker]# tree -Ld 1 /joker /joker ├── gameserver1 ├── gameserver2 ├── scripts └── tools directories -L layer层数, -d目录 ------------------------------------------------------- # stat 查看文件信息 [root@Poppy ~]# stat /etc/hosts File: ‘/etc/hosts’ Size: 204 Blocks: 8 IO Block: 4096 regular file Device: fd01h/64769d Inode: 1183348 Links: 1 Access: (0644/-rw-r--r--) Uid: ( 0/ root) Gid: ( 0/ root) Access: 2018-06-19 14:10:17.421425118 +0800 Modify: 2018-06-14 14:05:07.713140443 +0800 Change: 2018-06-14 14:05:07.716140534 +0800 Birth: - ------------------------------------------------------- # uname -m 64 还是 32 ------------------------------------------------------- # md5sum 计算和校验文件的md5值 硬链接的md5一样,软连接不一样 [root@Poppy joker]# touch a [root@Poppy joker]# md5sum a d41d8cd98f00b204e9800998ecf8427e a [root@Poppy joker]# md5sum a > md.log [root@Poppy joker]# md5sum -c md.log a: OK [root@Poppy joker]# echo "11" >> a [root@Poppy joker]# md5sum -c md.log a: FAILED md5sum: WARNING: 1 computed checksum did NOT match
-------------------------------------------------------
# split 想用数字后缀可使用-d参数,同时可以使用-a length来指定后缀的长度
split -b 10k date.file -d -a 3 split_file
# 生成文件
dd if=/dev/zero of=test bs=1M count=1000
正则表达式
处理大量的字符串而定义的一套规则和方法 alias grep='grep --color=auto' 让匹配的内容显示颜色 ^$表示空行 grep -n / -v / -i / -o只显示匹配到的字符 * 重复0个或多个前面的一个字符 .* 匹配所有字符 ^.*以任意多个字符开头,.*$以任意多个字符结尾 [abc] 匹配字符集合内的任意一个字符[a-zA-Z],[0-9] [^abc] 匹配不包含^后的任意一个字符的内容 a\{n,m\} 前一个字符a,重复n到m次 a\{n,\} 前一个字符a,重复至少n次 a\{n\} 前一个字符a,重复n次 a\{,m\} 前一额字符a,最多m次 egrep(grep -E)或sed -r过滤一般特殊字符可以不转义(不用\) -E扩展 + 表示重复“一个或一个以上”前面的字符 ?表示“0个或1个”前面的字符 | 表示同时过滤多个,或 () 分组过滤,向后引用
grep -E "g(la|oo)d" joker.log 小括号前面不需要加\转义
获取ip地址 [root@Poppy ~]# ifconfig eth0 eth0: flags=4163<UP,BROADCAST,RUNNING,MULTICAST> mtu 1500 inet 172.17.184.251 netmask 255.255.240.0 broadcast 172.17.191.255 ether 00:16:3e:10:d0:eb txqueuelen 1000 (Ethernet) RX packets 1363874 bytes 622369572 (593.5 MiB) RX errors 0 dropped 0 overruns 0 frame 0 TX packets 663050 bytes 98323781 (93.7 MiB) TX errors 0 dropped 0 overruns 0 carrier 0 collisions 0 [root@Poppy ~]# ifconfig eth0|sed -n '2p'|sed 's#^.* ##g' 172.17.191.255 [root@Poppy ~]# ifconfig eth0|sed -n '2s#^.* ##g'p 172.17.191.255 分组过滤匹配ip [root@Poppy ~]# ifconfig eth0|sed -nr 's#^.*inet (.*) netmask.*$#\1#g'p 172.17.184.251 对调字段 [root@Poppy ~]# cat /etc/passwd root:x:0:0:root:/root:/bin/bash [root@Poppy ~]# sed -nr 's#([^:]+)(:.*:)(/.*$)#\3\2\1#g'p /etc/passwd /bin/bash:x:0:0:root:/root:root
sed,awk,grep
#myname=joker,myname="joker's",myname='"$joker"is dog',myname='joker is',myname=`cat $myname` #ls test1 # test2 将忽视 test1 test2,ls test\*=ls test*脱意字符 #!$上一个命令最后出现的 #cut -d " 分隔符",cut -c字节 -f第几个区块,cut -d ":" -f1-3&1,3 | cut -c1-3&1,3 #sort -t分隔符,-n纯数字排序,-r反向排序,-u去除重复.uniq -c统计重复的行 -d 显示重复的行 #echo 123456 |tee &-a 1.txt,重定向,加a追加重定向,不加a就是清空并且将123456写入 #tr -d删除某个字符 -s压缩重复的字符并不是去掉,tr '[a-z]' '[A-Z]'替换,不修改文件 cat test.txt | tr -s 'o' #split -b 500 /etc/passwd passwd切割文档,单位字节byte,分割后文件名字为passwdaa,passwdab....,split -l 10 已10行来分割 #执行多条命令,加;分号。&&前面错误就不执行了。 #sleep 100 & 后台运行,fg 加任务号可以调用到前台,ctrl+z可以暂停,bg加任务号再次进入后台运行,可通过jobs查看任务号 #2>错误重定向,2>>错误追加重定向。不显示出来 & > /dev/null 正确错误都不显示 #[]中括号为字符符合,代表中间字符任意一个, #grep -i忽略大小写 -v打印不符合 ,^行头,$行尾 ^$空行, .表示任意一个字符 *表示多个字符。 #grep -v '^[a-zA-Z]' 1.txt = grep '^[^a-zA-Z]' 1.txt [^a-zA-Z] 表示非a-zA-Z #grep -n '^\broot\b' test.txt 锁定单词 ,grep -n '\<rooot' test.txt 匹配开头包含root的行显示出来,\>表示结尾 #egrep 'o+'/'oo+' 1.txt,筛选一个或以上,俩个或以上。egrep 'o?' 1.txt,筛选0个,egrep 'oo?' 1.txt,筛选 一个 #egrep '111|aaa' 1.txt,筛选111或aaa的行,egrep '(oo)+'表示一个oo或者多个oo。 #sed -n '4'p 1.txt打印第4行,sed -n '1,$'p 1.txt,打印整个文件。sed -e '1'p -e '/111/'p -n 1.txt,-e多个行为G #sed -n '/root/'p 1.txt 打印包含root的行,sed -n '/^1/'p 1.txt ,打印出开头1的行。^ $ . *也可以用。 #sed '1'd 1.txt,删除1行, sed '3,5'd 1.txt 删除3 5 行,sed '/root/'d 1.txt 删除带有root的行 sed '/^$/'d a.txt 删除空行 #sed '1,2s/ot/to/g'p 1.txt 1,2行ot替换成to,这里/也可以用# @来表示 #sed 's/[0-9]//g' 1.txt 删除所有数字或者字母 [a-zA-Z0-9] #sed 's/[a-zA-Z0-9:/]//g' 1.txt 相当于替换为空 #sed '/匹配项/s/A/B/g' filename sed -n '/operator:\/rooot:/s/rooot/root/g'p 1.txt 匹配/operator:\/rooot:行,将rooot替换成root #sed 's/\(rot\)\(.*\)\(bash\)/\3\2\1/g' 1.txt 将rot bash 调序 #sed 's/^.*$/123&/g' 1.txt 在行首添加123 . sed 's/^.*$/&321/g' 1.txt 在行尾添加321 #head -n2 test.txt | awk -F ':' '{print $1}' 1到2行,打印第一字符段 #head -n2 test.txt |awk -F':' '{print $1"d"$2"d"$3"d"}' 1到2行,打印2 3段,并且加入自定义的内容 #awk '/root/' test.txt 匹配字符或者字符串 #awk -F ":" '$1~/root/' test.txt 匹配开头到/root/都有的话显示出来 #awk -F ":" '$3=="0"' test.txt 匹配第三段数值等于0 #awk -F ":" '$3>"5" && $3<"6"' test.txt &&/|| 匹配第三段大5小于7的行 #awk -F ":" '{print NF}' test.txt 一共多少段 awk -F ":" '{print $NF}' test.txt 打印最后一段 NF多少段。NR多少行 #awk -F ":" 'NR>10 && $3="0"' test.txt #awk -F ":" '$1="root"' test.txt 将第一段修改成root #head -n 2 test.txt |awk -F ":" '{$7=$3+$4; print $3,$4,$7}' 可以在awk做一些运算 #awk -F ":" '{(tot+=$3)};END {print tot}' test.txt 计算某个字段的总和 #awk -F ":" '{if ($1=="root") print $0}' test.txt awk与if的结合 #uid=`sed -n "$i"p /etc/passwd` sehll脚本中sed引入变量变成双引号就可以了
shell脚本开发
# 一 什么是shell script 1、什么是shell shell是一个在操作系统之上的软件,linux登录后默认就进入这个软件 shell是一个命令的解释器,能解析用户所输入的命令 (ls cp rm pwd 等等) shell拥有自己内建的命令集 2、bash bash(Bourne Again shell )是shell的扩展,并且完全兼容shell(类似vim与vi的关系) 3、什么是shell script Shell脚本是利用 shell 的功能所写的一个程序,将一些shell的语法与命令(含外部命令)写在里面, 搭配管道与数据重定向等功能,以达到我们所想要的功能。 4、解释型语言与编译型语言 shell脚本是解释型语言,执行时是逐条解释你写的程序来运行。(python) 而编译型语言需要先通过编译器进行编译,把代码翻译成机器能识别的指令,然后再运行(C++) # 二 第一个shell script 第一步:使用文本编辑器(vim)来创建文本文件(一般以.sh结尾) 第一行必须包括shell声明:#! #!/bin/bash (告诉系统执行的时候要调用什么解释器) #开头的是shell的注释 第二步:输入命令 echo “hello world” 第三步:给文件添加执行权限 chmod 755 hello.sh 第四步 运行脚本 第一种方式:指定脚本的绝对或相对路径来运行 ./hello.sh 第二种方式:直接运行解释器,将脚本作为参数运行 sh hello.sh 常见问题 -bash: ./hello.sh: Permission denied 没有赋予执行权限 # 三 shell变量 赋值 1、变量 变量以字母或者下划线开头,后面接任意长度的字母、数字和下划线,如 var=linux 变量的引用需要在前面加$符号 ,如echo “$var” 如果变量的值中间有空格,需要用双引号引起来,如var=“hello world” 单引号、双引号的区别? 2、特殊变量 位置参数 $n ,n为数字,$0为命令本身,$1-$9是命令行第一到第9个参数 $* 代表所有参数 $# 代表参数的个数 $? 代表上一个命令的返回状态 3、命令替换和赋值 命令替换的格式: $(cmd) 或者 `cmd` # ``为tab上的反引号 在执行命令的时候,会先将$(cmd) 或者 `cmd` 里的命令先执行一遍,再将结果返回到原来的命令中 var=$(uname -a) echo $var 命令替换和管道的区别? 命令替换是将一个命令的输出作为另外一个命令的参数,而管道是将命令的输出作为下一个命令的标准输入 如 date +%Y|touch touch $(date +%Y) 4、算数运算和赋值 首先,echo 1+2,没有输出3。因为shell需要特殊的格式来进行算数运算 方式一 ((i=$j+$k)) 方式二 let i=$j+$k 赋值 var=$(($i+$j)) echo $var 5、多个命令分隔符 分号(;)是shell的命令分隔符, 让同一行的命令能够顺序执行。如echo 1 ;echo 2 # 四 if语句和test命令 1、if 判断 在shell中if条件判断语句和我们的C、python等语言不同,shell的if语句条件必须用[ ]括起来,另外[ ]里外都需要用空格与周围隔开(例如[ a == b ]),否则会报错 if基本语法 if [ 表达式 ];then ;fi 或 if command;then ;fi 其中[ 表达式 ] 等同于test命令,man test 2、条件测试类型 整数测试 -eq 测试两个整数是否相等 -ne 测试两个整数是否不等 -gt 测试一个数是否大于另一个数 -lt 测试一个数是否小于另一个数 -ge 大于或等于 -le 小于或等于 字符串测试(两边要有空格) == 等于 != 不等 > 大于 < 小于 -z string 测试指定字符是否为空,空着真,非空为假 -n string 测试指定字符串是否为不空,空为假 非空为真 文件测试 -e FILE 测试文件是否存在 -f file 测试文件是否为普通文件 -d file 测试指定路径是否为目录 -r file 测试文件对当前用户是否可读 -w file 测试文件对当前用户是否可写 -x file 测试文件对当前用户是都可执行 组合测试 -a: and -o: or !: 非 # 五 shell中&&和||的使用方法 1、&&运算符: command1 && command2 &&左边的命令(命令1)返回真(即返回0,成功被执行)后,&&右边的命令(命令2)才能够被执行;命令之间使用 && 连接,实现逻辑与的功能。 如test -f /var/log/messages && echo ok 2、||运算符: command1 || command2 ||则与&&相反。如果||左边的命令未执行成功,那么||右边的命令就会执行 如 test -f 123 || echo error # 六 循环语法 1、for循环 for arg in [list] do command… done list列表可以是空格分割的字符串,也可以是命令替换返回的结果 如 for v in /etc/sudoers /etc/resolv.conf do ls -l $v done 2、while循环 while [condition] do command... done 输入名字 打印一个随机数字 while read -p "please input a name" name; do echo $name $RANDOM; done # 七 shell函数 格式 function name () { } shell函数可以带function关键字,也可以不带 shell函数内可以加return返回值,也可以不带,如果不带就以最后一条命令运行结果,作为返回值。 例如 demoFun(){ echo "这是我的第一个 shell 函数!" } echo "-----函数开始执行-----" demoFun echo "-----函数执行完毕-----"
function joker (){
echo "one shell" $1 $2
return 1
}
var=joker 1 2 # echo $var 1
# 八 数组 1、数组定义 [root@bastion-IDC ~]# a=(1 2 3 4 5 6 7 8) [root@bastion-IDC ~]# echo $a 一对括号表示是数组,数组元素用“空格”符号分割开。 2、数组读取与赋值 1)得到长度: [root@bastion-IDC ~]# echo ${#a[@]} 8 [root@bastion-IDC ~]# echo ${#a[*]} 8 用${#数组名[@或*]} 可以得到数组长度 2)读取: [root@bastion-IDC ~]# echo ${a[4]} 5 [root@bastion-IDC ~]# echo ${a[*]} 1 2 3 4 5 6 7 8 用${数组名[下标]} 下标是从0开始 下标是:*或者@ 得到整个数组内容 3)赋值: [root@bastion-IDC ~]# a[1]=100 [root@bastion-IDC ~]# echo ${a[*]} 1 100 3 4 5 6 7 8 [root@bastion-IDC ~]# a[5]=140 [root@bastion-IDC ~]# echo ${a[*]} 1 100 3 4 5 140 7 8 直接通过 数组名[下标] 就可以对其进行引用赋值,如果下标不存在,自动添加新一个数组元素 4)删除: 复制代码 [root@bastion-IDC ~]# a=(1 2 3 4 5 6 7 8) [root@bastion-IDC ~]# unset a [root@bastion-IDC ~]# echo ${a[*]} [root@bastion-IDC ~]# a=(1 2 3 4 5 6 7 8) [root@bastion-IDC ~]# unset a[1] [root@bastion-IDC ~]# echo ${a[*]} 1 3 4 5 6 7 8 [root@bastion-IDC ~]# echo ${#a[*]} 7 复制代码 直接通过:unset 数组[下标] 可以清除相应的元素,不带下标,清除整个数据。 3、特殊使用 1)分片: 复制代码 [root@bastion-IDC ~]# a=(1 2 3 4 5 6 7 8) [root@bastion-IDC ~]# echo ${a[@]:0:3} 1 2 3 [root@bastion-IDC ~]# echo ${a[@]:1:4} 2 3 4 5 [root@bastion-IDC ~]# c=(${a[@]:1:4}) [root@bastion-IDC ~]# echo ${#c[@]} 4 [root@bastion-IDC ~]# echo ${c[*]} 2 3 4 5 复制代码 直接通过 ${数组名[@或*]:起始位置:长度} 切片原先数组,返回是字符串,中间用“空格”分开,因此如果加上”()”,将得到切片数组,上面例子:c 就是一个新数据。 2)替换: 复制代码 [root@bastion-IDC ~]# a=(1 2 3 4 5 6 7 8) [root@bastion-IDC ~]# echo ${a[@]/3/100} 1 2 100 4 5 6 7 8 [root@bastion-IDC ~]# echo ${a[@]} 1 2 3 4 5 6 7 8 [root@bastion-IDC ~]# a=(${a[@]/3/100}) [root@bastion-IDC ~]# echo ${a[@]} 1 2 100 4 5 6 7 8 复制代码 调用方法是:${数组名[@或*]/查找字符/替换字符} 该操作不会改变原先数组内容,如果需要修改,可以看上面例子,重新定义数据。 # 九 颜色处理 echo -e "\033[31m 红色字 \033[0m" echo -e "\033[32m 绿色字 \033[0m" echo -e "\033[33m 黄色字 \033[0m"