鸟哥的Linux私房菜笔记

常用命令

ls -al name*:查看包括匿名文件/目录的全部文件、查看文件/目录的详细信息、并且过滤出文件名带name的文件/目录

pwd -P:查看当前目录的所在PATH,如果是链接的快捷PATH的会显示正确地址

mkdir -p name/name/name:可以递归创建多级目录

mkdir -m 771 name:创建带权限的目录

cp/rm -i:复制/删除。如已存在,询问是否覆盖

cp/rm -r:递归复制/删除

cp -a:将文件权限、所属、创建日期等信息原样复制

cat -n或nl:带行号

which name:查找命令位置。bash内指令无法查找

whereis:从特定目录查找文件名。具体目录whereis -l查看

locate:从已建立的数据库查找/var/lib/mlocate

find:比较操硬盘的查找

df -h:更可读的磁盘容量形式

文件权限

文件权限-rwxrwx—:

第一个字符

  • 当为[d]则是目录,例如上表档名为『.config』的那一行;
  • 当为[-]则是文件,例如上表档名为『initial-setup-ks.cfg』那一行;
  • 若是[l]则表示为快捷方式(link file);
  • 若是[b]则表示为设备与装置文件(device),提供系统随机存取的接口设备,如硬盘;
  • 若是[c]则表示为设备与装置文件里面的串行端口设备,例如键盘、鼠标(一次性读取装置)。

其余字符,三个为一组,均为[rwx],r可读、w可写、x可执行、-为无权限

  • 第一组为『文件拥有者可具备的权限』
  • 第二组为『加入此群组之账号的权限』
  • 第三组为『其他账号的权限』

文件配置/存放方法:FHS

FHS订定出来的四种目录特色

image-20240722221111595

FHS所定义的三层主目录:

  • / (root, 根目录):与开机系统有关;
  • /usr (unix software resource):与软件安装/执行有关;
  • /var(variable):与系统运作过程有关。

命令示例

chmod数字类型改变文件权限

rwx=421

1
2
3
[root@study ~]# chmod 777 .bashrc
[root@study ~]# ls -al .bashrc
-rwxrwxrwx. 1 root root 176Dec 29 2013 .bashrc

chmod符号类型改变文件权限

u=user、g=group、o=others、a=all

1
2
3
4
[root@study ~]# chmod  u=rwx,go=rx  .bashrc
# 注意喔!那个u=rwx,go=rx 是连在一起的,中间并没有任何空格符!
[root@study ~]# ls -al .bashrc
-rwxr-xr-x. 1 root root 176 Dec 29 2013 .bashrc

+(加入)、-(除去)、=(设定)

1
2
3
4
5
[root@study ~]# ls -al .bashrc
-rwxr-xr-x. 1 root root 176 Dec 29 2013 .bashrc
[root@study ~]# chmod a+w .bashrc
[root@study ~]# ls -al .bashrc
-rwxrwxrwx. 1 root root 176 Dec 29 2013 .bashrc

文件压缩

常见的压缩指令有gzip, bzip2, xz。

压缩率最佳的是xz,若可以不计时间成本,建议使用xz 进行压缩。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
# 压缩c:tar -jcv -f filename.tar.bz2 要压缩的文件或目录
# 查询t:tar -jtv -f filename.tar.bz2
# 解压缩x&C:tar -jxv -f filename.tar.bz2 -C 解压到的地址
[root@study ~]# tar
选项与参数:
-c :建立打包文件,可搭配 -v 来察看过程中被打包的档名(filename)
-t :察看打包文件的内容含有哪些档名,重点在察看『档名』就是了;
-x :解打包或解压缩的功能,可以搭配-C (大写) 在特定目录解开
特别留意的是,-c, -t, -x 不可同时出现在一串指令列中。
# ------------------------------------------
-z :透过gzip 的支持进行压缩/解压缩:此时档名最好为*.tar.gz
-j :透过bzip2 的支持进行压缩/解压缩:此时档名最好为*.tar.bz2
-J :透过xz 的支持进行压缩/解压缩:此时档名最好为*.tar.xz
特别留意,-z, -j, -J 不可以同时出现在一串指令列中
# ------------------------------------------
-v :在压缩/解压缩的过程中,将正在处理的文件名显示出来!
-f filename:-f 后面要立刻接要被处理的档名!建议-f 单独写一个选项啰!(比较不会忘记)
-C 目录:这个选项用在解压缩,若要在特定目录解压缩,可以使用这个选项。

