码迷,mamicode.com
首页 > 系统相关 > 详细

shell入门初级篇

时间:2018-01-11 23:57:53      阅读:444      评论:0      收藏:0      [点我收藏+]

标签:useradd   分支   null   历史   简化   tail   $(())   abc   不显示   

Shell(第一天)

1、解释器

1)shell是解释器的总称,bash只是其中的一种

shell编程 bash脚本

为什么使用bash?

[root@server0 ~]# cat /etc/shells

/bin/sh

/bin/bash

/sbin/nologin

/usr/bin/sh

/usr/bin/bash

/usr/sbin/nologin

/bin/tcsh

/bin/csh

/bin/ksh

2)更改使用某一个解释器 usermod  -s

useradd -s /user/bi/bin/sh

/bin/kshn/ksh  nb

su - nb

2、History

默认历史记录1000条

history -c         //清空自己的历史命令

保存位置:/家目录/.bash_history

配置文件:/etc/profile


3、重定向

    重定向输入  <  将文本输入来源由键盘改为指定文件

    重定向输出  >  将命令行的正常执行输出保存到文件,而不是显示在屏幕

    重定向输出  >> 追加

    重定向错误  2>

    重定向错误  2>>追加

    混合重定向  &> 无论错误正确都覆盖到一个文件中


   [root@server0 ~]# ls /etc/hosts nofile  >log1  2>log2

   #将一个存在的文件和不存在的文件 正确的导入log1,错误的导入log2

 

   收发邮件的两种方法

   echo hello | mail -s hello root

   mail -s hello root < mail.txt  //需要具备一个文件


4、变量

1)变量赋值

  [root@desktop0 ~]# a=11

  [root@desktop0 ~]# b=22

  引用变量$a  $b

  [root@desktop0 ~]# echo $ab  #查看变量

  输出11b

  [root@desktop0 ~]# echo ${a}${b}  #注意括号

  输出1122

2)取消变量:unset 

3)存储类型变量:整数型,浮点型。。。

4)使用类型:环境变量,位置变量,预定义变量,自定义

5)环境变量  配置文件/etc/profile  ~/.bash_profile

   常见的环境变量:PWD、PATH、USER、LOGNAME、UID、

SHELL、HOME、PS1、PS2

  PS1=XX#

6)预定义变量

   $0  //当前所在进程或脚本名

   $*  //所有位置变量的值

   $#  //已加载的位置变量的个数

   $?  //上一条命令的输出状态,0表示正常,1或其他表示异常

   $!   //后台运行的最后一个进程

7)位置变量  在执行脚本时提供的命令行参数

   $1  //第一个变量

   $2  //第二个变量

   env  //查看当前系统的所有变量

   set  //列出所有变量

8)脚本的执行方式:

   当没有加x权限的情况

   sh 脚本文件路径

   source 脚本文件路径

   . 脚本文件路径

9)双引:使用双引号可以界定一个完整的字符串

touch a b     //创建两个文件

touch “a  b” //创建一个文件

     单引:一个完整的字符串,并且屏蔽特殊符号

   a=11

   echo “$a”   //输出a的值

   echo ‘$a’    //输出$a

   echo “ab” == echo ‘ab’

   echo “$a” != echo ‘$a’

     反引:` ` 和$效果一样

     将命令的执行输出作为变量值

     [root@desktop0 ~]# echo $(ls)  #注意括号

    1.sh anaconda-ks.cfg

    [root@desktop0 ~]# echo `ls`

    1.sh anaconda-ks.cfg

    案例:每周五备份/etc/log

    0 4 * * 5  tar -zcf /root/log.tar.gz  /etc/log

    //这样容易造成每周五将原有的数据覆盖

    0 4 * * 5  tar -zcf /root/log.`date +%F`.tar.gz  /etc/log

   //这样就起到了每周五不会覆盖原有的数据

 

10)read 标准输入取值

格式:read [-p 提示信息] 变量名

11)stty -echo //关闭回显

stty echo //恢复

 

    局部变量 a=11

    全局变量 export a=11


Shell(第二天)


1、整数运算工具

1)expr命令

乘法操作应采用 \* 转义,避免被作为Shell通配符;参与运算的整数值与运算操作符之间需要以空格分开,引用变量时必须加$符号

X=1234

expr  $X  +  78

2)使用$[]或$(())表达式  

乘法操作*无需转义,运算符两侧可以无空格;引用变量可省略 $ 符号([]内不需要在变量前加$);计算结果替换表达式本身,可结合echo命令输出。

