Linux基础自查手册

本文最后更新于:2020年12月24日 下午

一、文件系统

1.目录结构

  • bin:存放二进制可执行文件(ls,cat,mkdir等);
  • boot:存放用于系统引导时使用的各种文件;
  • dev:存放设备文件
  • etc:存放系统配置文件
  • home:存放所有用户文件的根目录;
  • lib:存放跟文件系统中的程序运行所需要的共享库及内核模块
  • opt:存放额外安装的可选应用程序包
  • tmp:存放各种临时文件。每次重启都会删掉
  • mnt:系统管理员安装临时文件系统的安装点
  • usr:存放系统应用程序,比较重要的目录为/usr/local,本地管理员软体安装目录
  • var:存放运行时需要改变数据的文件

2.目录操作

操作名称 指令
进入目录 cd
查看完整路径 pwd
创建目录 mkdir
拷贝目录 cp 原地址 目的地址 -r
删除目录 rm -r 循环遍历删除子文件夹;
rmdir
移动目录 mv old_addr new_addr
目录改名 mv old_name new_name
列出本目录下的所有文件 ls -al、ll(相当于ls -a)
  • ls命令:

    ls -a 列出目录所有文件,包含以.开始的隐藏文件
    ls -A 列出除.及..的其它文件
    ls -r 反序排列
    ls -t 以文件修改时间排序
    ls -S 以文件大小排序
    ls -h 以易读大小显示
    ls -l 除了文件名之外,还将文件的权限、所有者、文件大小等信息详细列出来
  • mv命令

    # 移动当前文件夹下的所有文件到上一级目录
    mv * ../
    
    # 将文件 log1.txt,log2.txt,log3.txt 移动到根的 test3 目录中
    mv log1.txt log2.txt log3.txt /test3

3.文件操作

操作名称 指令
创建文件 touch、vi
删除文件 rm -f
修改文件名 mv old_name new_name
查看文件内容 cat、more、less、head、tail
查找文件 which、whereis、locate、find、grep

(1)查看文件指令 详解

  • cat:

    # 一次显示整个文件
    cat filename
    
    # 从键盘创建一个文件
    cat > filename
    
    # 将几个文件合并为一个文件
    cat file1 file2 > file
    
    -b 对非空输出行号
    -n 输出所有行号
  • wc:

    # 统计指定的文件中字节数、字数、行数,并将统计结果输出
    wc -c  # 统计字节数
    wc -l  # 统计行数
    wc -m  # 统计字符数
    wc -w  # 统计词数,一个字被定义为由空白、跳格或换行字符分隔的字符串
  • ps:

    用来查看当前运行的进程状态,一次性查看,如果需要动态连续结果使用 top

    ps -A 显示当前所有进程
    ps -a 显示同一终端下所有进程
    ps c 显示进程真实名称
    ps e 显示环境变量
    ps f 显示进程间的关系
    ps r 显示当前终端运行的进程
    ps -aux 显示所有包含其他使用者的行程
    
    # 与grep联用查找某进程
    ps -aux | grep apache
    
    # 显示当前所有进程环境变量及进程间关系
    ps -ef
    
    # 找出与 cron 与 syslog 这两个服务有关的 PID 号码
    ps aux | grep '(cron|syslog)'
指令 解析
more 逐页显示文档内容
空格下一页、b上一页、q退出、回车向下一行、=显示当前行号
less 逐页显示文档内容,相比于more功能更全面
f下一页、b上一页、j下一行、k上一行、=显示当前行号、q/ZZ退出、/字符串向后搜索该字符串、?字符串向前搜索
head -n <行数>,如head -n 5 1.txt显示文件1.txt的5行(n可以省略)
tail tail -n <行数> filename会显示文件的n行内容(默认后10行,n也可省略)
tail -f filename会循环读取文件,并显示后10行,以始终看到最新的文件内容。