其他后续练习会使用到的选项介绍:
-p(小写) :保留备份数据的原本权限与属性,常用于备份(-c)重要的配置文件
-P(大写) :保留绝对路径,亦即允许备份数据中含有根目录存在之意;
--exclude=FILE:在压缩的过程中,不要将FILE 打包!

vim

wq保存退出

/搜索

小数点『. 』为重复进行前一次动作

按键 作用
v 字符选择
V 选择
ctrl+v 长方形式选择
u 撤回
y 复制所选
d 删除所选
p 粘贴所选
yy 复制整列
dd 删除整列
[number]G 移动到这个文件的第 number 列
G 移动到这个文件的最后一列
gg 移动到这个文件的第一列
[number] 光标向下移动 number 列
/word 向下查找单词
?word 向上查找单词
ctrl+r 重复上个操作

:sp {filename} 可以实现分屏,上面为当前窗口,下面为初始打开使用sp冻结的文档。

使用ctrl+w+↑/↓可切换当前窗口。ctrl+w+q离开当前窗口

image-20240725211213259

磁盘与文件系统

磁盘、操作系统与文件系统

在Linux系统中,每个装置都被当成一个文件来对待,每个装置都会有装置文件名。

磁盘的文件名:

/dev/sd[a, b, c]实体磁盘文件名

/dev/vd[a, b, c]虚拟磁盘文件名

整个开机流程到操作系统之前的动作应该是这样的:

  1. BIOS:开机主动执行的韧体,会认识第一个可开机的装置;
  2. MBR:第一个可开机装置的第一个扇区内的主要启动记录区块,内含开机管理程序;
  3. 开机管理程序(boot loader):一支可读取核心文件来执行的软件;
  4. 核心文件:开始操作系统的功能…

开机的流程:BIOS–>MBR–>–>boot loader–>核心文件

操作系统会控制所有的硬件并且提供核心功能,因此我们的计算机就能够认识硬盘内的文件系统,并且进一步的读取硬盘内的软件文件与执行该软件来达成各项软件的执行目的。

文件系统是建立在磁盘上面的,一个可以被挂载的数据通常称为『文件系统, filesystem』

文件系统通常会将文件权限(rwx)与文件属性(拥有者、群组、时间参数等)的数据分别存放在不同的区块,权限与属性放置到inode 中,至于实际数据则放置到data block 区块中。

另外,还有一个超级区块(superblock) 会记录整个文件系统的整体信息,包括inode 与block 的总量、使用量、剩余量等。

实体链接与符号链接

1
2
3
4
[root@study ~]# ln [ -sf ] 来源文件 目标文件
# 选项与参数:
# -s :如果不加任何参数就进行连结,那就是hard link,至于-s 就是symbolic link
# -f :如果目标文件存在时,就主动的将目标文件直接移除后再建立!

实体链接不能夸文件系统、不能链接目录。

符号链接建立一个独立的文件,文件指向链接的文件。类似win快捷方式

image-20240723155532343

图为实体链接的文件读取示意图。

两个不同inode,不同的指向的文件PATH,文件PATH中的block指向含有真实data的inode。

image-20240723155558424

符号链接的文件读取示意图。

磁盘分区、挂载、卸除

MBR(Master Boot Record, 主要开机纪录区) 的方式可以用来处理开机管理程序与分区表,是可以安装开机管理程序的地方。

GPT 分区:某些操作系统要使用GPT 分区时,必须要搭配UEFI 的新型BIOS 格式才可安装使用

MBR 分区表请使用fdisk 分区,GPT 分区表请使用gdisk 分区!

CSDN:loop是表示整盘分区的,意思就是整个硬盘作为一个独立的分区

挂载