[root@server0 ~]# x=1234

[root@server0 ~]# echo $[x+78]  #注意和输出变量{}的区分

1312

[root@server0 ~]# echo $x+78

1234+78

3)let命令

expr或$[]、$(())方式只进行运算,并不会改变变量的值;而let命令可以直接对变量值做运算再保存新的值。因此变量X=1234,在执行let运算后的值会变更;另 外,let运算操作并不显示结果,但是可以结合echo命令来查看

[root@server0 ~]# x=1234

[root@server0 ~]# let y=x+22

[root@server0 ~]# echo $y

1256

[root@server0 ~]# x=7

[root@server0 ~]# let x*3   //不能这样写

[root@server0 ~]# echo $x  //值为7

[root@server0 ~]# let x*=3

[root@server0 ~]# echo $x  //值为21

2、小数运算工具

 1)bc交互式运算

先执行bc命令进入交互环境,然后再输入需要计算的表达式。

scale=2  //小数点后面留出来2位数字

 2)bc非交互式运算

将需要运算的表达式通过管道操作交给bc运算

[root@server0 ~]# echo 'scale=4;12.34+5.6789' | bc

18.0189

可以进行数值比较

[root@server0 ~]# echo "2>3" | bc

0   //2是否大于3  输出0错误

[root@server0 ~]# echo "3>2" | bc

1   //2是否大于3  输出1正确

      和$?相反

3、条件测试操作

1)字符串测试

使用“test 表达式”或者[ 表达式 ]都可以,表达式两边至少要留一个空格。

== 比较两个字符串是否相同

[root@server0 ~]# [ $USER == "root" ]   // [ ] 内双引号有无都可以

[root@server0 ~]# [ $USER != "root" ]

[root@server0 ~]# echo $?  //查看上一条命令的结果0为对,非0为错

-z 检查变量的值是否未设置(空值)

[root@server0 ~]# [ -z $dachui ]

[root@server0 ~]# echo $?  

0

2)整数值比较

-eq  -ne  -ge  -le  -gt  -lt

    3)文件状态

 -e -d -f -r -w -x

4)多个条件/操作的逻辑组合

&&   ||  ;

A && B //执行A,当A成功后执行B

A || B  //执行A,当A失败后执行B

A ;B  //执行A ,执行B

 

-x 判断对象是否具有可执行权限(特殊)

[root@svr5 ~]# chmod 644 /1.sh

[root@server0 ~]# chmod -x 1.sh

[root@server0 ~]# ./1.sh

-bash: ./1.sh: 权限不够

//没有x权限root也执行不了

 

  #判断有没有装包,有没有起服务的脚本

#!/bin/bash

rpm -q httpd

if [ $? -ne 0 ];then

yum -y install httpd &> /dev/null

fi

systemctl status httpd

if [ $? -ne 0 ];then

systemctl restart httpd

systemctl status httpd

echo $?

fi

 

Ping -c2 IP   //count ping的次数

Ping -i0.1 IP  //每次间隔的时间


Shell(第三天)

1、echo ;seq

   echo {1..5}

   seq 5     

   都是输出1到5

2、for

   for  i  in 条件

   do

   done

   [root@server0 ~]# for i in {1..5}

   [root@server0 ~]# for i in `seq 5`

3、while

   while 条件  (while : //死循环)

   do

   done

   for 和while 的区别:

   for 循环有限制  while 循环无限制

   [root@server0 ~]# echo $[2**3]

   8

4、case

   case 变量值 in

   模式1)

命令序列1;;

   模式2)

命令序列2;;

   *)

默认命令序列

    esac

    case 简单,功能少  

5、输出颜色

   [root@server0 ~]# echo -e "\033[38mOK\033[0m"

   [root@server0 ~]# echo -e "\033[34mOK\033[0m"

   两次输出的OK的颜色不一样

   -e extend(扩展)

   3x代表字体色

   4x代表背景色

   0x代表样式

   三个可以写在一起

   格式:

   [root@server0 ~]# echo -e "\033[34m:44m:01mOK\033[0m"

 

6、中断

   中断[break,continue,exit]

1)break结束整个循环

   #!/bin/bash

   for i in {1..5}

   do

        [ $i -eq 3 ] && break

        echo $i

   done

   echo OK

   运行结果:1  2  OK