(2)查找文件指令 详解

  • which:

    查看可执行文件的位置,即可以看到某个系统命令是否存在,以及执行的到底是哪一个位置的命令。

    which ls
    which which
    which python
    
    # 查看当前 PATH 配置
    echo $PATH
  • whereis:

    只能用于程序名的搜索,而且只搜索二进制文件(参数-b)、man说明文件(参数-m)和源代码文件(参数-s)。如果省略参数,则返回所有信息。

    whereis 及 locate 都是基于系统内建的数据库进行搜索,因此效率很高,而find则是遍历硬盘查找文件。

    -b   定位可执行文件。
    -m   定位帮助文件。
    -s   定位源代码文件。
    -u   搜索默认路径下除可执行文件、源代码文件、帮助文件以外的其它文件。
    
    # 查找 locate 程序相关文件
    whereis locate
    # 查找 locate 的源码文件
    whereis -s locate
    # 查找 lcoate 的帮助文件
    whereis -m locate
  • locate:

    locate 通过搜寻系统内建文档数据库达到快速找到档案,数据库由 updatedb 程序来更新,updatedb 是由 cron daemon 周期性调用的。

    默认情况下 locate 命令在搜寻数据库时比由整个由硬盘资料来搜寻资料来得快,但较差劲的是 locate 所找到的档案若是最近才建立或 刚更名的,可能会找不到,在内定值中,updatedb 每天会跑一次,可以由修改 crontab 来更新设定值 (etc/crontab)。

    locate 与 find 命令相似,可以使用如 *、? 等进行正则匹配查找

    # 查找和 pwd 相关的所有文件(文件名中包含 pwd)
    locate pwd
    
    # 搜索 etc 目录下所有以 sh 开头的文件
    locate /etc/sh
    
    # 查找 /var 目录下,以 reason 结尾的文件
    # .表示一个字符,*表示任务多个;.*表示任意多个字符
    locate -r '^/var.*reason$'
  • find命令

    格式为find pathname -options [-print -exec -ok ...]

    • pathname: find命令所查找的目录路径。例如用.来表示当前目录,用/来表示系统根目录。
    • -exec:参数后面跟的是 command 命令,它的终止是以 ; 为结束标志的,前面加反斜杠\兼容多系统。-exec command {} \;
    find ./ -name '*.log'  # 在当前目录查找 以 .log 结尾的文件
    
    # 查找当前目录中以一个小写字母开头,最后是 4 到 9 加上 .log 结束的文件
    find . -name '[a-z]*[4-9].log' -print
    
    # 前目录中查找所有文件名以.log结尾、更改时间在5日以上的文件,并删除它们,只不过在删除之前先给出提示。 按y键删除文件,按n键不删除
    find . -name '*.log' mtime +5 -ok -exec rm {} \;
    # 当前目录下查找文件名以 passwd 开头,内容包含 "pkg" 字符的文件
    find . -name '*.log' -exec grep "pkg" {} \;
    
    find -atime -2         # 查找 48 小时内修改过的文件
    
    find /opt -perm 777    # 查找 /opt 目录下 权限为 777 的文件
    find -size +1000c      # 查找大于 1K 的文件
    find -size 1000c       # 查找等于 1000 字符的文件
    
    # 查找更改时间比文件 log2012.log新但比文件 log2017.log 旧的文件
    find -newer log2012.log ! -newer log2017.log 
    
    options命令选项:
    -name 按照文件名查找文件
    -perm 按文件权限查找文件
    -user 按文件属主查找文件
    -group  按照文件所属的组来查找文件。
    -type  查找某一类型的文件,诸如:
       b - 块设备文件
       d - 目录
       c - 字符设备文件
       l - 符号链接文件
       p - 管道文件
       f - 普通文件
  • grep:

    查找文件里符合条件的字符串,grep [范本样式] [文件或目录]

    • grep test *file会查找文件名前缀有“test”且文件内容包含“test”字符串的文件;
    • grep -r update /etc/acpi会查找指定目录/etc/acpi 及其子目录(如果存在子目录的话)下所有文件中包含字符串”update”的文件,并打印出该字符串所在行的内容

4.访问权限

chmod命令用于改变 linux 系统文件或目录的访问权限,其有两种用法:一种是包含字母和操作符表达式的文字设定法;另一种是包含数字的数字设定法。

(1)概述

每一文件或目录的访问权限都有三组,每组用三位表示,分别为文件属主的读、写和执行权限与属主同组的用户的读、写和执行权限系统中其他用户的读、写和执行权限。可使用 ls -l test.txt 查找。

