八、Linux 常用 Shell 命令,控制台的快捷键以及 Shell 编程(中)

举报
毛利 发表于 2021/07/15 03:34:24 2021/07/15
【摘要】 @Author : Runsen @Date:2020/9/11 文章是Runsen在Gitchat付费文章分享:Linux 常用 Shell 命令,控制台的快捷键以及 Shell 编程 顺便同步到CSDN中,这里设置了VIP,不好意思!!八月份写的,有些时间了。 文章目录 Shell脚本编程变量预定义变量数组和运算符数组运算符 流程控制Linux 问...

@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 环境之后,进行如下操作。

  1. 将根目录重新挂载,模式可写:
switch_root:/# mount -o rw,remount /sysroot

  
 
  • 1
  1. 变更目录至根目录下:
switch_root:/# chroot /sysroot

  
 
  • 1
  1. 更改密码:
sh-4.2# passwd

  
 
  • 1
  1. 如果安装的是中文系统,此时会出现乱码,可以根据经验直接输入,也可输入以下命令,当次变更语言为英语。
sh-4.2# LANG=en_US

  
 
  • 1
  1. 如果 SELinux 开启需要更新 SELinux 上下文,只要创建下面的文件即可。
sh-4.2# touch /.autorelabel

  
 
  • 1
  1. 退出重启。
sh-4.2# exit
switch_root:/# exit

  
 
  • 1
  • 2

文章来源: maoli.blog.csdn.net,作者:刘润森!,版权归原作者所有,如需转载,请联系作者。

原文链接:maoli.blog.csdn.net/article/details/108543207

【版权声明】本文为华为云社区用户转载文章,如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。