2)continue结束本次循环,跳到下一个循环

   #!/bin/bash

   for i in {1..5}

   do

        [ $i -eq 3 ] && continue

        echo $i

   done

   echo OK

   运行结果:1  2  4  5  OK

3)exit结束脚本

   #!/bin/bash

   for i in {1..5}

   do

        [ $i -eq 3 ] && exit

        echo $i

   done

   echo OK

   运行结果:1  2


Shell(第四天)

1、子串截取的三种用法

1)${var:起始位置:长度}    //从第0位开始

    [root@server0 ~]# X=135556684456

    [root@server0 ~]# echo ${#X}       #获取变量x有多少位

    12

    //统计X的长度

    [root@server0 ~]# echo ${X:0:4}

    1355

  2)expr substr "$var" 起始位置 长度      #该方法起始从1开始

    [root@server0 ~]# expr substr $X 2 4

  3)echo $var | cut -b 起始位置-结束位置   #该方法起始从1开始

    [root@server0 ~]# echo $X | cut -b 4-6


2、字符串的替换

  1)只替换第1个子串

格式:${var/old/new}

[root@server0 ~]# x=123456123456

[root@server0 ~]# echo ${x/3/*}

12*456123456

  2)替换全部子串

格式:${var//old/new}

[root@server0 ~]# echo ${x//3/*}

12*45612*456

(替换不影响x的值,只会影响输出的显示效果)


3、字符串的匹配删除

1)从左向右,最短匹配删除(掐头)

格式:${变量名#*关键词}

删除从左侧第1个字符到最近的关键词的部分,* 作通配符理解:

[root@server0 ~]# x='root:x:0:0:root:/root:/bin/bash'

[root@server0 ~]# echo ${x#*:}  //只删除最近:之前的

x:0:0:root:/root:/bin/bash

2)从左向右,最长匹配删除

[root@server0 ~]# echo ${x##*:}  //删除到:之前所有的

/bin/bash

3)从右向左,最短匹配删除(去尾)

[root@server0 ~]# echo ${x%:*}

root:x:0:0:root:/root

4)从右向左,最长匹配删除

[root@server0 ~]# echo ${x%%:*}

root

 

4、字符串初值的处理

通过${var:-word}判断变量是否存在,决定是否给变量赋初始值

若变量var已存在且非Null,则返回 $var 的值;否则返回字串“word”,原变量var的值不受影响。

[root@server0 ~]# echo ${NB:-123}  //var值不存在

123            

[root@server0 ~]# NB=hehe          //var值存在

[root@server0 ~]# echo ${NB:-123}   //输出原变量的值

hehe

 

5、数组

整体赋值的格式为“数组名=(值1 值2 值3 .. ..)”

[root@server0 ~]# x=(11 22 33 44 55 66)

[root@server0 ~]# echo ${x[0]}

也可以直接为单个数组元素赋值,格式为“数组名[下标]=值”

[root@server0 ~]# x[0]=1

[root@server0 ~]# x[1]=2

[root@server0 ~]# x[2]=3

变量名里不能再包含变量(例如x$i)

查看数组内的内容:

[root@server0 ~]# echo ${x[*]}


6、expect预期交互

expect可以为交互式过程(比如FTP、SSH等登录过程)自动输送预先准备的文本或指令,而无需人工干预。触发的依据是预期会出现的特征提示文本。

yum -y install expect

#!/bin/bash

ip=176.19.1.65

expect << EOF (开头结尾保持一致)

spawn ssh root@$ip                     //spawn对屏幕监控

expect "password" {send "Taren1\n"}     //当屏幕出现password发送密码

expect "#"        {send "touch /root/a.txt\n"}

expect "#"        {send "exit\n"}

EOF

 

3个问题

1)continue的问题

   rm -rf /root/.ssh/known_hosts  //删除第一登录输入保存yes的文件

2)timeout (在远程连接之前等待一会)

man expect   //

set timeout 30  //需要放在远程命令之前

3)最后一行不执行 (上边脚本的expect "#"  {send "exit\n"})

 

7、正则表达式  

(需加双引号)

[]集合查找的是单个字符  

*  :例如 grep “a*” a.txt  //匹配a出现的(a,aa,aaa)

. 匹配任意单个字符,可以取出非空行

.* 代表匹配任意所有  空行,非空行一起取出

a\{2,m\} m可以不写    //匹配a出现2到m次  m无限制

使用 \> 匹配单词右边界

\(\)  abcabcjklkjl