1
2
3
4
5
6
7
8
9
[root@study ~]# mount -a
# -a :依照配置文件/etc/fstab的数据将所有未挂载的磁盘都挂载上来
[root@study ~]# mount [-l]
# -l :单纯的输入mount 会显示目前挂载的信息。加上-l 可增列Label 名称!
[root@study ~]# mount LABEL='' 挂载点
[root@study ~]# mount UUID='' 挂载点
[root@study ~]# mount 装置文件名 挂载点
[root@study ~]# mount -o loop /tmp/CentOS-7.0-1406-x86_64-DVD.iso /data/centos_dvd
# -o :后面可以接一些挂载时额外加上的参数!比方说账号、密码、读写权限等:

卸除

1
2
3
4
5
[root@study ~]# umount [-fn] 装置文件名或挂载点
# 选项与参数:
# -f :强制卸除!可用在类似网络文件系统(NFS) 无法读取到的情况下;
# -l :立刻卸除文件系统,比-f 还强!
# -n :不更新/etc/mtab 情况下卸除。

SWAP交换分区

用途:可以暂时将内存的程序拿到硬盘中暂放的内存置换空间(swap)

步骤:

  1. 分区:先使用 gdisk/fdisk 在你的磁盘中分区出一个分区槽给系统作为swap 。由于Linux 的gdisk 预设会将分区槽的ID 设定为Linux 的文件系统,所以你可能还得要设定一下system ID 就是了。
  2. 格式化:利用建立swap 格式的『mkswap 装置文件名』就能够格式化该分区槽成为swap 格式
  3. 使用:最后将该swap 装置启动,方法为:『swapon 装置文件名』。
  4. 观察:最终透过free 与swapon -s 这个指令来观察一下内存的用量

命令示例

查看文件系统的磁盘用量

1
2
3
4
5
6
7
8
9
[root@study ~]# df -h
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/centos-root 10G 3.3G 6.8G 33% /
devtmpfs 613M 0 613M 0% /dev
tmpfs 623M 80K 623M 1% /dev/shm
tmpfs 623M 25M 599M 4% /run
tmpfs 623M 0 623M 0% /sys/fs/cgroup
/dev/mapper/centos-home 5.0G 67M 5.0G 2% /home
/dev/vda2 1014M 131M 884M 13% /boo
  • Filesystem:代表该文件系统是在哪个partition ,所以列出装置名称;
  • Used:顾名思义,就是使用掉的磁盘空间啦!
  • Available:也就是剩下的磁盘空间大小;
  • Use%:就是磁盘的使用率啦!如果使用率高达90% 以上时,最好需要注意一下了,免得容量不足造成系统问题喔!(例如最容易被灌爆的/var/spool/mail 这个放置邮件的磁盘)
  • Mounted on:就是磁盘挂载的目录所在啦!(挂载点啦!)

列出系统上的所有磁盘列表

1
2
3
4
5
6
7
8
[root@study ~]# lsblk [-dfimpt] [device]
# 选项与参数:
# -d :仅列出磁盘本身,并不会列出该磁盘的分区数据
# -f :同时列出该磁盘内的文件系统名称
# -i :使用ASCII 的线段输出,不要使用复杂的编码(再某些环境下很有用)
# -m :同时输出该装置在/dev 底下的权限数据(rwx 的数据)
# -p :列出该装置的完整文件名!而不是仅列出最后的名字而已。
# -t :列出该磁盘装置的详细数据,包括磁盘队列机制、预读写的数据量大小等
  • NAME:就是装置的文件名啰!会省略 /dev 等前导目录!
  • MAJ:MIN:其实核心认识的装置都是透过这两个代码来熟悉的!分别是主要:次要装置代码!
  • RM:是否为可卸除装置(removable device),如光盘、USB 磁盘等等
  • SIZE:当然就是容量啰!
  • RO:是否为只读装置的意思
  • TYPE:是磁盘(disk)、分区槽(partition) 还是只读存储器(rom) 等输出
  • MOUTPOINT:就是前一章谈到的挂载点!

blkid 列出装置的UUID 等参数

