Linux Shell笔记(1)

Linux中的Shell脚本源自用户与Linux的交互模式——命令行。在Linux命令行中用户可以进行简单的文件、进程、网络、系统配置等操作,一旦在Linux中命令行操作变得重复且繁琐时,系统内部的shell脚本语言就派上大用场了。

本人此系列的博客里主要讲述本人在实际情况里学习与运用Linux Shell脚本语言的历程。
(以下的内容均为实用性高的shell用法,冷门的shell命令用法本人不学,不提)

命令概述

1. echo
echo命令的作用同C语言中的printf函数类似,即输出一段字符串到标准输出,以下便是本人在学习过程中常用到的该命令的用法:

  • 打印输出字符串
    命令格式与执行结果:
[shallwing@centos ~]$ echo "csdn     csdn"
csdn     csdn
[shallwing@centos ~]$ echo csdn     csdn
csdn csdn
[shallwing@centos ~]$ echo "csdn\n"
csdn\n
[shallwing@centos ~]$ echo csdn\n 
csdnn

上述例子说明了字符串加引号和不加引号的区别,加了引号的字符串,系统默认将字符串的所有内容全部输出,保留其中的空格类字符和字符’\’。不加空格时,字符串中的‘\’字符将会被删除,系统仍然会输出字符串中的空格,但是连续的空格内容将会被删除,只保留上面俩字母之间的一个空格。从上面的例子可以总结一个经验:无论字符串的结构如何,想要将字符串的内容完整输出,必须加上引号!

echo 的选项:-e -E -n
先看例子:

[shallwing@centos ~]$ echo "csdn\ncsdn"
csdn\ncsdn
[shallwing@centos ~]$ echo -E "csdn\ncsdn"
csdn\ncsdn
[shallwing@centos ~]$ echo -e "csdn\ncsdn"
csdn
csdn
[shallwing@centos ~]$ echo -e -n "csdn\ncsdn"
csdn
csdn[shallwing@centos ~]$

echo命令中默认的选项是-E选项,其含义是不识别与输出字符串中所有的转义字符。当字符串里面有转义字符需要输出时,就需要加上-e选项,来提醒系统在输出字符串的时候注意转义字符的输出字符串完整输出之后,会总动输出一个换行符,这是系统默认的操作,当不需要输出那个换行符时,需要加上-n选项,此时系统输出完整个字符串之后就不会输出换行符了。

echo 输出重定向
当需要把某条命令执行的结果输出重定向到一个文件或/dev/null(无底黑洞,可简单地认为输出到这个路径里面的内容是自动被系统删除的,且输出内容不可见)时,可使用下列格式的命令:

[shallwing@centos ~]$ ping www.csdn.net -c 5 > file 
[shallwing@centos ~]$ cat file 
PING e42gk2h6qtfreyimlrlxbf8pxgfubgjc.yundunwaf1.com (39.96.252.213) 56(84) bytes of data.
64 bytes from 39.96.252.213 (39.96.252.213): icmp_seq=1 ttl=128 time=31.3 ms
64 bytes from 39.96.252.213 (39.96.252.213): icmp_seq=2 ttl=128 time=30.9 ms
64 bytes from 39.96.252.213 (39.96.252.213): icmp_seq=3 ttl=128 time=34.5 ms
64 bytes from 39.96.252.213 (39.96.252.213): icmp_seq=5 ttl=128 time=30.5 ms

--- e42gk2h6qtfreyimlrlxbf8pxgfubgjc.yundunwaf1.com ping statistics ---
5 packets transmitted, 4 received, 20% packet loss, time 4016ms
rtt min/avg/max/mdev = 30.573/31.859/34.554/1.579 ms

上述命令的含义为:基于ICMP协议,向本平台所在的服务器发送5个PING报文,并且把服务器响应之后的ICMP应答报文的内容重定向输出到本路径下的文件file中,读取文件file,可以发现ICMP应答的信息已经成功写入。此种操作主要运用在长文本文件的截取与处理中。