grep ‘(abc)\1(jkl)\2’  a.txt  

最开始和最后一个字母对调

[root@server0 ~]# sed -r 's/^(.)(.*)(.)$/\3\2\1/' 1.txt 

 

8、扩展正则

(简化基本,扩展新的)

? 前面字符出现0或者1次

+  前面字符出现1次或多次

() 整体 (abc)+  abc  abcabc  ...

\b  单词边界,精确过滤

[root@room8pc205 桌面]# grep 'the' 1.txt     #无论the在哪都匹配

hello the world

theapple is great

tast atheorang

[root@room8pc205 桌面]# grep '\bthe' 1.txt  #只匹配the前没有字符

hello the world

theapple is great

[root@room8pc205 桌面]# grep '\bthe\b' 1.txt

hello the world

     扩展正则:简单,兼容性差(并不是)

     基本正则:复杂,兼容性强(所有软件都支持)


Shell(第五天)


1、sed (Stream EDitor) 流式编辑器

  1)非交互

逐行处理

Vim ——硬盘到内存,一次全部显示

Sed ——一行到内存的显示

  2)[root@server0 ~]# sed -n '3p' /etc/passwd   #显示第3行

    不加-n的时候,会在第三行将第三行重复打印  (-n取消自动打印模式空间)

    屏蔽默认输出

-r, --regexp-extended  在脚本中使用扩展正则表达式   -i 直接修改文件内容

    p 显示(print)

    sed -n  '3p;5p' /etc/passwd  #显示第3,第5行 多个指令用分隔符

    sed -n  '3,5p' /etc/passwd   #显示第3到第5行

    sed -n  '3,+5p' /etc/passwd  #显示第3行以及其后的5行

    sed -n  'p;n' /etc/passwd     #输出奇数行,sed自动读行,给n拒绝

    sed -n  'n;p' /etc/passwd     #输出偶数行

    sed -n  '$=' /etc/passwd     #输出文件的行数 wc -l

    sed -n   '/834/!p' /etc/passwd #输出不包括843的行

    根据正则相结合使用(不知道行号)

    [root@server0 ~]# sed -n '/root/p' /etc/passwd   #找出/root并显示出来

    d  删除(delete)  

    sed   '3,5d'    /etc/passwd       #删除3到5行 

    sed  ‘/xml/d’  /etc/passwd   #删除所有包含xml的行(整行删除)

    sed  ‘/xml/!d’  /etc/passwd  #删除不包含xml的行

    s  替换 (substitution)   

    sed ‘s/old/new/’    #文件每行第一个old替换为new

    sed ‘3s/old/new/’   #文件第3行第一个old替换为new

    sed ‘s/old/new/g’  #文件所有old替换为new

    sed ‘s/old/new/3’  #文件每行第三个old替换为new

    sed ‘s/old//g       #文件所有old替换为空

    sed ‘s/old/&s/g’    #文件所有old替换为olds

    sed  's#/bin/bash#/sbin/sh#' #可以使用任何特殊符号作为分隔符必须3个   

    sed  's/\/bin\/bash/\/sbin\/sh/'   #太复杂

    i(insert)  a(append)  c

    sed '2i xxx' 1.txt      #在第2行的前面插入xxx

    sed '2a xxx' 1.txt     #在第2行的后面插入xxx

    sed '2c xxx' 1.txt     #第2行替换为xxx (整行替换)

    sed '2i xx\nyy' 1.txt  #在第2行的前面插入xx和yy

    r w h g

    sed '1r /etc/hostname' 1.txt  #在第一行后加入/etc/hostname的内容

    sed 'w /qq.txt' 1.txt    #在根下另存为qq.txt(不用i已经存了)

    sed '2H;4G' 1.txt      #在第2行复制内容加回车在第4行粘贴第2行内容加回车

    sed '2h;4g' 1.txt      #在第2行复制内容覆盖第4行为第2行的内容


Shell(第六天)


1、awk 数据过滤软件

逐行处理 (grep只能整行)

可以过滤列

格式: awk [选项]  ‘条件{指令}’  文件

条件可以没有,代表所有

也可以没有指令,打印整行

不能同时没有条件和指令

df | awk '/\/$/{print $4}'  #查看以/结尾的第4列的信息  根的磁盘剩余

tailf /var/log/secure  #查看远程登录日志

用途:监控脚本:

登录日志

分区剩余容量:df

内存剩余容量:free

CPU负载大于xx: top ,uptime  