parted 列出磁盘的分区表类型与分区信息。可以通过parted -l显示的Partition Table查看是什么类型的分区系统

1
2
3
4
5
6
7
8
9
[root@szpt /]# parted /dev/vda3 print
Model: Virtio Block Device (virtblk) # 磁盘的模块名称(厂商)
Disk /dev/vda3: 42.7GB # 磁盘的总容量
Sector size (logical/physical): 512B/512B # 磁盘的每个逻辑/物理扇区容量
Partition Table: loop # 分区表的格式(MBR/GPT)
Disk Flags:

Number Start End Size File system Flags
1 0.00B 42.7GB 42.7GB ext4

BASH

Shell(壳程序)作为应用程序,通过向Kernel(操作系统核心)发送指令,达到操作硬件设备/操作系统的目的。

只要能够操作应用程序的接口都能够称为壳程序。比如bash(Bourne Again SHell)。

系统上合法的shell需要写入/etc/shells文件,以限制服务使用者能够使用的shells。

使用者通过/cat /etc/passwd获取的最后一个数据即为可以取得的预设shell。如下的/bin/bash/sbin/nologin

1
2
3
[dmtsai@study ~]$ cat /etc/passwd
#root:x:0:0:root:/root:/bin/bash
#bin:x:1:1:bin:/bin:/sbin/nologin

变量

变量调用:$var

输出:echo ${var}。推荐用法

  • echo $var

赋值:name=FishingRod。无引号不能空格

  • name="My name is FishingRod"
  • name='FishingRod\'s name' 可用\转义
  • PATH=${PATH}:/home/dmtsai/bin变量添加
    • 其中${PATH}可以是"$PATH"$PATH
  • 可以活用,『version=$(uname -r)』『echo $version』可得『3.10.0-1160.76.1.el7.x86_64』

环境变量:export name。供其他程序执行

取消变量:unset name