-rw-r--r-- 1 root root 296K 11-13 06:03 log2012.log

第一列参数由10个字符组成,第一个字符表示文件类型:-表示文件,d表示目录;后9位分为3组,每组三位,分别表示三组权限,其中,r表示只读,w表示写,x表示可执行,-表示空许可。

(2)指令参数

-c 当发生改变时,报告处理信息
-R 处理指定目录以及其子目录下所有文件

权限范围:

a :所有的用户及群组(all)
u :目录或者文件的当前用户(user)
g :目录或者文件的当前群组(group)
o :除了目录或者文件的当前用户或群组之外的用户或者群组(other)

权限代号:

r :读权限,用数字4表示
w :写权限,用数字2表示
x :执行权限,用数字1表示
- :删除权限,用数字0表示
s :特殊权限

示例:

# 增加文件 t.log 所有用户可执行权限
chmod a+x t.log

# 撤销原来所有的权限,然后使拥有者具有可读权限,并输出处理信息
chmod u=r t.log -c

# 给 file 的属主分配读、写、执行(7)的权限,给file的所在组分配读、执行(5)的权限,给其他用户分配执行(1)的权限
chmod 777 t.log
chmod u=rwx,g=rx,o=x t.log

# 将 test 目录及其子目录所有文件添加可读权限
# 添加权限用+号,重新分配权限用=号
sudo chmod u+r,g+r,o+r -R test/

二、磁盘指令

1.df命令

显示磁盘空间使用情况。默认情况下,磁盘空间将以 1KB 为单位进行显示。

2.du命令

查看文件和目录磁盘使用的空间。

命令格式:

du [选项] [文件]

-h 以易读方式显示文件大小
-a 显示目录中所有文件大小
-k 以KB为单位显示文件大小
-m 以MB为单位显示文件大小
-g 以GB为单位显示文件大小
-s 仅显示总计
-c或--total  除了显示个别目录或文件的大小外,同时也显示所有目录或文件的总和

实例:

# 以易读方式显示 文件夹内及子文件夹大小
du -h scf/

# 以易读方式显示 文件夹内所有文件大小
du -ah scf/

# 显示几个文件或目录各自占用磁盘空间的大小,还统计它们的总和
du -hc test/ scf/

# 输出当前目录下各个子目录所使用的空间
du -hc --max-depth=1 ./

3.free命令

显示系统内存使用情况,包括物理内存、交互区内存(swap)和内核缓冲区内存。

命令格式:

free [选项]

-b 以Byte显示内存使用情况
-k 以kb为单位显示内存使用情况
-m 以mb为单位显示内存使用情况
-g 以gb为单位显示内存使用情况

-s<间隔秒数> 持续显示内存
-t 显示内存使用总合

示例:

# 显示内存使用情况
free
free -k
free -m

# 周期性查询内存使用情况
free -s 2 -g

三、网络命令

1.ifconfig

2.ping

四、Shell命令

1.概述

在sh脚本开头,采用#!/bin/bash注明程序的解释器

运行sh脚本时,可以直接./test.sh(其中./不可省略,否则linux系统会到PATH里寻找有没有叫test.sh的文件;采用./是告诉系统在当前目录寻找),也可以通过/bin/bash test.sh运行

2.Shell变量

(1)定义变量

  • 变量名和等号之间不能有空格

  • 变量名只能使用英文字母,数字和下划线,首个字符不能以数字开头。

  • 不能使用bash里的关键字(可用help命令查看保留关键字)

  • 使用 readonly 命令可以将变量定义为只读变量,只读变量的值不能被改变。
#!/bin/bash
your_name="runoob.com"

myUrl="https://www.google.com"
readonly myUrl
myUrl="https://www.runoob.com"  # 此处会报错

(2)使用变量

使用一个定义过的变量,只要在变量名前面加美元符号$即可

your_name="qinjx"
echo $your_name
echo ${your_name}
  • 花括号是可以省略的,加花括号是为了帮助解释器识别变量的边界,比如
for skill in Ada Coffe Action Java; do
    echo "I am good at ${skill}Script"
done

