命令 | 作用 |
---|---|
dd | 删除(剪切)光标所在整行 |
5dd | 删除(剪切)从光标处开始的 5 行 |
yy | 复制光标所在整行 |
5yy | 复制从光标处开始的 5 行 |
n | 显示搜索命令定位到的下一个字符串 |
N | 显示搜索命令定位到的上一个字符串 |
u | 撤销上一步的操作 |
p | 将之前删除( dd)或复制( yy)过的数据粘贴到光标后面 |
要想切换到末行模式,在命令模式中输入一个冒号就可以了。
命令 | 作用 |
---|---|
保存 | |
退出 | |
! | 强制退出(放弃对文档的修改内容) |
! | 强制保存退出 |
nu | 显示行号 |
nonu | 不显示行号 |
:命令 | 执行该命令 |
:整数 | 跳转到该行 |
/one/two | 将当前光标所在行的第一个 one 替换成 two |
/one/two/g | 将当前光标所在行的所有 one 替换成 two |
:%s/one/two/g | 将全文中的所有 one 替换成 two |
?字符串 | 在文本中从下至上搜索该字符串 |
/字符串 | 在文本中从上至下搜索该字符串 |
注: a、 i、 o 三个键从命令模式切换到输入模式。其中, a 键与 i 键分别是在光标后面一位和光标当前位置切换到输入模式,而 o 键则是在光标的下面再创建一个空行,此时可敲击 a 键进入到编辑器的输入模式。 在编写完之后,想要保存并退出,必须先敲击键盘 Esc 键从输入模式返回命令模式,然后再输入
!切换到末行模式才能完成保存退出操作。第 1 步:首先切换到/etc/sysconfig/network-scripts 目录中(存放着网卡的配置文件)。 第 2 步:使用 Vim 编辑器修改网卡文件 ifcfg-eno16777736,逐项写入下面的配置参数并保存退出。由于每台设备的硬件及架构是不一样的,因此请先使用 ifconfig 命令自行确认各自网卡的默认名称。
设备类型: TYPE=Ethernet 地址分配模式: BOOTPROTO=static 网卡名称: NAME=eno16777736 是否启动: ONBOOT=yes IP 地址: IPADDR=192.168.10.10 子网掩码: NETMASK=255.255.255.0 网关地址: GATEWAY=192.168.10.1 DNS 地址: DNS1=192.168.10.1
第 3 步:重启网络服务并测试网络是否联通。 进入到网卡配置文件所在的目录,然后编辑网卡配置文件,在其中填入下面的信息:
[root@linuxprobe ~]# cd /etc/sysconfig/network-scripts/ [root@linuxprobe network-scripts]# vim ifcfg-eno16777736 TYPE=Ethernet BOOTPROTO=static NAME=eno16777736 ONBOOT=yes IPADDR=192.168.10.10 NETMASK=255.255.255.0 GATEWAY=192.168.10.1 DNS1=192.168.10.1
执行重启网卡设备的命令(在正常情况下不会有提示信息),然后通过 ping 命令测试网络能否 联通。由于在 Linux 系统中 ping 命令不会自动终止,因此需要手动按下 Ctrl-c 键来强行结束进程。
[root@linuxprobe network-scripts]# systemctl restart network [root@linuxprobe network-scripts]# ping 192.168.10.10 PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data. 64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.081 ms 64 bytes from 192.168.10.10: icmp_seq=2 ttl=64 time=0.083 ms 64 bytes from 192.168.10.10: icmp_seq=3 ttl=64 time=0.059 ms 64 bytes from 192.168.10.10: icmp_seq=4 ttl=64 time=0.097 ms ^C --- 192.168.10.10 ping statistics --- 4 packets transmitted, 4 received, 0% packet loss, time 2999ms rtt min/avg/max/mdev = 0.059/0.080/0.097/0.013 ms
第 1 步:进入到/etc/yum.repos.d/目录中(因为该目录存放着 Yum 软件仓库的配置文件)。 第 2 步:使用 Vim 编辑器创建一个名为 rhel7.repo 的新配置文件(文件名称可随意,但后缀必须为.repo),逐项写入下面加粗的配置参数并保存退出(不要写后面的中文注释)。 -[rhel-media] : Yum 软件仓库唯一标识符,避免与其他仓库冲突。 -name=linuxprobe: Yum 软件仓库的名称描述,易于识别仓库用处。 -baseurl=file:///media/cdrom:提供的方式包括 FTP( ftp://..)、 HTTP( http://..)、本地( file:///..)。 -enabled=1:设置此源是否可用; 1 为可用, 0 为禁用。 -gpgcheck=1:设置此源是否校验文件; 1 为校验, 0 为不校验。 -gpgkey=file:///media/cdrom/RPM-GPG-KEY-redhat-release:若上面参数开启校验,那么请指定公钥文件地址。 第 3 步:按配置参数的路径挂载光盘,并把光盘挂载信息写入到/etc/fstab 文件中。 第 4 步:使用“yum install httpd -y”命令检查 Yum 软件仓库是否已经可用。进入/etc/yum.repos.d 目录中后创建 Yum 配置文件:
[root@linuxprobe ~]# cd /etc/yum.repos.d/ [root@linuxprobe yum.repos.d]# vim rhel7.repo [rhel7] name=rhel7 baseurl=file:///media/cdrom enabled=1 gpgcheck=0
创建挂载点后进行挂载操作,并设置成开机自动挂载。尝试使用 Yum 软件仓库来安装 Web 服务,出现 Complete!则代表配置正确:
[root@linuxprobe yum.repos.d]# mkdir -p /media/cdrom [root@linuxprobe yum.repos.d]# mount /dev/cdrom /media/cdrom mount: /dev/sr0 is write-protected, mounting read-only [root@linuxprobe yum.repos.d]# vim /etc/fstab /dev/cdrom /media/cdrom iso9660 defaults 0 0 [root@linuxprobe ~]# yum install httpd Loaded plugins: langpacks, product-id, subscription-manager ………………省略部分输出信息……………… Dependencies Resolved =============================================================================== Package Arch Version Repository Size =============================================================================== Installing: httpd x86_64 2.4.6-17.el7 rhel 1.2 M Installing for dependencies: apr x86_64 1.4.8-3.el7 rhel 103 k apr-util x86_64 1.5.2-6.el7 rhel 92 k httpd-tools x86_64 2.4.6-17.el7 rhel 77 k mailcap noarch 2.1.41-2.el7 rhel 31 k Transaction Summary =============================================================================== Install 1 Package (+4 Dependent packages) Total download size: 1.5 M Installed size: 4.3 M Is this ok [y/d/N]: y Downloading packages: \------------------------------------------------------------------------------- ………………省略部分输出信息……………… Complete!
例:
[root@linuxprobe ~]# cd /etc/yum.repos.d [root@linuxprobe yum.repos.d]# ls [root@linuxprobe yum.repos.d]# touch rhel7.repo [root@linuxprobe yum.repos.d]# vi rhel7.repo [base] name= yum repo baseurl=http://mirrors.aliyun.com/centos/7/os/$basearch/ enabled=1 gpgcheck=0 [root@linuxprobe yum.repos.d]# yum update
Shell 脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议将.sh 后缀加上,以表示是一个脚本文件。sh 脚本中一般会有三种不同的元素:
例:
[root@linuxprobe ~]# vim example.sh \#!/bin/bash \#For Example BY linuxprobe.com pwd ls -al
Linux 系统中的 Shell 脚本语言 内设了用于接收参数的变量,变量之间可以使用空格间隔。例如#对应的是总共有几个参数, ?对应的是显示上一次命令的执行返回值**,而2、 $3……则分别对应着第 N 个位置的参数值。
如下为 Shell脚本程序中的参数位置变量,one为2 即第二个位置参数,以此类推。
[root@linuxprobe ~]# ./example.sh one two three four five
如下脚本程序示例,通过引用上面的变量参数来看下真实效果:
[root@linuxprobe ~]# vim example.sh \#!/bin/bash echo "当前脚本名称为$0" echo "总共有$#个参数,分别是$*。 " echo "第 1 个参数为$1,第 5 个为$5。 " [root@linuxprobe ~]# sh example.sh one two three four five six 当前脚本名称为 example.sh 总共有 6 个参数,分别是 one two three four five six。 第 1 个参数为 one,第 5 个为 five。
Shell 脚本中的条件测试语法可以判断表达式是否成立,若条件成立则返回数字 0,否则便返回其他随机数值。
按照测试对象来划分,条件测试语句可以分为 4 种:
1.文件测试即使用指定条件来判断文件是否存在或权限是否满足等情况的运算符, 具体的参数如下:
运算符 | 作用 |
---|---|
-d | 测试文件是否为目录类型 |
-e | 测试文件是否存在 |
-f | 判断是否为一般文件 |
-r | 测试当前用户是否有权限读取 |
-w | 测试当前用户是否有权限写入 |
-x | 测试当前用户是否有权限执行 |
两则使用示例: 下面使用文件测试语句来判断/etc/fstab 是否为一个目录类型的文件, 然后通过 Shell 解释器的内设$?变量显示上一条命令执行后的返回值。如果返回值为 0,则目录存在;如果返回值为非零的值,则意味着目录不存在:
[root@linuxprobe ~]# [ -d /etc/fstab ] [root@linuxprobe ~]# echo $? 1
再使用文件测试语句来判断/etc/fstab 是否为一般文件,如果返回值为 0,则代表文件存在,且为一般文件:
[root@linuxprobe ~]# [ -f /etc/fstab ] [root@linuxprobe ~]# echo $? 0
2.逻辑语句用于对测试结果进行逻辑分析,根据测试结果可实现不同的效果。
在 Shell终端中逻辑“与” 的运算符号是&&, 它表示当前面的命令执行成功后才会执行它后面的命令,因此可以用来判断/dev/cdrom 文件是否存在,若存在则输出 Exist 字样。
[root@linuxprobe ~]# [ -e /dev/cdrom ] && echo "Exist" Exist
除了逻辑“与”外,还有逻辑“或”,它在 Linux 系统中的运算符号为||,表示当前面的命令执行失败后才会执行它后面的命令,因此可以用来结合系统环境变量 USER 来判断当前登录的用户是否为非管理员身份:
[root@linuxprobe ~]# echo $USER root [root@linuxprobe ~]# [ $USER = root ] || echo "user" [root@linuxprobe ~]# su - linuxprobe [linuxprobe@linuxprobe ~]$ [ $USER = root ] || echo "user" user
第三种逻辑语句是“非”,在 Linux 系统中的运算符号是一个叹号(! ),它表示把条件测试中的判断结果取相反值。也就是说,如果原本测试的结果是正确的,则将其变成错误的;原本测试错误的结果则将其变成正确的。我们现在切换到一个普通用户的身份,再判断当前用户是否为一个非管理员的用户。由 于判断结果因为两次否定而变成正确,因此会正常地输出预设信息:
[linuxprobe@linuxprobe ~]$ exit logout [root@linuxprobe root]# [ ! $USER = root ] || echo "administrator" administrator
3.整数比较运算符仅是对数字的操作,不能将数字与字符串、文件等内容一起操作,而且不能想当然地使用日常生活中的等号、大于号、小于号等来判断。
运算符 | 作用 |
---|---|
-eq | 是否等于 |
-ne | 是否不等于 |
-gt | 是否大于 |
-lt | 是否小于 |
-le | 是否等于或小于 |
-ge | 是否大于或等于 |
接下来小试牛刀。我们先测试一下 10 是否大于 10 以及 10 是否等于 10(通过输出的返回值内容来判断,0为false,1为true):
[root@linuxprobe ~]# [ 10 -gt 10 ] [root@linuxprobe ~]# echo $? 1 [root@linuxprobe ~]# [ 10 -eq 10 ] [root@linuxprobe ~]# echo $? 0
4.字符串比较语句用于判断测试字符串是否为空值,或两个字符串是否相同。它经常用来判断某个变量是否未被定义(即内容为空值)。
运算符 | 作用 |
---|---|
= | 比较字符串内容是否相同 |
!= | 比较字符串内容是否不同 |
-z | 判断字符串内容是否为空 |
if 条件测试语句可以让脚本根据实际情况自动执行相应的命令。
if 条件语句的单分支结构由 if、 then、 fi 关键词组成,而且只在条件成立后才执行预设的命令, 相当于口语的“如果……那么……”。 单分支的 if 语句属于最简单的一种条件判断结构,语法格式如下:
if 条件测试操作 then 命令序列 fi
示例:
使用单分支的 if 条件语句来判断/media/cdrom 目录是否存在,若存在就结束条件判断和整个 Shell 脚本,反之则去创建这个目录:
[root@linuxprobe ~]# vim mkcdrom.sh \#!/bin/bash DIR="/media/cdrom" if [ ! -e $DIR ] then mkdir -p $DIR fi
if 条件语句的双分支结构由 if、 then、 else、 fi 关键词组成,它进行一次条件匹配判断,如果与条件匹配,则去执行相应的预设命令;反之则去执行不匹配时的预设命令。 if 条件语句的双分支结构也是一种很简单的判断结构,语法格式如下:
if 条件测试操作 then 命令序列1 else 命令序列2 fi
例:
下面使用双分支的 if 条件语句来验证某台主机是否在线,然后根据返回值的结果,要么显示主机在线信息,要么显示主机不在线信息。这里的脚本主要使用 ping 命令来测试与对方主机的网络联通性,而 Linux 系统中的 ping 命令不像 Windows 一样尝试 4 次就结束,因此为了避免用户等待时间过长,需要通过-c 参数来规定尝试的次数,并使用-i 参数定义每个数据包的发送间隔,以及使用-W 参数定义等待超时时间。
[root@linuxprobe ~]# vim chkhost.sh \#!/bin/bash ping -c 3 -i 0.2 -W 3 $1 &> /dev/null if [ $? -eq 0 ] then echo "Host $1 is On-line." else echo "Host $1 is Off-line." fi
if 条件语句的多分支结构由 if、 then、 else、 elif、 fi 关键词组成,它进行多次条件匹配判断,这多次判断中的任何一项在匹配成功后都会执行相应的预设命令。if 条件语句的多分支结构是工作中最常使用的一种条件判断结构,尽管相对复杂但是更加灵活,语法格式如下:
if 条件测试操作1 then 命令序列1 elif 条件测试操作2 then 命令序列2 else 命令序列3 fi
例:
下面使用多分支的 if 条件语句来判断用户输入的分数在哪个成绩区间内,然后输出如Excellent、 Pass、 Fail 等提示信息。在 Linux 系统中, read 是用来读取用户输入信息的命令,能够把接收到的用户输入信息赋值给后面的指定变量, -p 参数用于向用户显示一定的提示信息。在下面的脚本示例中,只有当用户输入的分数大于等于 85 分且小于等于 100 分,才输出Excellent 字样;若分数不满足该条件(即匹配不成功),则继续判断分数是否大于等于 70 分且小于等于 84 分,如果是,则输出 Pass 字样;若两次都落空(即两次的匹配操作都失败了),则输出 Fail 字样:
[root@linuxprobe ~]# vim chkscore.sh \#!/bin/bash read -p "Enter your score(0-100): " GRADE if [ $GRADE -ge 85 ] && [ $GRADE -le 100 ] ; then echo "$GRADE is Excellent" elif [ $GRADE -ge 70 ] && [ $GRADE -le 84 ] ; then echo "$GRADE is Pass" else echo "$GRADE is Fail" fi [root@linuxprobe ~]# bash chkscore.sh Enter your score(0-100): 88 88 is Excellent [root@linuxprobe ~]# bash chkscore.sh Enter your score(0-100): 80 80 is Pass
下面执行该脚本。当用户输入的分数分别为 30 和 200 时,其结果如下:
[root@linuxprobe ~]# bash chkscore.sh Enter your score(0-100): 30 30 is Fail [root@linuxprobe ~]# bash chkscore.sh Enter your score(0-100): 200 200 is Fail
为什么输入的分数为 200 时, 依然显示 Fail 呢?原因很简单—没有成功匹配脚本中的两个条件判断语句,因此自动执行了最终的兜底策略。
for 循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当要处理的数据有范围时,使用 for 循环语句再适合不过了。语法格式如下:
for 变量名 in 取值列表 do 命令序列 done
while 循环语句通过判断条件测试的真假来决定是否继续执行命令,若条件为真就继续执行,为假就结束循环。语法格式如下:
while 条件测试操作 do 命令序列 done
示例脚本:
结合使用多分支的 if 条件测试语句与 while 条件循环语句,编写一个用来猜测数值大小的脚本 Guess.sh。该脚本使用$RANDOM 变量来调取出一个随机的数值(范围为 0~32767),将这个随机数对 1000 进行取余操作, 并使用 expr 命令取得其结果, 再用这个数值与用户通过 read命令输入的数值进行比较判断。 这个判断语句分为三种情况, 分别是判断用户输入的数值是等于、大于还是小于使用 expr 命令取得的数值。当前,现在这些内容不是重点,我们当前要关注的是while 条件循环语句中的条件测试始终为 true,因此判断语句会无限执行下去,直到用户输入的数值等于 expr 命令取得的数值后,这两者相等之后才运行 exit 0 命令,终止脚本的执行。
内容如下:
\#!/bin/bash PRICE=$(expr $RANDOM % 1000) TIMES=0 echo "商品实际价格为 0-999 之间,猜猜看是多少? " while true do read -p "请输入您猜测的价格数目: " INT let TIMES++ if [ $INT -eq $PRICE ] ; then echo "恭喜您答对了,实际价格是 $PRICE" echo "您总共猜测了 $TIMES 次" exit 0 elif [ $INT -gt $PRICE ] ; then echo "太高了! " else echo "太低了! " fi done
在这个 Guess.sh 脚本中,我们添加了一些交互式的信息,从而使得用户与系统的互动性得以增强。而且每当循环到 let TIMES++命令时都会让 TIMES 变量内的数值加 1,用来统计循环总计执行了多少次。这可以让用户得知总共猜测了多少次之后,才猜对价格。
执行效果如下:
[root@linuxprobe ~]# bash Guess.sh 商品实际价格为 0-999 之间,猜猜看是多少? 请输入您猜测的价格数目: 500 太低了! 请输入您猜测的价格数目: 800 太高了! 请输入您猜测的价格数目: 650 太低了! 请输入您猜测的价格数目: 720 太高了! 请输入您猜测的价格数目: 690 太低了! 请输入您猜测的价格数目: 700 太高了! 请输入您猜测的价格数目: 695 太高了! 请输入您猜测的价格数目: 692 太高了! 请输入您猜测的价格数目: 691 恭喜您答对了,实际价格是 691 您总共猜测了 9 次
case 语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号( *)中所定义的默认命令。语法格式如下:
case 变量值 in 模式 1) 命令序列1 ;; 模式 2) 命令序列2 ;; …… *) 默认命令序列 esac
脚本内容:
[root@linuxprobe ~]# vim Checkkeys.sh \#!/bin/bash read -p "请输入一个字符,并按 Enter 键确认: " KEY case "$KEY" in [a-z]|[A-Z]) echo "您输入的是 字母。 " ;; [0-9]) echo "您输入的是 数字。 " ;; *) echo "您输入的是 空格、功能键或其他控制字符。 " esac
执行效果:
[root@linuxprobe ~]# bash Checkkeys.sh 请输入一个字符,并按 Enter 键确认: 6 您输入的是 数字。 [root@linuxprobe ~]# bash Checkkeys.sh 请输入一个字符,并按 Enter 键确认: p 您输入的是 字母。 [root@linuxprobe ~]# bash Checkkeys.sh 请输入一个字符,并按 Enter 键确认: ^[[15~ 您输入的是 空格、功能键或其他控制字符
一次性计划任务只执行一次,我们可以用 at命令实现这种功能,只需要写成“at 时间”的形式就可以。如果想要查看已设置好但还未执行的一次性计划任务,可以使用“at -l”命令;要想将其删除,可以用“atrm 任务序号”。在使用 at 命令来设置一次性计划任务时,默认采用的是交互式方法。
示例3则:
设置一次性计划任务
[root@linuxprobe ~]# at 23:30 at > systemctl restart httpd at > 此处请同时按下 Ctrl + D 组合键来结束编写计划任务 job 3 at Mon Apr 27 23:30:00 2017 [root@linuxprobe ~]# at -l 3 Mon Apr 27 23:30:00 2017 a root
结合管道符,让at命令接受前面echo命令的输出信息
[root@linuxprobe ~]# echo "systemctl restart httpd" | at 23:30 job 4 at Mon Apr 27 23:30:00 2017 [root@linuxprobe ~]# at -l 3 Mon Apr 27 23:30:00 2017 a root 4 Mon Apr 27 23:30:00 2017 a root
删除某个一次性计划任务
[root@linuxprobe ~]# atrm 3 [root@linuxprobe ~]# at -l 4 Mon Apr 27 23:30:00 2017 a root
周期性地、有规律地执行某些具体的任务,那么 Linux 系统中默认启用的 crond 服务简直再适合不过了。创建、编辑计划任务的命令为“crontab -e”,查看当前计划任务的命令为“crontab -l”,删除某条计划任务的命令为“crontab -r”。另外,如果您是以管理员的身份登录的系统,还可以在 crontab 命令中加上-u 参数来编辑他人的计划任务。 此外crontab任务是以Vim编辑器的形式编辑指令的。
crond命令参数格式:
分钟 | 小时 | 日 | 月 | 星期 | 命令 |
---|---|---|---|---|---|
取值为 0~59 的整数分钟 | 取值为 0~23 的任意整数小时 | 取值为 1~31 的任意整数日 | 取值为 1~12 的任意整数月 | 取值为 0~7 的任意整数,其中 0 与 7 均为星期日星期 | 要执行的命令或程序脚本命令 |
50 | 3 | 2 | 1 | * | run_command |
注:如果有些字段没有设置,则需要使用星号( *)占位。需要说明的是,除了用逗号( ,)来分别表示多个时间段,例如“8,9,12”表示 8 月、 9 月和 12 月。还可以用减号( -)来表示一段连续的时间周期(例如字段“日”的取值为“12-15”,则表示每月的 12~15 日)。以及用除号( /)表示执行任务的间隔时间(例如“/2”表示每隔2 分钟执行一次任务)。
本文作者:Gustav
本文链接:
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!