学习笔记1:《Linux就该这么学(第二版)》-命令
学习笔记2:《Linux就该这么学(第二版)》笔记-重定向,命令符和环境变量
Vim编辑器
Vim编辑器的三种模式
- 命令模式:控制光标移动,可对文本进行复制、粘贴、删除和查找等工作
- 末行模式:保存或退出文档,以及设置编辑环境
- 编辑模式:正常的文本录入

每次运行Vim编辑器时默认进入命令模式,此时需要先切换到输入模式后再进行文档编写工作,而每次在编写完文档后需要先返回命令模式,再进去末行模式,进行文档保存或退出工作。
从命令模式切换到输入模式:
a-在光标后面一位切换到输入模式
i-在光标当前位置切换到输入模式
o-在光标下面再创建一个空行,由此输入
命令模式常用命令:
dd:删除光标所在整行
5dd:删除光标处开始的5行
yy:复制光标所在的整行
5yy:复制从光标处开始的5行
n:显示搜索命令定位到的下一个字符串
N:显示搜索命令定位到的上一个字符串
u:撤销上一步操作
p:将之前dd或yy的数据粘贴到光标后
末行模式常用命令
:w 保存
:q 退出
:q! 强制退出(放弃对文档的修改内容)
:wq! 强制保存退出
:set nu 显示行号
:set nonu 不显示行号
:命令 执行该命令
:整数 跳转到该行
:s/one/two:将当前光标所在行的第一个one替换成two
:s/one/two/g:将当前光标所在行的所有one替换成two
:%s/one/two/g:将全文中的所有one替换成two
?字符串:在文本中从下至上搜索该字符串
/字符串:在文本中从上至下搜索该字符串
ping可以检查网络是否连通
[dell@bogon network-scripts]$ ping 10.3.14.254
PING 10.3.14.254 (10.3.14.254) 56(84) bytes of data.
64 bytes from 10.3.14.254: icmp_seq=1 ttl=64 time=0.023 ms
64 bytes from 10.3.14.254: icmp_seq=2 ttl=64 time=0.026 ms
64 bytes from 10.3.14.254: icmp_seq=3 ttl=64 time=0.026 ms
64 bytes from 10.3.14.254: icmp_seq=4 ttl=64 time=0.029 ms
^C
--- 10.3.14.254 ping statistics ---
4 packets transmitted, 4 received, 0% packet loss, time 2999ms
rtt min/avg/max/mdev = 0.023/0.026/0.029/0.002 ms
编写Shell脚本
Shell脚本工作方式:
- 交互式:用户每输入一条命令就立即执行
- 批处理:由用户事先编写好的一个完整的Shell脚本,Shell会一次性执行诸多命令
脚本文件的名称可以任意,但为了避免被误以为是普通文件,建议把.sh后缀加上,以表明这是一个脚本文件
[dell@bogon ~]$ vim example.sh
[dell@bogon ~]$ cat example.sh
#!/bin/bash
#For example by yaya
pwd
ls -al
上述脚本中出现了三种不同的元素
脚本声明(#!):告诉用哪种Shell解释器来执行该脚本
注释信息(#):介绍信息
后面两行就是执行的命令了
执行脚本:
方法一
[dell@bogon ~]$ bash example.sh
/home/dell
总用量 60
drwx------. 21 dell dell 4096 1月 20 19:11 .
drwxr-xr-x. 6 root root 76 1月 20 11:51 ..
-rw-------. 1 dell dell 5090 1月 20 18:40 .bash_history
-rw-r--r--. 1 dell dell 18 10月 31 2018 .bash_logout
方法二
[dell@bogon ~]$ ./example.sh
-bash: ./example.sh: 权限不够
默认会因为权限不足而提示报错信息,因此需要为脚本文本增加执行权限
[dell@bogon ~]$ chmod u+x example.sh
[dell@bogon ~]$ ./example.sh
/home/dell
总用量 60
drwx------. 21 dell dell 4096 1月 20 19:11 .
drwxr-xr-x. 6 root root 76 1月 20 11:51 ..
但上面的脚本程序只能执行一些预先定义好的功能,未免死板了,所以需要让脚本程序能够像之前一样接收用户输入的参数。
Shell脚本语言已经内设了用于接收参数的变量,变量之间可以用空格间隔
#:对应的是总共有几个参数
1、
? 对应上一次命令的执行返回值
[dell@bogon ~]$ vim example.sh
[dell@bogon ~]$ cat example.sh
#!/bin/bash
#For example by yaya
echo "当前脚本名称为$0"
echo "总共有$#个参数,分别为$*"
echo "第1个参数为$1, 第五个参数为$5"
[dell@bogon ~]$ bash example.sh
当前脚本名称为example.sh
总共有0个参数,分别为
第1个参数为, 第五个参数为
[dell@bogon ~]$ sh example.sh one two three four five six
当前脚本名称为example.sh
总共有6个参数,分别为one two three four five six
第1个参数为one, 第五个参数为five
Shell脚本中的条件测试语法可以判断表达式是否成立,若成立则返回数字0,否则返回其他随机的值。
条件测试语句执行格式
[ 条件表达式 ]
注意条件表达式两边均应该有一个空格
按照测试对象来划分,条件测试语句可以分为4种:
- 文件测试语句:判断文件是否存在或权限是否满足等情况的运算符
-d: 测试文件是否为目录类型
-e: 测试文件是否存在
-f: 判断是否为一般文件
-r: 测试当前用户是否有权限read
-w:测试当前用户是否有权限write
-x: 测试当前用于是否有权限excute
[dell@bogon ~]$ [ -d /etc/fstab ]
[dell@bogon ~]$ echo $?
1
(返回值为0-目录存在,返回值非0-目录不存在)
- 逻辑测试语句:用于对测试结果进行逻辑分析,根据测试结果可实现不同的效果。
①在Shell终端中“与”的运算符号是&&,表示当前面的命令执行成功后才会执行它后面的命令。
[dell@bogon ~]$ [ -f /etc/fstab ] && echo "Exist"
Exist
②“或”:||,表示前面的命令执行失败后才会执行它后面的命令
判断当前登录的用户是否为非管理员身份:
[dell@bogon ~]$ [ $USER = root ] || echo "user"
user
③“非”:! 表示把条件测试中的判断结果取相反值。也就是说,如果原本测试的结果是正确的,则将其变成错误的,反之亦然
[root@bogon ~]# [ ! $USER = root ] || echo "administrator"
administrator
- 整数值比较语句(不是平时的> < =)
-eq 是否等于
-ne 是否不等于
-gt 是否大于
-lt 是否小于
-le 是否小于或等于
-ge 是否大于或等于
less equal greater
[root@bogon ~]# free -m
total used free shared buff/cache available
Mem: 257378 31357 12457 259 213563 224898
Swap: 4095 0 4095
[root@bogon ~]# free -m | grep Mem
Mem: 257378 31356 12458 259 213563 224899
[root@bogon ~]# free -m | grep Mem | awk '{print $4}'
12445
[root@bogon ~]# FreeMem=`free -m | grep Mem | awk '{print $4}'`
[root@bogon ~]# echo $FreeMem
12448
[root@bogon ~]# [ $FreeMem -lt 1024 ] && echo "Insufficient Memory"
[root@bogon ~]# [ $FreeMem -lt 1024 ] || echo "Sufficient Memory"
Sufficient Memory
- 字符串比较语句:用于判断测试字符串是否为空值,或两个字符串是否相同。也常用来判断某个变量是否未被定义(即内容为空值)
= 比较字符串是否相同
!= 比较字符串是否不同
-z 判断字符串内容是否为空
[root@bogon ~]# echo $LANG
zh_CN.UTF-8
[root@bogon ~]# [ $LANG != "en.US" ] && echo "Not en.US"
Not en.US
流程控制语句
if条件测试语句
单分支结构
if 条件测试操作
then 命令序列
fi
[dell@bogon ~]$ vim mkcdrom.sh
[dell@bogon ~]$ cat mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
[dell@bogon ~]$ bash mkcdrom.sh
mkdir: 无法创建目录"/media/cdrom": 权限不够
双分支结构
if 条件测试操作
then 命令1
else 命令2
fi
多分支结构
if 条件测试操作1
then 命令1
elif 条件测试操作2
then 命令2
else
命令3
fi
[dell@bogon ~]$ vim chkscore.sh
[dell@bogon ~]$ cat 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
[dell@bogon ~]$ bash chkscore.sh
Enter your score(0-100):200
200 is fail
[dell@bogon ~]$ bash chkscore.sh
Enter your score(0-100):68
68 is fail
read可用于读取用户输入的信息,能把接收到的用户输入信息赋值给后面的指定变量。
-p用于向用户显示一定的提示信息
for循环语句
for循环语句允许脚本一次性读取多个信息,然后逐一对信息进行操作处理,当要处理的数据有范围时,使用for合适
for 变量名 in 取值列表
do
命令序列
done
练习:如何批量创建账户
/dev/null是一个被称作Linux黑洞的文件,把输出信息重定向到这个文件等于删除数据(类似于没有回收功能的垃圾箱),可以让用户的屏幕窗口保持简洁
[root@bogon usermanage]# vim adduser.sh
[root@bogon usermanage]# cat adduser.sh
#!/bin/bash
read -p "Enter the users password : " PASSWD
for UNAME in `cat users.txt`
do
id $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "Already exists"
else
useradd -d /home/user/$UNAME -m $UNAME
echo "$PASSWD" | passwd --stdin $UNAME &> /dev/null
if [ $? -eq 0 ]
then
echo "$UNAME , create success"
else
echo "$UNAME , create failure"
fi
fi
done
[root@bogon usermanage]# bash adduser.sh
Enter the users password : 12345678
test1 , create success
test2 , create success
test3 , create success
[root@bogon usermanage]# bash adduser.sh
Enter the users password : 12345678
Already exists
Already exists
Already exists
[root@bogon usermanage]# tail -3 /etc/passwd
test1:x:1040:1041::/home/user/test1:/bin/bash
test2:x:1041:1042::/home/user/test2:/bin/bash
test3:x:1042:1043::/home/user/test3:/bin/bash
While条件循环语句
是一种让脚本根据某些条件来重复执行命令的语句,它的循环结构往往在执行前并不确定最终执行的次数,完全不同于for循环语句中有目标、有范围的使用场景
while循环语句通过判断条件测试的真假来决定对否继续执行命令,若条件为真就继续执行,为假就结束循环
while 条件测试操作
do
命令
done
[dell@bogon ~]$ vim mkcdrom.sh
[dell@bogon ~]$ cat mkcdrom.sh
#!/bin/bash
DIR="/media/cdrom"
if [ ! -e $DIR ]
then
mkdir -p $DIR
fi
[dell@bogon ~]$ bash mkcdrom.sh
mkdir: 无法创建目录"/media/cdrom": 权限不够
[dell@bogon ~]$ vim chkscore.sh
[dell@bogon ~]$ cat 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
[dell@bogon ~]$ bash chkscore.sh
Enter your score(0-100):90^H^H1^H^H^H^[[3~^[[3~\
^C
[dell@bogon ~]$ bash chkscore.sh
Enter your score(0-100):200
200 is fail
[dell@bogon ~]$ bash chkscore.sh
Enter your score(0-100):68
68 is fail
[dell@bogon ~]$ ^C
[dell@bogon ~]$ vim guess.sh
[dell@bogon ~]$ cat guess.sh
#!/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 "too high"
else
echo "too low"
fi
done
[dell@bogon ~]$ bash guess.sh
商品实际价格为0-999之间,猜猜是多少
请输入您猜的价格数目:500
too high
请输入您猜的价格数目:250
too high
请输入您猜的价格数目:100
too high
请输入您猜的价格数目:80
too high
请输入您猜的价格数目:3
too low
请输入您猜的价格数目:50
too high
请输入您猜的价格数目:12
too low
请输入您猜的价格数目:25
too high
请输入您猜的价格数目:18
too low
请输入您猜的价格数目:20
too low
请输入您猜的价格数目:23
too high
请输入您猜的价格数目:22
too high
请输入您猜的价格数目:21
恭喜您答对了,实际价格是 21
您总共猜 13 次
let TIMES++每次村换到这里时TIMES变量数值加一
case条件测试语句
case语句是在多个范围内匹配数据,若匹配成功则执行相关命令并结束整个条件测试;而如果数据不在所列出的范围内,则会去执行星号(*)中所定义的默认命令
case 变量值 in
模式1)
命令序列1
;;
模式1)
命令序列2
;;
……
*)
默认命令序列
esac
[dell@bogon ~]$ vim Checkkey.sh
[dell@bogon ~]$ cat Checkkey.sh
#!/bin/bash
read -p "请输入一个字符,并按enter确认:" KEY
case "$KEY" in
[a-z]|[A-Z])
echo "您输入的是字母"
;;
[0-9])
echo "您输入的是数字"
;;
*)
echo "您输入的是其他"
esac
[dell@bogon ~]$ bash Checkkey.sh
请输入一个字符,并按enter确认:9
您输入的是数字
网友评论