# 如果不给skill变量加花括号,写成echo "I am good at $skillScript"
# 解释器就会把$skillScript当成一个变量(其值为空),造成错误
  • 已定义的变量,可以被重新定义。赋值无需$,这个符号只有在调用变量时才会用到
your_name="tom"
echo $your_name
your_name="alibaba"
echo $your_name

(3)删除变量

unset variable_name
  • 变量被删除后不能再次使用。

  • unset 命令不能删除只读变量。

(4)变量类型

运行shell时,会同时存在三种变量:

  • 局部变量 :局部变量在脚本或命令中定义,仅在当前shell实例中有效,其他shell启动的程序不能访问局部变量。
  • 环境变量: 所有的程序,包括shell启动的程序,都能访问环境变量,有些程序需要环境变量来保证其正常运行。必要的时候shell脚本也可以定义环境变量。
  • shell变量 :shell变量是由shell程序设置的特殊变量。shell变量中有一部分是环境变量,有一部分是局部变量,这些变量保证了shell的正常运行

3.Shell字符串

字符串可以用单引号,也可以用双引号,也可以不用引号。

(1)单引号

str='this is a string'

单引号字符串的限制:

  • 单引号里的任何字符都会原样输出,单引号字符串中的变量是无效的
  • 单引号字串中不能出现单独一个的单引号(对单引号使用转义符后也不行),但可成对出现,作为字符串拼接使用。

(2) 双引号

your_name='runoob'
str="Hello, I know you are \"$your_name\"! \n"
echo -e $str    # Hello, I know you are "runoob"! 

双引号的优点:

  • 双引号里可以有变量
  • 双引号里可以出现转义字符

(3)拼接字符串

your_name="runoob"
# 使用双引号拼接
greeting="hello, "$your_name" !"
greeting_1="hello, ${your_name} !"
echo $greeting  $greeting_1    # hello, runoob ! hello, runoob !

# 使用单引号拼接
greeting_2='hello, '$your_name' !'
greeting_3='hello, ${your_name} !'   # 变量无效
echo $greeting_2  $greeting_3  # hello, runoob ! hello, ${your_name} !

(4)获取字符串长度:#

