八、Linux 常用 Shell 命令,控制台的快捷键以及 Shell 编程(中)
@Author : Runsen
@Date:2020/9/11
文章是Runsen在Gitchat付费文章分享:Linux 常用 Shell 命令,控制台的快捷键以及 Shell 编程
顺便同步到CSDN中,这里设置了VIP,不好意思!!八月份写的,有些时间了。
Shell脚本编程
所谓脚本,就是把众多命令写入一个文件中,让其按照一定的逻辑顺序执行,以完成一个具体的功能。而在Linux的shell编译环境下,shell编程与众多编程语言一样,也有其独立的语法。
打开文本编辑器(可以使用 vi/vim 命令来创建文件),新建一个文件 test.sh,扩展名为 sh(sh代表shell)。
maoli@ubuntu:~$ vim test.sh
#!/bin/bash
echo "Hello World !"
- 1
- 2
- 3
- 4
变量
变量名不加美元符号($
,PHP语言中变量需要)。比如在shell中 定义变量name = Runsen,而在php就是$name = Runsen
使用一个定义过的变量,只要在变量名前面加美元符号即可,如:$name
或者${name}
。变量名外面的花括号是可选的,加不加都行。
变量支持字符串类型,浮点等类型,常见有这 3 个前缀:
- unset:删除变量
- readonly:标记只读变量
- export:指定全局变量
#!/bin/bash
# 定义普通变量,没有特殊字符或者空格,可以不用引号
CITY=Dongguan
# 定义全局变量
export NAME=Runsen
# 定义只读变量
readonly AGE=20
# 打印变量的值
echo $CITY
echo $NAME
echo $AGE
# 删除 CITY 变量
unset CITY
# 不会输出 Dongguan
echo $CITY
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
预定义变量
预定义变量常用来获取命令行的输入,有下面这些:
$0 :脚本文件名
$1-9 :第 1-9 个命令行参数名
$# :命令行参数个数
$@ :所有命令行参数
$* :所有命令行参数
$? :前一个命令的退出状态,可用于获取函数返回值
$$ :执行的进程 ID
- 1
- 2
- 3
- 4
- 5
- 6
- 7
下面我们看一个预定义变量例子:
maoli@ubuntu:~$ vim hello.sh
#!/bin/bash
echo "\$0 = $0"
echo "\$1 = $1"
echo "\$2 = $2"
echo "\$# = $#"
echo "\$@ = $@"
echo "\$* = $*"
echo "\$$ = $$"
echo "\$? = $?"
maoli@ubuntu:~$ ./hello.sh 1 2 3 4 5
# 程序名
$0 = ./hello.sh
# 第一个参数
$1 = 1
# 第二个参数
$2 = 2
# 一共有 5 个参数
$# = 5
# 打印出所有参数
$@ = 1 2 3 4 5
# 打印出所有参数
$* = 1 2 3 4 5
# 进程 ID
$$ = 9450
# 之前没有执行其他命令或者函数
$? = 0
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
数组和运算符
数组
数组中可以存放多个值。Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。Shell 数组用括号来表示,元素用"空格"符号分割开,举例如下:
my_array=(A B "C" D)
- 1
我们也可以使用下标来定义数组:
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2
- 1
- 2
- 3
读取数组
my_array=(A B "C" D)
echo "第一个元素为: ${my_array[0]}"
echo "第二个元素为: ${my_array[1]}"
echo "第三个元素为: ${my_array[2]}"
echo "第四个元素为: ${my_array[3]}"
- 1
- 2
- 3
- 4
- 5
- 6
获取数组中的所有元素
使用@ 或 * 可以获取数组中的所有元素,例如:
my_array[0]=A
my_array[1]=B
my_array[2]=C
my_array[3]=D
echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为: ${my_array[@]}"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
获取数组的长度
获取数组长度的方法与获取字符串长度的方法相同,例如:
my_array[0]=A
my_array[1]=B
my_array[2]=C
my_array[3]=D
echo "数组元素个数为: ${#my_array[*]}"
echo "数组元素个数为: ${#my_array[@]}"
- 1
- 2
- 3
- 4
- 5
- 6
- 7
运算符
val=`expr 2 + 2`
echo "两数之和为 : $val"
- 1
- 2
两点注意:
- 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2,这与我们熟悉的大多数编程语言不一样。
- 完整的表达式要被
包含,注意这个字符不是常用的单引号,在 Esc 键下边。
运算符 | 说明 | 举例 |
---|---|---|
+ | 加法 | expr $a + $b 结果为 30。 |
- | 减法 | expr $a - $b 结果为 -10。 |
* | 乘法 | expr $a \* $b 结果为 200。 |
/ | 除法 | expr $b / $a 结果为 2。 |
% | 取余 | expr $b % $a 结果为 0。 |
= | 赋值 | a=$b 将把变量 b 的值赋给 a。 |
== | 相等。用于比较两个数字,相同则返回 true。 | [ $a == $b ] 返回 false。 |
!= | 不相等。用于比较两个数字,不相同则返回 true。 | [ $a != $b ] 返回 true。 |
关系运算符
关系运算符只支持数字,不支持字符串,除非字符串的值是数字。
下表列出了常用的关系运算符,假定变量 a 为 10,变量 b 为 20:
运算符 | 说明 | 举例 |
---|---|---|
-eq | 检测两个数是否相等,相等返回 true。 | [ $a -eq $b ] 返回 false。 |
-ne | 检测两个数是否相等,不相等返回 true。 | [ $a -ne $b ] 返回 true。 |
-gt | 检测左边的数是否大于右边的,如果是,则返回 true。 | [ $a -gt $b ] 返回 false。 |
-lt | 检测左边的数是否小于右边的,如果是,则返回 true。 | [ $a -lt $b ] 返回 true。 |
-ge | 检测左边的数是否大于等于右边的,如果是,则返回 true。 | [ $a -ge $b ] 返回 false。 |
-le | 检测左边的数是否小于等于右边的,如果是,则返回 true。 | [ $a -le $b ] 返回 true。 |
流程控制
if判断语句,下面我们写一个简单判断语句。
maoli@ubuntu:~$ vim hello.sh
#!/bin/bash
# read 的方法就python中的input,适用于终端命令提示符
read VAR
# 下面这两种判断方法都可以,使用 [] 注意左右加空格
#if test $VAR -eq 10
if [ $VAR -eq 10 ]
then echo "true"
else echo "false"
fi
maoli@ubuntu:~$ sh hello.sh
10
true
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
for 循环和Python没有什么区别,挺简单的。如果运行for循环报错Syntax error: Bad for loop variable
,需要使用命令sudo dpkg-reconfigure dash
,然后在在选择项中选No
原因:代码对于标准bash而言没有错,因为Ubuntu为了加快开机速度,用dash代替了传统的bash,是dash在捣鬼。
下面是for循环的shell代码
maoli@ubuntu:~$ vim hello.sh
#!/bin/bash
# 普通 for 循环 declare声明变量-i
declare -i SUM=0
for ((i=1;i<=100;i+=1))
do let SUM+=$i
done
echo $SUM
# loop 依次代表每个元素
for loop in 1 2 3 4 5
do echo "The value is: $loop"
done
# VAR 依次代表每个元素 ,{}产生连续数字
for VAR in {1..3}
do echo $VAR
done
maoli@ubuntu:~$ sh hello.sh
5050
The value is: 1
The value is: 2
The value is: 3
The value is: 4
The value is: 5
1
2
3
#也可以写成一行,方便在命令行直接运行,注意空格和;号:
maoli@ubuntu:~$ for VAR in {1..3}; do echo $VAR; done
1
2
3
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 29
- 30
- 31
- 32
- 33
- 34
- 35
- 36
- 37
Linux 问题处理
下面问题是我在用 Linux 时,经常出来,对此,个人做一个简单的记录。
不知道文件放在哪里,如何查找文件
很多的时候,我搭建 Hadoop 等环境的时候,不知道下载的安装包放在哪里,其实使用 locate 命令就可以了。
下面是我的具体演示。
locate:通过文件名查找文件。
语法:
locate [-d ][--help][--version][范本样式...]
举例:查找 passwd 文件。
locate passwd
搜索 etc 目录下所有以 my 开头的文件:
locate /etc/my
这里说下:在用 whereis 和 locate 查找文件时,有时会找到已经被删除的数据,或者刚刚建立文件,却无法查找到,原因就是因为数据库文件没有被更新。为了避免这种情况,可以在使用 locate 之前,先使用 updatedb 命令,手动更新数据库。整个 locate 工作其实是由四部分组成的。
新增的文件无法 locate,使用 updatedb:
[root@cent7 ~]# touch new.txt
[root@cent7 ~]# locate new.txt
[root@cent7 ~]# updatedb
[root@cent7 ~]# locate new.txt
/root/new.txt
- 1
- 2
- 3
- 4
- 5
还有 find:在目录层次结构中查找文件。
忘记密码解决,怎么登录
有几次,我忘了 CentOS 7 的用户密码,对此也百度折腾了下。下面介绍解决方法,我以 CentOS 7 为例。
在启动选择内核版本的时候按上下键,令画面停住。
CentOS 7 每次会有两个版本的内核供选择,简单的来说就是一个主内核版本,一个副内核版本,如果以后内核升级失败无法使用新内核重启时,可以通过这个界面选择旧内核重启进行修复。
选择好了内核之后,按下 e 键,进入编辑界面。
找到以 linux16 开头的那一行,在行尾加上如下几句话:
- 如果是物理机,添加:rd.break
- 如果是虚拟机,添加:rd.break console=tty0
这里我用的是虚拟机,所以添加 rd.break console=tty0,如下图所示:
然后按 Ctrl+x 进行启动。
进入 shell 环境之后,进行如下操作。
- 将根目录重新挂载,模式可写:
switch_root:/# mount -o rw,remount /sysroot
- 1
- 变更目录至根目录下:
switch_root:/# chroot /sysroot
- 1
- 更改密码:
sh-4.2# passwd
- 1
- 如果安装的是中文系统,此时会出现乱码,可以根据经验直接输入,也可输入以下命令,当次变更语言为英语。
sh-4.2# LANG=en_US
- 1
- 如果 SELinux 开启需要更新 SELinux 上下文,只要创建下面的文件即可。
sh-4.2# touch /.autorelabel
- 1
- 退出重启。
sh-4.2# exit
switch_root:/# exit
- 1
- 2
文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。
原文链接:maoli.blog.csdn.net/article/details/108543207
- 点赞
- 收藏
- 关注作者
评论(0)