read键入:将用户键入字符变为变量。read testecho ${test}查看。

  • [dmtsai@study ~]$ read -p "Please keyin your name: " -t 30 named
    Please keyin your name: VBird Tsai # 注意看,会有提示字符!
    [dmtsai@study ~]$ echo ${named}
    
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13

    declare:可以将变量变为环境变量`-x`、只读`-r`、变为非环境变量`+x`。

    #### 不同类型

    数组:

    ```bash
    [dmtsai@study ~]$ var[1]="small min"
    [dmtsai@study ~]$ var[2]="big min"
    [dmtsai@study ~]$ var[3]="nice min"
    [dmtsai@study ~]$ echo "${var[1]}, ${var[2]}, ${var[3]}"
    small min, big min, nice min

命令

别名 alias:将命令赋予别名。

通过lm直接运行ls -al

1
2
alias lm='ls -al'
unalias lm # 同理,取消别名

env:列出当前环境变量

1
2
HOSTNAME= #主机名
LOGNAME= #登入者名称

set:观察所有变量

1
2
3
RANDOM=12345 #随机数变量
OSTYPE=linux-gnu# 操作系统类型
HISTFILE=/home/dmtsai/.bash_history # 历史命令记录文档

locale:-a查看支持语系。

通常仅设定LANGLC_ALL这两个变量,中文建议设置LC_ALL

1
2
3
4
5
6
7
8
LANG=en_US.UTF-8                 <==主语言的环境
LC_CTYPE="en_US.UTF-8" <==字符(文字)辨识的编码
LC_NUMERIC="en_US.UTF-8" <==数字系统的显示讯息
LC_TIME="en_US.UTF-8" <==时间系统的显示数据
LC_COLLATE="en_US.UTF-8" <==字符串的比较与排序等
LC_MONETARY="en_US.UTF-8" <==币值格式的显示等
LC_MESSAGES="en_US.UTF-8" <==讯息显示的内容,如菜单、错误讯息等
LC_ALL= <==整体语系的环境
  • LC_ALL生效,需要使用export转成环境变量。export LC_ALL=en_US.utf8

通配符

符号 意义
* 代表『0 个到无穷多个』任意字符
? 代表『一定有一个』任意字符
[ ] 同样代表『一定有一个在括号内』的字符(非任意字符)。例如[abcd] 代表『一定有一个字符,可能是a, b, c, d 这四个任何一个』
[ -] 若有减号在中括号内时,代表『在编码顺序内的所有字符』。例如[0-9] 代表0 到9 之间的所有数字,因为数字的语系编码是连续的!
[^ ] 若中括号内的第一个字符为指数符号(^) ,那表示『反向选择』,例如[ ^abc ] 代表一定有一个字符,只要是非a, b, c 的其他字符就接受的意思。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
[dmtsai@study ~]$ LANG=C            <==由于与编码有关,先设定语系一下
范例一:找出/etc/ 底下以cron 为开头的档名
[dmtsai@study ~]$ ll -d /etc/cron* <==加上-d 是为了仅显示目录而已

范例二:找出/etc/ 底下文件名『刚好是五个字母』的文件名
[dmtsai@study ~]$ ll -d /etc/????? <==由于? 一定有一个,所以五个? 就对了

范例三:找出/etc/ 底下文件名含有数字的文件名
[dmtsai@study ~]$ ll -d /etc/*[0-9]*<==记得中括号左右两边均需 *

范例四:找出/etc/ 底下,档名开头非为小写字母的文件名:
[dmtsai@study ~]$ ll -d /etc/[^a-z]*<==注意中括号左边没有*

范例五:将范例四找到的文件复制到/tmp/upper 中
[dmtsai@study ~]$ mkdir /tmp/upper; cp -a /etc/[^a-z]* /tmp/upper

其他特殊符号

符号 内容
| 管线(pipe):分隔两个管线命令的界定
! 逻辑运算意义上的『非』not 的意思
>, >> 数据流重导向:输出导向,分别是『取代』与『累加』
<, << 数据流重导向:输入导向
; 连续指令下达分隔符:连续性命令的界定(注意!与管线命令并不相同)
1
2
3
4
[dmtsai@study ~]$ ll / > ~/rootfile # <==屏幕并无任何信息
[dmtsai@study ~]$ ll ~/rootfile # 有个新档被建立了
-rw-rw-r--. 1 dmtsai dmtsai 1078 Jul 9 18:51 /home/dmtsai/rootfile
# >, >>会创建文件
1
2
3
4
5
6
7
8
9
# 范例六:利用cat 指令来建立一个文件的简单流程
[dmtsai@study ~]$ cat > catfile
testing
cat file test
#这里按下[ctrl]+d 来离开
[dmtsai@study ~]$ cat catfile

# 也可以这样copy
[dmtsai@study ~]$ cat > catfile < ~/.bashrc

EOF

1
2
3
4
5
6
7
8
9
[dmtsai@study ~]$ cat > catfile << "eof"
> This is a test.
> OK now stop
> eof # =输入这关键词,立刻就结束而不需要输入[ctrl]+d

[dmtsai@study ~]$ cat catfile
This is a test.
OK now stop
#只有这两行,不会存在关键词那一行!

Shell Script

Shell Script 程序化脚本,将多个shell语法与指令搭配正则、管线命令、数据流重导向等功能结合为一个程序文件

执行差异

直接执行shell脚本时(如bash、shell),是在新的bash环境中执行的,子程序内的用户自定义变量不会被保存到父程序。

使用source执行指令使得脚本文件在父程序中执行,脚本中的用户自定义变量可以正常调用。

1
2
3
4
5
6
7
$(()) # 用于算术运算符
# $((1+1))
$() # 用于执行shell命令
# a=$(echo 123)
# echo $a
${} # 引用变量
# ${a}

${}的其他用法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
var="Hello World"
echo ${#var} # 输出字符串长度 —— 11
echo ${var:0:5} # 字符串切片 —— Hello
# echo ${var:5} # 字符串切片 —— World
echo ${var/World/WORLD} # 替换字符串 —— Hello WORLD

echo ${var% *} # 截取字符串,百分号后指定分隔符
Hello # 截取空格,% *输出截取前面部分的字符
echo ${var#* } # 截取字符串,百分号后指定分隔符
World # 截取空格,#* 输出截取后面部分的字符

var= # 变量状态赋值
echo ${var:-'123'} # 冒号条件判断,如果没有值则-输出123
echo ${var:='123'} # 冒号条件判断,如果没有值则-赋值123

案例


输入与输出

1
2
read -p "Please input your last name:  " lastname       # 提示使用者输入
echo -e "\nYour full name is: ${firstname} ${lastname}" # 结果由屏幕输出

强化,并建立文件

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
# 1. 让使用者输入文件名,并取得fileuser 这个变量;
echo -e "I will use 'touch' command to create 3 files." # 纯粹显示信息
read -p "Please input your filename: " fileuser # 提示使用者输入

# 2. 如果没有输入,filename为默认文件名
filename=${fileuser:-"filename"} # 如果没有输入(即用户直接按了 Enter 键),则使用默认的文件名 "filename"

# 3. 开始利用date 指令来取得所需要的档名了;
date1=$(date --date='2 days ago' +%Y%m%d) # 前两天的日期
date2=$(date --date='1 days ago' +%Y%m%d) # 前一天的日期
date3=$(date +%Y%m%d) # 今天的日期
file1=${filename}${date1} # 底下三行在配置文件名
file2=${filename}${date2}
file3=${filename}${date3}

# 4. 将档名建立吧!
touch "${file1}" # 底下三行在建立文件
touch "${file2}"
touch "${file3}

数值运算

1
2
3
# $((计算式))、有+-*/%
echo $(( 13 % 3 )) # 1、但是只支持整数
echo "123.123*55.9" | bc

判断

1
2
3
4
5
6
7
8
read -p "Please input (Y/N): " yn
# -o为或
[ "${yn}" == "Y" -o "${yn}" == "y" ] && echo "OK, continue" && exit 0
[ "${yn}" == "N" -o "${yn}" == "n" ] && echo "Oh, interrupt!" && exit 0
echo "I don't know what your choice is" && exit 0
# 输入y/n/?均会触发exit 0的退出指令
# [ "${yn}" == "N" -o "${yn}" == "n" ]可以替换为
# [ "${yn}" == "Y" ] || [ "${yn}" == "y" ]

if语句

1
2
3
4
5
6
7
if [ boolean ]; then
# 指令内容
elif [ boolean ]; then
# 指令内容
else
# 指令内容
fi # if的结束语句

使用netstat -tuln获取目前已启动的服务端口

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
testfile=/dev/shm/netstat_checking.txt
netstat -tuln > ${testfile} # 先转存数据到内存当中!不用一直执行netstat
testing=$(grep ":80 " ${testfile}) # 侦测看port 80 在否?
if [ "${testing}" != "" ]; then
echo "WWW is running in your system."
fi
testing=$(grep ":22 " ${testfile}) # 侦测看port 22 在否?
if [ "${testing}" != "" ]; then
echo "SSH is running in your system."
fi
testing=$(grep ":21 " ${testfile}) # 侦测看port 21 在否?
if [ "${testing}" != "" ]; then
echo "FTP is running in your system."
fi
testing=$(grep ":25 " ${testfile}) # 侦测看port 25 在否?
if [ "${testing}" != "" ]; then
echo "Mail is running in your system."
fi

case…esac语句

1
2
3
4
5
6
7
8
9
10
11
12
case $variable in
"1")
# 指令内容
;;
"2")
# 指令内容
;;
*)
# 指令内容
exit 1
;;
esac

脚本输入参数

1
2
3
4
5
6
7
# sh how_paras.sh theone haha quot
echo "脚本名称为 ==> ${0}" # how_paras.sh
echo "总共参数数量 ==> $#" # 3
[ "$#" -lt 2 ] && echo "输入的参数数量不能少于2,停止运行。" && exit 0
echo "全部参数 ==> '$@'" # 'theone haha quot'
echo "第1个参数 ==> ${1}" # theone
echo "第2个参数 ==> ${2}" # haha

shift可以拿掉参数

1
2
3
4
5
6
7
8
9
# sh shift_paras.sh 1 2 3 4 5 6
echo "总共 ==> $#" # 6
echo "现在的参数 ==> '$@'" # 123456
shift

echo "现在的参数 ==> '$@'" # 2345
shift 3

echo "现在的参数 ==> '$@'" # 56

函数

1
2
3
4
function funcname(){
echo "函数内部 ${1} and ${2}"
}
funcname 'var1' 'var2'

循环

1
2
3
4
while [ boolean ] # 不成立即停止
do # 循环开始
# 指令内容
done # 循环结束
1
2
3
4
until [ boolean ] # 成立即停止
do # 循环开始
# 指令内容
done # 循环结束
1
2
3
4
for var in iterable # iterable可迭代对象,可以是seq 1 100
do
# 指令内容
done
1
2
3
4
for (( i=1; i<=100; i=i+1 ))
do
# 指令内容,会循环100次
done

debug

1
2
3
4
5
[dmtsai@study ~]$ sh [-nvx] scripts.sh
选项与参数:
-n :不要执行script,仅查询语法的问题;
-v :再执行sccript 前,先将scripts 的内容输出到屏幕上;
-x :将使用到的script 内容显示到屏幕上,这是很有用的参数

test,检测文件是否存在

1
2
3
4
test -e /dmtsai # 检查/dmtsai 是否存在
# 结合算术运算符
test -e /dmtsai && echo "exist" || echo "Not exist"
# Not exist
标志 意义
关于某个档名的『文件类型』判断 如test -e filename 表示存在否
-e 该『档名』是否存在?(常用)
-f 该『档名』是否存在且为文件(file)?(常用)
-d 该『文件名』是否存在且为目录(directory)?(常用)
-b 该『档名』是否存在且为一个block device 装置?
-c 该『档名』是否存在且为一个character device 装置?
-S 该『档名』是否存在且为一个Socket 文件?
-p 该『档名』是否存在且为一个FIFO (pipe) 文件?
-L 该『档名』是否存在且为一个连结档?
关于文件的权限侦测 如test -r filename 表示可读否(但root 权限常有例外)
-r 侦测该档名是否存在且具有『可读』的权限?
-w 侦测该档名是否存在且具有『可写』的权限?
-x 侦测该档名是否存在且具有『可执行』的权限?
-u 侦测该文件名是否存在且具有『SUID』的属性?
-g 侦测该文件名是否存在且具有『SGID』的属性?
-k 侦测该文件名是否存在且具有『Sticky bit』的属性?
-s 侦测该档名是否存在且为『非空白文件』?
两个文件之间的比较 如:test file1 -nt file2
-nt (newer than)判断file1 是否比file2 新
-ot (older than)判断file1 是否比file2 旧
-ef 判断file1 与file2 是否为同一文件,可用在判断hard link 的判定上。主要意义在判定,两个文件是否均指向同一个inode 哩!
关于两个整数之间的判定 test number1 -eq number2
-eq 两数值相等(equal)
-ne 两数值不等(not equal)
-gt number1 大于number2 (greater than)
-lt number1 小于number2 (less than)
-ge number1 大于等于number2 (greater than or equal)
-le number1 小于等于number2 (less than or equal)
判定字符串的数据
test-z string 判定字符串是否为0 ?若string 为空字符串,则为true
test -n string 判定字符串是否非为0 ?若string 为空字符串,则为false。注:-n 亦可省略
test str1 == str2 判定str1 是否等于str2 ,若相等,则回传true
test str1 != str2 判定str1 是否不等于str2 ,若相等,则回传false
多重条件判定 例如:test -r filename -a -x filename
-a(and) 两状况同时成立!例如test -r file -a -x file,则file 同时具有r 与x 权限时,才回传true。
-o(or) 两状况任何一个成立!例如test -r file -o -x file,则file 具有r 或x 权限时,就可回传true。
! 反相状态,如test ! -x file ,当file 不具有x 时,回传true


鸟哥的Linux私房菜笔记
https://www.fishingrodd.cn/2024/08/26/鸟哥的Linux私房菜笔记/
作者
FishingRod
发布于
2024年8月26日
许可协议