2. Shell中的变量
Shell中也可以自己定义变量,例如:

[shallwing@centos ~]$ var1="This is CSDN"
[shallwing@centos ~]$ echo var1
var1
[shallwing@centos ~]$ echo $var1
This is CSDN
[shallwing@centos ~]$ var2=`uname`
[shallwing@centos ~]$ echo $var2
Linux

上述的例子里定义了两个变量var1与var2,shell变量的命名规则与C语言中变量的命名规则是一样的,所有shell变量都无需像C中一样指定类型,定义变量直接以【变量名】=【变量值】的格式在shell脚本文件里面书写即可,变量的类型是通过变量值后面的一些关键字或修饰符予以确定,其中字符串类型是shell变量的缺省类型,即系统默认无修饰关键字的变量为字符串。

上述例子里面,var1就是一个字符串类型的变量,而var2是“uname”这条命令执行结果所形成的字符串,两者虽都是字符串,但含义是有差别的。

当需要得到一条命令执行结果所形成的字符串时,应该在将此条命令用双`号(ASCII码第96号的字符)括起,表示此变量是此命令执行的结果,例如要获取当前路径并将此结果赋值给var3时,可以这样写:

[shallwing@centos ~]$ var3=`pwd`

当需要引用此变量的值时,应该在变量名前面加上"$"符号,这样才算引用了该变量的值,而不是引用一个字符串。上面的例子里面,“echo var2”表示输出的字符串“var2”,echo $var2才表示输出var2的值,Linux环境中还有着许多的系统变量,我们通常也是以此形式来查看系统变量的值,例如:

[shallwing@centos ~]$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/local/sbin:/usr/sbin:/home/shallwing/.local/bin:/home/shallwing/bin

这里的PATH变量,就是系统的默认路径,所有的Linux命令系统都是在这些路径里面进行查找。

3. 字符串的截取与连接

字符串的连接
以下面例子进行讲述:

[shallwing@centos ~]$ url="https://www.csdn.net/"
[shallwing@centos ~]$ name="Donald_Shallwing"
[shallwing@centos ~]$ url=${url}${name}
[shallwing@centos ~]$ echo $url 
https://www.csdn.net/Donald_Shallwing

shell中字符串的链接其实很简单。当需要进行字符串的连接时,一个字符串便成为了一个整体,此时,使用${str1}${str2}的形式便可以进行字符串的连接,把各个字符串按序排列并写成此种形式后,再将其赋给一个变量,打印这个变量后,于是出现了上面的效果。

字符串的截取
先看下面的一个案例:

[shallwing@centos ~]$ link="https://www.csdn.net/nav/career"

上面已经定义了一个字符串link,字符串的内容是本平台一个栏目的网页链接。现在,我们需要给出一个解决方案,就是从这个字符串里面截取本平台的域名(即“https://www.csdn.net”)

仔细观察可以发现,要从link变量中截取得到本平台域名,将域名后面的路径名“/nav/career”去除即可,此操作可以通过下面的方法实现:

[shallwing@centos ~]$ domain_name=${link%%/n*}
[shallwing@centos ~]$ echo $domain_name       
https://www.csdn.net

以上是在使用运算符的情况下对部分字符串进行删除而达到截取的效果。“%%”是删除运算符,删除右边的字符段。上面的例子表示截取从字符串最右边数起,与字符串“/n”右端相匹配的字符段(即“/nav/career”,表示“/n”所有子串的意思),如果实际的操作中要删除左边字符,则应该使用运算符“##”,此时的通配符应该写在子串的左边,即“*/n”,表示左端相匹配的字符段。

如果要从上面的变量link中截取此栏目在服务器里的路径("/nav/career"),此时用cut命令最方便:

[shallwing@centos ~]$ echo $link
https://www.csdn.net/nav/career
[shallwing@centos ~]$ name1=`echo $link | cut -d"/" -f4`
[shallwing@centos ~]$ name2=`echo $link | cut -d"/" -f5` 
[shallwing@centos ~]$ echo "/"${name1}"/"${name2}
/nav/career

cut中常用的选项便是-d了,这个选项表示用字符串中的某些特定字符进行分割截断,上面的link变量中,最好的分隔符莫过于“/”了。后面的“-f4”选项表示分割之后取第四段的字符串,即“nav”,当得到另一段字符串“career”之后,把两者再次通过“/”连接在一起后,便得到了最终的字符串“/nav/career”
同理,字符串“www.csdn.net”的也可以这样:

[shallwing@centos ~]$ link="https://www.csdn.net/nav/career"
[shallwing@centos ~]$ platform=`echo $link | cut -d"/" -f3`
[shallwing@centos ~]$ echo $platform
www.csdn.net

实战运用

每一台Linux的主机在连接到互联网之后都会得到一个IP地址。在RedHat系列的Linux主机中,以发行版本为CentOS的主机为例,查看网络设备的命令如下:

[shallwing@centos ~]$ ip a 
1: lo: <LOOPBACK,UP,LOWER_UP> mtu 65536 qdisc noqueue state UNKNOWN group default qlen 1000
    link/loopback 00:00:00:00:00:00 brd 00:00:00:00:00:00
    inet 127.0.0.1/8 scope host lo
       valid_lft forever preferred_lft forever
    inet6 ::1/128 scope host 
       valid_lft forever preferred_lft forever
2: ens33: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:92:23:53 brd ff:ff:ff:ff:ff:ff
    inet 192.168.172.136/24 brd 192.168.172.255 scope global noprefixroute dynamic ens33
       valid_lft 1390sec preferred_lft 1390sec
    inet6 fe80::3eac:14a6:af:f441/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever
3: ens34: <BROADCAST,MULTICAST,UP,LOWER_UP> mtu 1500 qdisc pfifo_fast state UP group default qlen 1000
    link/ether 00:0c:29:92:23:5d brd ff:ff:ff:ff:ff:ff
    inet 192.168.152.128/24 brd 192.168.152.255 scope global noprefixroute dynamic ens34
       valid_lft 1389sec preferred_lft 1389sec
    inet6 fe80::80ec:31c3:314c:8a94/64 scope link noprefixroute 
       valid_lft forever preferred_lft forever

以上可以说明,该主机具有三个网卡,分别为lo、ens33、ens34,都分别存在自己的IP地址,下面我们将要解决的,就是通过写shell脚本并执行的方式读出三个网卡的IP地址。

  • 基本解决方案
    可以发现,写有IP地址的那一行,都具有“scope”之类的字符串,我们可以以此为查询线索,用grep命令来查找到IP地址所在的行,锁定对应的行之后,我们就可以用本博客中讲到的字符串的截取方法,来截取得到IP地址对应的字符串。
  • 源码
#!/bin/bash
#File name:inet.sh

lo=`ip a | grep lo | grep scope`
ens33=`ip a | grep ens33 | grep scope`
ens34=`ip a | grep ens34 | grep scope`

lo=${lo%%" scope"*}
ens33=${ens33%%" brd"*}
ens34=${ens34%%" brd"*}

lo=${lo##*"inet"}
ens33=${ens33##*"inet"}
ens34=${ens34##*"inet"}

echo "lo:"
echo $lo

echo "ens33:"
echo $ens33

echo "ens34:"
echo $ens34

#end
  • 执行结果
[shallwing@centos ~]$ bash inet.sh 
lo:
127.0.0.1/8
ens33:
192.168.172.136/24
ens34:
192.168.152.128/24

源码里已经给出了一个shell脚本的基本写法,第一行,基本上是通用的,写上shell解释器在系统内的路径,之后便是shell脚本的执行内容。正文部分,一般是先定义变量,然后再对变量进行操作和打印输出,这一点和C程序的写法大同小异。源码里的grep命令,用于定位一个长文本里面某个单词或词组在全文中所在的行,这个命令也是shell脚本里一个重要的命令。

第一期shell笔记经验基本结束,下次将讲述的是shell中的参数解析与条件判断。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值