load average: 0.07, 0.21, 0.21

[1,5,15分钟的平均负载]

2、awk 命令,变量

默认使用空格或者tab作为分割符号

-F 指定分隔符(默认空格或者tab)

awk -F: '{print $1}' /etc/passwd #使用:作为分隔符

awk -F: '{print $1,$3,$7}' /etc/passwd #打印多列

打印变量:

print $0   #整行

print $1   #第一列

print $2   #第二列

print NR   #当前行的行号

print NF   #当前行的列号

print $NF  #打印最后一列

打印常量:(字符串需要加引号)

awk '{print "dachui"}' /etc/passwd  #每一行都出来(只有)dachui

awk -F ":" '{print "第"NR"行""第"NF"列"}' /etc/passwd

3、awk处理的时机

awk会逐行处理文本,支持在处理第一行之前做一些准备工作,以及在处理完最后一行之后做一些总结性质的工作。在命令格式上分别体现如下:

     行前处理,BEGIN{ }  #读取文件之前,执行1次

     逐行处理,{ }        #读取文件过程中执行,执行n次

     行后处理,END{ }    #读取文件之后,执行1次

     awk -F: 'BEGIN{print "用户名\tUID\t家目录"} {print $1,$3,$6} END{print "总用户 "NR}' /etc/passwd

     awk 'BEGIN{x=2;y=3.3;print x*y}'  #不加其它选项作为运算使用

     awk变量可以不定义,就直接用(默认0)

     awk 'BEGIN{x=0} /bash$/{x++} END{print x}' /etc/passwd

     awk '/bash$/{x++} END{print x}' /etc/passwd

4、awk处理条件

1)使用正则表达式设置条件

~(模糊)匹配 !~不匹配

awk '/root/' /etc/passwd       #对整行匹配

root:x:0:0:root:/root:/bin/bash

operator:x:11:0:operator:/root:/sbin/nologin

awk  -F: '$1~/root/' /etc/passwd  #匹配第一列是root

root:x:0:0:root:/root:/bin/bash  

awk -F: '$7!~/bash$/' /etc/passwd #匹配第7列不是bash结尾的行

2)使用数值/字符串比较设置条件 (字符串需要引号,精确匹配)

==  !=  >=  <=  >  <

awk -F: '$1=="root"  /etc/passwd  #精确匹配第一列是root的行

3)逻辑测试条件

&&逻辑与

awk -F: '$3>=10 && $3<=20' /etc/passwd

||  逻辑或

awk -F: '$3==0 || $3==1000' /etc/passwd

4)数学运算

+ - * / %  ++  --

seq 200 | awk '$1%7==0 || $1~/7/' #200以内能够整除7并且包含7的


5、awk流程控制

1)if分支结构(双分支、多分支)

找出多少系统用户,多少普通用户

awk -F: '{if ($3>=1000){x++}else{y++}}END{print x,y}' /etc/passwd

找出第一列是M.Tansley并且第六列-1,输出1,6,7列

awk '{if($1=="M.Tansley")$6-=1;print $1,$6,$7}' awk_exe.txt

2)while循环结构

统计词频[文章,日志,文件]

例:统计/etc/passwd中的root出现的次数

[root@svr5 ~]# awk -F [:/] \

'BEGIN{j=0}\

{i=1}{while(i<=NF){if($i~/root/){j++};i++}}\

END{print j}'  /etc/passwd

4

awk -F : ‘{i=1;while(i<=NF){if($i~/root/){j++};i++}}

END{print j}’ /etc/passwd

3)break、continue等其他控制语句


6、awk公式

     ab -c 100 -n 10000  http://172.25.0.11/   #模拟100个人同时访问网站,点击页面1000次。IP后必须写/

     拒绝服务攻击(DOS攻击)

 

例:提取IP地址及访问量

     awk '{A[$1]++}                #统计第一列的IP

     END{for(i in A){print i,A[i]}}'   #对每个IP循环得到每个IP的次数

     /var/log/httpd/access_log  |

     awk '$2>=500{print $1}'       #找出访问次数大于500的IP

     例:写一个进度条脚本

     #!/bin/bash

     jindu(){

     while :

     do

     echo -n '#'

     sleep 0.3

    done

     }

      jindu &

     cp -r  $1  $2

     kill $!


shell入门初级篇

标签:useradd   分支   null   历史   简化   tail   $(())   abc   不显示   

原文地址:http://blog.51cto.com/13452945/2060024

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!