string="abcd"
echo ${#string} # 输出 4

(5)查找子字符串:expr index

查找字符 io 的位置(哪个字母先出现就计算哪个):

string="runoob is a great site"
echo `expr index "$string" io`  # 输出 4
# 此处是`而不是'

(6)提取子字符串

  • ### 表示从左边开始删除。一个 # 表示从左边删除到第一个指定的字符;两个 # 表示从左边删除到最后一个指定的字符。

  • %%% 表示从右边开始删除。一个 % 表示从右边删除到第一个指定的字符;两个 % 表示从左边删除到最后一个指定的字符。

    删除包括了指定的字符本身。

var=http://www.aaa.com/123.htm

echo ${var#*//}   # 删除第一个出现的//及其左侧字符
echo ${var##*/}   # 删除最后一个出现的/及其左侧字符

echo ${var%/*}    # 从右边开始,删除第一个/及其右侧字符,http://www.aaa.com
echo ${var%%/*}   # 从右边开始,删除最后一个/及其右侧字符,http:
  • 通过:索引提取子字符串,第一个字符的索引值为 0
echo ${var:0:5}    # 从左边第几个字符开始,及字符的个数;输出 http:
echo ${var:7}      # 从左边第几个字符开始,一直到结束;www.aaa.com/123.htm
echo ${var:0-7:3}  # 从右边第几个字符开始,及字符的个数;此处为右侧第7个字符开始,123
echo ${var:0-7}    # 从右边第几个字符开始,一直到结束;123.htm

左边的第一个字符是用 0 表示,右边的第一个字符用 0-1 表示

4.Shell参数传递

在执行 Shell 脚本时,同时向脚本传递参数,脚本内获取参数的格式为:$n

#!/bin/bash

echo "Shell 传递参数实例!";
echo "执行的文件名:$0";
echo "第一个参数为:$1";
echo "第二个参数为:$2";
echo "第三个参数为:$3";

为脚本设置可执行权限chmod +x test.sh,并执行脚本./test.sh 1 2 3,因此输出为:

Shell 传递参数实例!
执行的文件名:./test.sh
第一个参数为:1
第二个参数为:2
第三个参数为:3

参数处理:

指令 说明
$# 传递到脚本的参数个数
$* 以一个单字符串显示所有向脚本传递的参数。 如"$*""括起来的情况、以”$1 $2 … $n”的形式输出所有参数。
$@ $*一样,都是引用所有参数。但假设在脚本运行时写了三个参数 1、2、3,,则 * 等价于 “1 2 3”(传递了一个参数),而 @ 等价于 “1” “2” “3”(传递了三个参数)。
$- 显示Shell使用的当前选项,与set命令功能相同。
$$ 脚本运行的当前进程ID号
$! 后台运行的最后一个进程的ID号
$? 显示最后命令的退出状态。0表示没有错误,其他任何值表明有错误。
#!/bin/bash

echo "Shell 传递参数实例!";
echo "第一个参数为:$1";

echo "参数个数为:$#";
echo "传递的参数作为一个字符串显示:$*";

echo "-- \$* 演示 ---"
for i in "$*"; do
    echo $i
done

echo "-- \$@ 演示 ---"
for i in "$@"; do
    echo $i
done

为脚本设置可执行权限chmod +x test.sh,并执行脚本./test.sh 1 2 3,因此输出为:

Shell 传递参数实例!
第一个参数为:1
参数个数为:3
传递的参数作为一个字符串显示:1 2 3
-- $* 演示 ---
1 2 3
-- $@ 演示 ---
1
2
3

5.Shell数组

Bash Shell 只支持一维数组(不支持多维数组),初始化时不需要定义数组大小。

(1)定义数组

  • 数组中,各元素用”空格”符号分割开。
my_array=(A B "C" D)
  • 也可以使用下标来定义数组
array_name[0]=value0
array_name[1]=value1
array_name[2]=value2

(2)访问数组

  • 读取数组元素值的一般格式是:${array_name[index]}
  • 获取数组中的所有元素:${array_name[*]}或者${array_name[@]}
  • 获取数组长度:${#array_name[*]}或者${#array_name[@]}
    • 和字符串是一样的,*和$获取所有元素,#获取长度
#!/bin/bash
my_array=(A B "C" D)

echo "第一个元素为: ${my_array[0]}"   
echo "第二个元素为: ${my_array[1]}"  
echo "第三个元素为: ${my_array[2]}"
echo "第四个元素为: ${my_array[3]}"
echo "最后一个元素为:${my_array[-1]}
echo $my_array[0]  # 输出A[0]

echo "数组的元素为: ${my_array[*]}"
echo "数组的元素为:${my_array[@]}"

echo "数组元素个数为: ${#my_array[*]}"
echo "数组元素个数为: ${#my_array[@]}"

(3)遍历数组

#!/bin/bash
my_array=(A B "C" D)

for arr in ${my_array[*]}
do
	echo $arr
done

6.Shell运算符

原生bash不支持简单的数学运算,但可以通过awkexpr等命令来实现

  • 表达式和运算符之间要有空格,例如 2+2 是不对的,必须写成 2 + 2
  • 完整的表达式要被``包含,如
#!/bin/bash

val=`expr 2 + 2`
val2=$(expr 10 + 20)

echo "两数之和为 : $val"

(1)算数运算符

运算符 说明 举例
+ 加法 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==$b] 是错误的,必须写成 [ $a == $b ]

(2)关系运算符

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
-eq 检测两个数是否相等(equal),相等返回 true。 [ $a -eq $b ] 返回 false。
-ne 检测两个数是否不相等(not equal),不相等返回 true。 [ $a -ne $b ] 返回 true。
-gt 检测左边的数是否大于右边的(Greater Than),如果是,则返回 true。 [ $a -gt $b ] 返回 false。
-lt 检测左边的数是否小于右边的(Less Than),如果是,则返回 true。 [ $a -lt $b ] 返回 true。
-ge 检测左边的数是否大于等于右边的(Greater ThanOR Equal),如果是,则返回 true。 [ $a -ge $b ] 返回 false。
-le 检测左边的数是否小于等于右边的,如果是,则返回 true。 [ $a -le $b ] 返回 true。

(3)布尔运算符

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
! 非运算,表达式为 true 则返回 false,否则返回 true。 [ ! false ] 返回 true。
-o 或运算(or),有一个表达式为 true 则返回 true。 [ $a -lt 20 -o $b -gt 100 ] 返回 true。
-a 与运算(and),两个表达式都为 true 才返回 true。 [ $a -lt 20 -a ​$b -gt 100 ] 返回 false。

(4)逻辑运算符

假定变量 a 为 10,变量 b 为 20:

运算符 说明 举例
&& 逻辑 与 [[ $a -lt 100 && ​$b -gt 100 ]] 返回 false
\ \ 逻辑 或 [[ $a -lt 100 \ \ ​$b -gt 100 ]] 返回 true

(5)字符串运算符

假定变量 a 为 “abc”,变量 b 为 “efg”:

运算符 说明 举例
= 检测两个字符串是否相等,相等返回 true。 [ $a = $b ] 返回 false。
!= 检测两个字符串是否相等,不相等返回 true。 [ $a != $b ] 返回 true。
-z 检测字符串长度是否为0 (zero),为0返回 true。 [ -z $a ] 返回 false。
-n 检测字符串长度是否不为 0 (not zero),不为 0 返回 true。 [ -n “$a” ] 返回 true。
$ 检测字符串是否为空,不为空返回 true。 [ $a ] 返回 true。

(6)文件测试运算符

操作符 说明 举例
-b file 检测文件是否是块设备文件,如果是,则返回 true。 [ -b $file ] 返回 false。
-c file 检测文件是否是字符设备文件,如果是,则返回 true。 [ -c $file ] 返回 false。
-d file 检测文件是否是目录,如果是,则返回 true。 [ -d $file ] 返回 false。
-f file 检测文件是否是普通文件(既不是目录,也不是设备文件),如果是,则返回 true。 [ -f $file ] 返回 true。
-g file 检测文件是否设置了 SGID 位,如果是,则返回 true。 [ -g $file ] 返回 false。
-k file 检测文件是否设置了粘着位(Sticky Bit),如果是,则返回 true。 [ -k $file ] 返回 false。
-p file 检测文件是否是有名管道,如果是,则返回 true。 [ -p $file ] 返回 false。
-u file 检测文件是否设置了 SUID 位,如果是,则返回 true。 [ -u $file ] 返回 false。
-r file 检测文件是否可读,如果是,则返回 true。 [ -r $file ] 返回 true。
-w file 检测文件是否可写,如果是,则返回 true。 [ -w $file ] 返回 true。
-x file 检测文件是否可执行,如果是,则返回 true。 [ -x $file ] 返回 true。
-s file 检测文件是否为空(文件大小是否大于0),不为空返回 true。 [ -s $file ] 返回 true。
-e file 检测文件(包括目录)是否存在,如果是,则返回 true。
  • -S: 判断某文件是否 socket。
  • -L: 检测文件是否存在并且是一个符号链接。

7.流程控制

(1)选择结构

  • if 语句语法格式:

    if condition
    then
        command1 
        command2
        ...
        commandN 
    fi
    
    # 写成一行
    if [ $(ps -ef | grep -c "ssh") -gt 1 ]; then echo "true"; fi
    
    if [ $(ps -ef | grep -c "ssh") -gt 1 ]
    then 
    	echo "true"
    fi
  • if else 语法格式:

    if condition
    then
        command1 
        command2
        ...
        commandN
    else
        command
    fi
  • if elif 语法格式为:

    if condition1
    then
        command1
    elif condition2 
    then 
        command2
    else
        commandN
    fi
    
    
    a=10
    b=20
    if [ $a == $b]
    then
    	echo "a等于b"
    elif [ $a -gt $b]
    then
    	echo "a大于b"
    else
    	echo "a小于b"
    fi
  • case语法格式为:

    casein
    模式1)
        command1
        commandN
        ;;
    模式2)
        command1
        commandN
        ;;
    esac
    
    echo '输入 1 到 4 之间的数字:'
    echo '你输入的数字为:'
    read aNum
    case $aNum in
        1)  echo '你选择了 1'
        ;;
        2)  echo '你选择了 2'
        ;;
        3)  echo '你选择了 3'
        ;;
        4)  echo '你选择了 4'
        ;;
        *)  echo '你没有输入 1 到 4 之间的数字'
        ;;
    esac

(2)循环结构

  • for循环一般格式为

    for var in item1 item2 ... itemN
    do
        command1
        command2
        ...
        commandN
    done
    
    for loop in 1 2 3 4 5
    do
    	echo "The value: $loop"
    done
    
    for str in 'This is a String'
    do
    	echo $str
    done
    
    for((i=1;i<=5;i++));do
    	echo $i
    done;
  • while语句

    while condition
    do
        command
    done
    
    int=1
    while(( $int<=5 ))
    do
        echo $int
        let "int++"
    done
  • break命令允许跳出所有循环

    #!/bin/bash
    while :
    do
        echo -n "输入 1 到 5 之间的数字:"
        read aNum
        case $aNum in
            1|2|3|4|5) echo "你输入的数字为 $aNum!"
            ;;
            *) echo "你输入的数字不是 1 到 5 之间的! 游戏结束"
                break
            ;;
        esac
    done
  • continue退出当前循环

    #!/bin/bash
    while :
    do
        echo -n "输入 1 到 5 之间的数字: "
        read aNum
        case $aNum in
            1|2|3|4|5) echo "你输入的数字为 $aNum!"
            ;;
            *) echo "你输入的数字不是 1 到 5 之间的!"
                continue
                echo "游戏结束"
            ;;
        esac
    done

8.Shell函数

shell中函数的定义格式如下:

funname (){
    action;
    [return int;]
}
  • 函数名前的function字段可以省略
  • 可以有返回值(0~255),也可以不加return语句,以最后一条命令的运行结果作为返回值
#!/bin/bash

demofunc(){
	echo "Hello,World"
}

echo "函数开始执行..."
demofunc      # 没有括号,直接调用
echo "函数执行结束..."

funWithReturn(){
    echo "这个函数会对输入的两个数字进行相加运算..."
    echo "输入第一个数字: "
    read aNum
    echo "输入第二个数字: "
    read anotherNum
    echo "两个数字分别为 $aNum$anotherNum !"
    return $(($aNum+$anotherNum))
}
funWithReturn
echo "输入的两个数字之和为 $? !"
  • 通过$?调用函数的返回值

  • 调用函数仅使用其函数名即可

  • 在函数体内部,通过$n获取参数的值。带参数的函数示例:

    #!/bin/bash
    funWithParam(){
        echo "第一个参数为 $1 !"
        echo "第二个参数为 $2 !"
        echo "第十个参数为 $10 !"
        echo "第十个参数为 ${10} !"
        echo "第十一个参数为 ${11} !"
        echo "参数总数有 $# 个!"
        echo "作为一个字符串输出所有参数 $* !"
    }
    funWithParam 1 2 3 4 5 6 7 8 9 34 73

9.输入、输出重定向

命令 说明
command > file 将输出重定向到 file。(文件会先被格式化)
command >> file 将输出以追加的方式重定向到 file。
command < file 将输入重定向到 file。
n > file 将文件描述符为 n 的文件重定向到 file。
n >> file 将文件描述符为 n 的文件以追加的方式重定向到 file。
n >& m 将输出文件 m 和 n 合并。
n <& m 将输入文件 m 和 n 合并。
<< tag 将开始标记 tag 和结束标记 tag 之间的内容作为输入。
who > users    # 将当前登录系统的用户 输出到users文件中
who >> users   # 追加到user文件中

wc -l users

# 从文件读入,并输出到另一个文件
command1 < infile > outfile

一般情况下,每个 Unix/Linux 命令运行时都会打开三个文件:

  • 标准输入文件(stdin):stdin的文件描述符为0,Unix程序默认从stdin读取数据。
  • 标准输出文件(stdout):stdout 的文件描述符为1,Unix程序默认向stdout输出数据。
  • 标准错误文件(stderr):stderr的文件描述符为2,Unix程序会向stderr流中写入错误信息。

默认情况下,command > file 将 stdout 重定向到 file,command < file 将stdin 重定向到 file。

command 2>file   # stderr 重定向到 file
command 2>>file  # stderr 追加到 file 文件末尾
command > file 2>&1   #  stdout 和 stderr 合并后重定向到 file
command >> file 2>&1