ekwong.cn

尔康的博客

0%

序号 事项 具体操作 检验结论 备注
1 检查轮胎生产日期 后两位数字表示年份,前两位数字表示第几周,例如 3220 表示 2020 年第 32 周生产
2 检查玻璃生产日期 数字代表年份的最后一值,小黑点代表季度,大黑点代表该季度的第几个月
3 行驶里程 检查仪表盘行驶里程,尽量不可多于40KM;
4 生产铭牌 一般在副驾驶A柱下方
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 中控屏 检查功能是否正常,carlife、carplay 使用是否正常、
38 油箱盖子 检查邮箱盖子打开是否正常,关闭能否关紧
39 接口 检查 USB/Type-C 是否能正常充电
40 泊车 检查自动泊车入库功能是否正常
41 天窗 电动天窗开启和关闭是否正常,是否有遮阳帘,功能是否正常
42 应急用品 是否有备胎、补胎工具是否齐全、有没配送三脚架
43 钥匙 是否支持无钥匙进入,车钥匙一共多少把
44 保险 检查保险生效日期,交强险是即时生效的,看商业险是否即时生效的

上川岛自驾游要点

概述

上川岛自然风光秀丽,开发程度低,适合对海岛自然风光有兴趣的朋友去旅游。

地理和交通

位置

广东省江门市台山市,从地图上可看出,距离山咀港大概10海里,与西边的下川岛隔海相望。

交通

岛上有港口三洲港、沙堤港(渔港)。

游客可从山咀港搭渡轮到达三洲港。

从三洲港到飞沙滩,有旅游大巴,单次10块钱。

岛上公交仅对岛民开放。

若自驾,可在山咀港货运码头将车开到货船上,由货船将车运到三洲港。

山咀港货船相关

  1. 前往三洲港的货船,第一趟大概早上6点,第二趟大概早上10点,第三趟大概中午12点,
    第四趟大概下午4点,第五趟大概晚上8点。
  2. 货船单程大概一个小时(看当天风浪潮汐情况)
  3. 每趟船大概能装28~32辆小汽车,大货车优先登船,货船登船后,剩余的位置留给小汽车登船。
  4. 每趟船,排队在前10的小汽车司机,可跟货船一起搭到三洲港(跟车)。 而排在后面小汽车司机,则需要自行搭客运船前往三洲港(寄车)。
  5. 需要寄车的游客,可在货运码头登记手机号码、车牌号码,把车钥匙留给工作人员,带走贵重物品。 工作人在货运船到达后,会把车开上船。 车被运到三洲港后,工作人员会打电话通知游客前来取车。
  6. 请注意开车排队的时间。周六日游客较多,五菱宏光到货运码头时,时间8点零几分,排队的车已经超过 20 辆。
    九点钟的货船到了之后,工作人员告知,五菱宏光排不上这趟船,要排到 12点 的船,于是办理寄船。
  7. 办理好寄车后,司机可自行前往客运码头搭船前往三洲港。
  8. 小汽车运送至三洲港收费250块,寄车服务免费。需要出示行驶证、健康码。

加油站

岛上似乎没有常见的中石油、中石化加油站,但有民营加油站(小型、微型),甚至部分加油站连牌子都没有。

油品尚不清楚,五菱宏光加满油才上岛,所以不知道。

充电桩

尚不清楚,没充电需求,不关注。
岛上很少看到电动车。

食宿

酒店

  1. 价格不便宜,周五周六和节假日,普通酒店三百多,工作日降到两百;
  2. 主要分布在三洲港和飞沙滩,飞沙滩的偏贵;
  3. 飞沙滩的酒店都没洗衣机,只有一个酒店有烘干机,但不好用;
  4. 酒店装修稍显陈旧,部分酒店空调是一体机;
  5. 据说海景房不错,不过可能有点吵闹(下面是热闹的街);
  6. 绝大部分酒店没泳池,靠近望鱼石那边的酒店,带泳池;

民宿

民宿似乎做得不好,从图片看就像广州的城中村出租屋。

餐饮

大餐

  1. 飞沙滩景区内有很多餐饮店,价格相对偏贵;
  2. 三洲港的餐饮店性价比相对高;
  3. 三洲港的石斑鱼很好吃,肉很结实,很鲜美;
  4. 岛上的海鲜相对好吃(对比鸡肉、鸭肉、猪肉、牛肉);
  5. 靠近高冠村那边,有山羊;
  6. 三洲港码头餐饮店、大排档晚上搬到外面,可边欣赏晚霞,边吃饭;
  7. 飞沙滩晚上餐饮兴旺,人流量大,密度类似广州城中村;
  8. 银滩附近有餐饮店;

休闲

  1. 飞沙滩有烧烤档,晚上营业,就在海边;
  2. 飞沙滩有酒吧,晚上营业,就在海边;
  3. 飞沙滩有奶茶店,中午、下午、晚上营业;
  4. 飞沙滩有商业一条街,晚上热闹非凡,像村里趁墟(粤语,赶集);
  5. 三洲港也有烧烤档;
  6. 三洲港有普通快餐店,在三洲市场附近;
  7. 银滩附近有漂亮的酒吧;

野炊

  1. 景区内似乎不给野炊;
  2. 郊外野炊,可在三洲市场购买食材;

沙滩

  1. 飞沙滩朝东边,早上适合看日出;
  2. 飞沙滩人特别多,晚上有灯光;
  3. 飞沙滩的商业街有售烟花;
  4. 飞沙滩有沙滩车、摩托艇、滨海浴场;
  5. 公湾沙滩的沙子很细,水很干净;
  6. 公湾沙滩属于野沙滩,无人管理,有少量垃圾;
  7. 银滩水较深,浪比较大;
  8. 银滩沙里有玻璃碎片,注意穿拖鞋;

滩涂

  1. 滩涂贝壳、螃蟹较多,含泥量也多;
  2. 牛过咀一带海湾,以前养鸭,小螃蟹、生蚝、花甲之类很多;
  3. 白沙湾、贯草湾一带,适合挖螃蟹;

海景

  1. 公湾的海水湛蓝,风景漂亮;
  2. 望鱼石可俯瞰飞沙滩;
  3. 银滩风景很不错,那边有婚纱摄影基地;
  4. 沙堤港拍摄渔港风情很漂亮;
  5. 官冲湾海景也很漂亮;

租船出海

  1. 价格大概400块一次;
  2. 每次最多8个游客;
  3. 是普通的小渔船,由渔民带到附近海域;
  4. 船上安全设备不多;
  5. 浪大时,晕船玩家不适宜出海;

其它

不宜多提,美好的风景需要自行探索。

气象

台风

山咀港到三洲港,大概10海里。

台风期间渡轮可能停运,注意出行时,港口的告示。

台风前后,海浪相对较大,搭船可能比较颠簸。

台风过后,沙滩、滩涂、海里的鱼相对变多。

潮汐

潮汐会影响船舶航行、渔业、滩涂的虾蟹贝壳海参海胆。

潮汐分为 小潮、中潮、大潮。

每日都有潮水最高点和潮水最低点,潮水最低点时,海边的沙滩露出部分越大,越容易挖到虾蟹贝壳海参海胆。

潮汐的时间可咨询当地渔民,或网上查询,例如在 https://www.chaoxibiao.net/chaxun.html 可查询潮汐时间。

Run

执行 ssc_gen.sh 文件即可:

1
bash ssc_gen.sh

说明

文件

执行脚本后,会生成以下文件

1
2
3
4
5
6
7
-rw-r--r--  1 ekwong  staff   1.9K  1 24 14:21 ca.crt
-rw-r--r-- 1 ekwong staff 3.2K 1 24 14:21 ca.key
-rw-r--r-- 1 ekwong staff 17B 1 24 14:21 ca.srl
-rw-r--r-- 1 ekwong staff 2.2K 1 24 14:21 example.com.crt
-rw-r--r-- 1 ekwong staff 1.7K 1 24 14:21 example.com.csr
-rw-r--r-- 1 ekwong staff 3.2K 1 24 14:21 example.com.key
-rw-r--r-- 1 ekwong staff 267B 1 24 14:21 v3.ext

这里着重关注四个文件:

1
2
3
4
5
6
7
8
9
# 证书颁布机构的证书
ca.crt
# 证书颁布机构的私钥
ca.key

# 服务器证书
example.com.crt
# 服务器证书私钥
example.com.key

使用方法

以 nginx 配置作为 web 服务器,Windows 机器作为 client 为例。

server

请把 example.com.crtexample.com.key 上传到服务器,并配置修改 nginx.conf :

1
2
3
4
5
6
7
8
9
10
http{
...
server{
listen 443 ssl;
ssl_certificate /home/ca/example.com.crt;
ssl_certificate_key /home/ca/example.com.key;
...
}
...
}

请重启 nginx 服务:

1
nginx -s reload

client

请把 ca.crt 放到 Windows 机器上,并添加为受信任的证书。

自定义

若需自定义证书颁布机构域名、服务器域名、过期时间等信息,请修改 custom.cf 文件,请把 custom.cf 文件和 ssc_gen.sh 文件放在同一目录下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ca_numbits=4096
ca_c=CN
ca_st=Beijing
ca_l=Beijing
ca_o=Ca
ca_ou=Personal
ca_cn=self.ca.org
ca_days=3650

svr_numbits=4096
svr_domain=example.com
svr_c=CN
svr_st=Beijing
svr_l=Beijing
svr_o=Example
svr_ou=Personal
svr_days=3650
svr_host=localhost.domain

关于

本脚本内容代码见 Github仓库

脚本及配置

ssc_gen.sh

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
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
#!/bin/bash
# self sign certificate

function getValue() {
key=${1}
default_value=${2}
result=""
if [[ -f custom.cf ]]; then
result=`grep "${key}=" custom.cf | awk -F'=' '{print $2}'`
fi
if [[ -z ${result} ]]; then
result="${default_value}"
fi
echo ${result}
return 0
}

echo "generate self sign certificate"

version=`openssl "version"`

echo "using $version"

ca_numbits=`getValue "ca_numbits" "4096"`

echo "generate ca key using numbits ${ca_numbits}"
openssl genrsa -out ca.key ${ca_numbits}

ca_c=`getValue ca_c "CN"`
ca_st=`getValue ca_st "Beijing"`
ca_l=`getValue ca_l "Beijing"`
ca_o=`getValue ca_o "Ca"`
ca_ou=`getValue ca_ou "Personal"`
ca_cn=`getValue ca_cn "self.ca.org"`
ca_days=`getValue ca_days "3650"`

echo "generate ca crt for ${ca_cn}"
openssl req -x509 -new -nodes -sha512 -days ${ca_days} \
-subj "/C=${ca_c}/ST=${ca_st}/L=${ca_l}/O=${ca_o}/OU=${ca_ou}/CN=${ca_cn}" \
-key ca.key \
-out ca.crt

svr_numbits=`getValue "svr_numbits" "4096"`

svr_domain=`getValue svr_domain "example.com"`
svr_c=`getValue svr_c "CN"`
svr_st=`getValue svr_st "Beijing"`
svr_l=`getValue svr_l "Beijing"`
svr_o=`getValue svr_o "Example"`
svr_ou=`getValue svr_ou "Personal"`
svr_days=`getValue svr_days "3650"`
svr_host=`getValue svr_host "localhost.domain"`

echo "generate server key using numbits ${svr_numbits}"
openssl genrsa -out "${svr_domain}.key" ${svr_numbits}

echo "generate certificate sign request "
openssl req -sha512 -new \
-subj "/C=${svr_c}/ST=${svr_st}/L=${svr_l}/O=${svr_o}/OU=${svr_ou}/CN=${svr_domain}" \
-key "${svr_domain}.key" \
-out "${svr_domain}.csr"

echo "generate x509 v3 ext file"
echo "authorityKeyIdentifier=keyid,issuer" > v3.ext
echo "basicConstraints=CA:FALSE" >> v3.ext
echo "keyUsage = digitalSignature, nonRepudiation, keyEncipherment, dataEncipherment" >> v3.ext
echo "extendedKeyUsage = serverAuth" >> v3.ext
echo "subjectAltName = @alt_names" >> v3.ext
echo "" >> v3.ext
echo "[alt_names]" >> v3.ext
echo "DNS.1=${svr_domain}" >> v3.ext
echo "DNS.2=${svr_domain%.*}" >> v3.ext
echo "DNS.3=${svr_host}" >> v3.ext

echo "generate server crt for ${svr_domain}"
openssl x509 -req -sha512 -days ${svr_days} \
-extfile v3.ext \
-CA ca.crt -CAkey ca.key -CAcreateserial \
-in "${svr_domain}.csr" \
-out "${svr_domain}.crt"

custom.cf

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
ca_numbits=4096
ca_c=CN
ca_st=Beijing
ca_l=Beijing
ca_o=Ca
ca_ou=Personal
ca_cn=self.ca.org
ca_days=3650

svr_numbits=4096
svr_domain=example.com
svr_c=CN
svr_st=Beijing
svr_l=Beijing
svr_o=Example
svr_ou=Personal
svr_days=3650
svr_host=localhost.domain

在工作中经常需要写 shell 脚本,为了方便观察脚本执行情况,经常需要执行一些打印操作。在打印的文案中,可能带有一些敏感信息,例如用户账号、密码等。出于安全考虑,需要对一些敏感字符执行屏蔽。

这时候可以看到常见的方案:

把敏感信息写在一个变量集合中 $msg_array,在脚本执行结束逻辑,调用 sed命令对 log 文件进行一遍过滤。

这个方案在需要确保脚本能执行到 sed 的逻辑,若脚本提前退出或进程被杀死,敏感信息会留在 log 文件中,从而产生安全问题。

于是有另一个方案出现:

把打印 log 都调用相同的方法,在该方法中过滤敏感信息,打印过滤后的信息。

这里稍微使用了 eval 命令,实现了把敏感信息替换成 xxx

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#!/bin/bash

params="username,password"
msg_array=(${params//,/ })

function common_log(){
local msg=$1
echo "now we get msg $msg"
for s in ${msg_array[@]}
do
eval tmp="\$$s"
msg=${msg/$tmp/xxx}
done
echo $msg
}

username="Jack"
password="123"

msg="create user with name $username and password $password"

common_log "$msg"

执行以上脚本,将得到输出:

1
2
now we get msg create user with name Jack and password 123
create user with name xxx and password xxx

Mac 下树莓派3B+烧录 Centos 7

硬件准备

  • Mac 电脑
  • 读卡器
  • SD卡
  • 树莓派3B+

安装

1 下载centos系统镜像

可以前往centos官网下载arm版的centos 7镜像,

下载下来的是 .xz 文件,解压后可得到 .img 或者 .raw 文件。例如我这里解压后,得到

1
CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1908-sda.raw

*2 写入SD卡 *

把SD卡插入电脑,然后在命令行查看当前的硬盘情况:

1
diskutil list

例如我这里,/dev/disk2 就是我的SD卡了

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
ekwong  ~  diskutil list
/dev/disk0 (internal, physical):
#: TYPE NAME SIZE IDENTIFIER
0: GUID_partition_scheme *500.3 GB disk0
1: EFI EFI 314.6 MB disk0s1
2: Apple_APFS Container disk1 500.0 GB disk0s2

/dev/disk1 (synthesized):
#: TYPE NAME SIZE IDENTIFIER
0: APFS Container Scheme - +500.0 GB disk1
Physical Store disk0s2
1: APFS Volume Macintosh HD - 数据 223.5 GB disk1s1
2: APFS Volume Preboot 82.8 MB disk1s2
3: APFS Volume Recovery 528.5 MB disk1s3
4: APFS Volume VM 3.2 GB disk1s4
5: APFS Volume Macintosh HD 11.0 GB disk1s5

/dev/disk2 (external, physical):
#: TYPE NAME SIZE IDENTIFIER
0: FDisk_partition_scheme *15.9 GB disk2
1: Windows_FAT_32 NO NAME 299.9 MB disk2s1
2: Linux 15.6 GB disk2s2

卸载SD卡:

1
diskutil unmountDisk /dev/disk2 # 把这里的 /dev/disk2 修改成你的 SD 卡磁盘名称

烧录镜像:

1
2
# 把文件路径指向你解压出来的镜像文件,把 /dev/disk2 修改成你的 SD 卡磁盘名称
sudo dd bs=4m if=~/Downloads/CentOS-Userland-7-armv7hl-RaspberryPI-Minimal-1908-sda.raw of=/dev/rdisk2

这时候,命令行会没有什么输出,过几分钟后,会有如下输出:

1
2
3
578+0 records in
578+0 records out
2424307712 bytes transferred in 212.299948 secs (11419257 bytes/sec)

说明烧录好了。

再次卸载SD卡:

1
diskutil unmountDisk /dev/disk2 # 把这里的 /dev/disk2 修改成你的 SD 卡磁盘名称
3 初始化Centos 7

拔出SD卡,插入树莓派内,树莓派连接显示器和键盘,接通电源。

初始账号:root

密码: centos

修改一下密码:

1
sudo passwd

查看网卡信息

1
ifconfig

找到设备的内网IP,例如我的内网IP是 192.168.200.209

4 远程登录

在Mac上打开命令行,输入

1
2
3
# 把本地public key保存到树莓派的CentOS 7, 后面登录就无需输入密码
# 把IP地址改成你的树莓派IP地址
ssh-copy-id root@192.168.200.209

然后进行登录:

1
2
# 把IP地址改成你的树莓派IP地址
ssh root@192.168.200.209
5 调整磁盘大小

默认情况下,刚安装好时,查看磁盘只有2G容量,

1
2
3
4
5
6
7
8
9
[root@bogon ~]# df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/root 1.4G 1.2G 212M 85% /
devtmpfs 459M 0 459M 0% /dev
tmpfs 464M 0 464M 0% /dev/shm
tmpfs 464M 13M 451M 3% /run
tmpfs 464M 0 464M 0% /sys/fs/cgroup
/dev/mmcblk0p1 286M 52M 235M 19% /boot
tmpfs 93M 0 93M 0% /run/user/0

但我的SD卡是16G的啊,于是要调整一下。

在root目录下,就有一个README文档,打开看一下

1
2
3
4
5
[root@bogon ~]# cat README 
== CentOS 7 userland ==

If you want to automatically resize your / partition, just type the following (as root user):
rootfs-expand

很好,直接有个指令可以让我们拓展容量,直接输入指令

1
rootfs-expand

然后查看容量:

1
2
3
4
5
6
7
8
9
 df -h
文件系统 容量 已用 可用 已用% 挂载点
/dev/root 14G 1.2G 13G 9% /
devtmpfs 459M 0 459M 0% /dev
tmpfs 464M 0 464M 0% /dev/shm
tmpfs 464M 13M 451M 3% /run
tmpfs 464M 0 464M 0% /sys/fs/cgroup
/dev/mmcblk0p1 286M 52M 235M 19% /boot
tmpfs 93M 0 93M 0% /run/user/0

大功告成!

Shell 脚本基础

Shell脚本一般用 .sh 作为后缀

例如我们编写一个 exmple.sh

1
2
3
4
5
#!/bin/bash
# example shell script
ls
pwd
free -m

Shell脚本一般会分为三种元素:

第一行是脚本声明,告知系统使用哪种Shell解析器来执行该脚本;

第二行的注视用于描述脚本功能和备注;

第三行开始,才是脚本程序的内容部分。

接收用户参数

使用Shell脚本语句时,需要输入的参数可以直接在脚本命令后输入,以空格分开,例如

1
./example.sh arg1 arg2 arg3 ...

在脚本内部,可以使用美元符号💲+数字来接收参数相关内容,例如:

  • $0 可以获取当前脚本的名称
  • $# 可以获取当前脚本的参数个数
  • $* 可以获取当前脚本的所有参数
  • $数字 可以获取当前脚本的某个具体参数(从1开始),例如$1获取脚本输入的第一个参数,而$3获取脚本输入的第三个参数
  • $? 是显示最后命令的退出状态,0表示没有错误,其它表示有错误

判断条件

在Shell脚本语句中,条件判断式的写法如下:

1
if [ 条件测试语句 ]

注意,测试语句的左右两边各有一个空格

按照测试的对象来分,测试语句可以分为四种:

  • 文件测试语句;
  • 逻辑测试语句;
  • 整数值比较语句;
  • 字符串比较语句;
文件测试

文件测试是指判断文件是否存在、文件的类型和文件的权限等情况,常用的参数如下:

参数 作用
-d 判断文件是否为目录类型
-e 判断文件是否存在
-f 判断是否为一般文件类型
-r 判断当前用户是否有权读取
-w 判断当前用户是否有权写入
-x 判断当前用户是否有权执行
逻辑测试

在逻辑测试语句中,运算符如下:

  • “与”运算的符号是 &&
  • “或”运算的符号是 ||
  • “非”运算的符号是在运算逻辑前加 !
整数值比较

整数值运算只能是对数字进行操作,不能将数字与字符串、文件等进行比较。其运算符如下:

运算符 含义
-eq 等于
-ne 不等于
-gt 大于
-lt 小于
-ge 大于等于
-le 小于等于
字符串比较

用于测试字符串是否为空、判断两字符串是否相同。其运算符如下:

运算符 含义
= 比较字符串内容是否相同
!= 判断字符串内容是否不相同
-z 判断字符串内容是否为空

流程控制语句

if条件语句

结尾必须带 fi。

单分支判断逻辑写法如下:

1
2
3
4
if 条件判断
then
执行逻辑
if

双分支判断语句写法如下:

1
2
3
4
5
6
if 条件判断
then
执行逻辑1
else
执行逻辑2
fi

多分枝判断语句写法如下:

1
2
3
4
5
6
7
8
9
10
if 条件判断1
then
执行逻辑1
elif 条件判断2
then
执行逻辑2
...
else
执行逻辑n
fi
for循环语句

结尾必须带 done,写法如下:

1
2
3
4
for 变量名 in 变量集合
do
执行逻辑
done
while循环语句

结尾必须带done,可以用 exit 语句进行退出,写法如下:

1
2
3
4
while 条件判断
do
执行逻辑
done
case条件语句

结尾必须带 esac,写法如下:

1
2
3
4
5
6
7
8
9
10
11
case 变量值 in
模式1)
执行逻辑1
;;
模式2)
执行逻辑2
;;
...
*)
默认执行逻辑
esac

前置条件

  1. 电脑已开启 CPU 虚拟化。(Windows系统可在 BIOS 界面设置);
  2. CPU 为多核;
  3. 磁盘有空余空间

准备

Virtual Box

本方案需要使用 Virtual Box 来运行 CentOS 7 系统,所以需要在电脑上安装 Virtual Box。

请到 Virtual Box 的官网下载安装包,并安装;

CenOS 7

可在 CentOS 官网找到下载指引,下载 CentOS 7 的 iso 文件,或直接在阿里云的镜像提供点下载;在这里,请选择 CentOS-7-x86_64-Minimal-2003.iso 文件,这是最小安装文件,用这个文件就可以啦。

安装

安装过程分为两步:创建虚拟机和安装 CentOS7 系统;

创建虚拟机

可以按照以下步骤执行创建虚拟机:

  1. 打开VirtualBox,点击上方新建按钮;
  2. 输入你的虚拟机名字,这里我们可以输入 CentOS7,选择类型为 Linux ,选择版本为 Red Hat(64-bit),点击继续;
  3. 给虚拟电脑配置内存大小,这个内存大小是后面是可以调整的,给 2048 MB,点击继续;
  4. 创建虚拟硬盘,选择现在创建虚拟硬盘,点击创建;
  5. 选择虚拟硬盘文件类型,使用默认的 VDI 类型就可以,点击继续;
  6. 选择虚拟硬盘的存放方式,这里建议选择固定大小,点击继续;
  7. 给虚拟硬盘选择存放位置和大小,注意这里的硬盘大小,就是创建之后虚拟机的硬盘大小,请根据你的实际需要输入,点击继续;

安装 CentOS7 系统

创建虚拟机成功后,在 VirtualBox 的面板上,可以看到新创建出来的一个设备。可以按照以下操作,安装虚拟机:

  1. 选择该虚拟机,点击设置,选择系统 -> 处理器,设置为两个处理器,点击确定;
  2. 选择该虚拟机,点击设置,选择存储 -> 控制器:IDE -> 没有盘片,然后鼠标移到右边的 属性->分配光驱右边的按钮,点击该光盘按钮,选择 “选择一个虚拟光盘文件”,然后选择之前下载的 CentOS-7-x86_64-Minimal-2003.iso文件,点击 OK;
  3. 选择该虚拟机,点击启动,就可以看到出来一个新的窗口,选择 安装 CentOS7,进入正式的安装流程,进入正式安装后,鼠标和键盘输入会被虚拟机捕获,鼠标会一直在虚拟机的框框内出不来。如需要把鼠标移到虚拟机外,Mac OSX 用户请按左 Command 键,Windows 和 Ubuntu 用户请按右侧 Ctl 键,鼠标就可以出来啦;
  4. 选语言为 英语-美国,键盘为美式键盘;点击下一步;
  5. 选择安装目标( INSTALLATION DESTINATION ),这里是让你选择把 CentOS系统安装到哪个硬盘上看,点击左上角的 “Done” 即可,回到外面窗口,点击 开始安装;
  6. 这时候可以看到,下方的进度条已经开始动了,可以设置 root 密码,点击设置 root 密码,需要输入两次,点击确定按钮两次,等待安装完成;
  7. 安装完成后,会提示让你重启,点击重启系统;

基础设置

安装并重启后,需要进行一些基础设置:

  1. 设置电脑开启时启动网络。重启后,进入系统,输入账号密码登录,修改网卡设置,请到 /etc/sysconfig/network-scripts/ 目录下修改对应的配置文件( ifcfg-en 开头的文件);

    1
    2
    cd /etc/sysconfig/network-scripts/
    vi ifcfg-enp0s3

    把 ONBOOT 设置为 yes ,即:

    1
    ONBOOT=yes

    保存并退出,关闭虚拟机:

    1
    shutdown now
  2. 设置虚拟机的网卡模式。虚拟机关闭后,选择该虚拟机,点击设置,选择网络 -> 网卡1,设置连接方式为 桥接网卡,点击确定。原因:默认情况下,虚拟机获得的 IP 是 10.0.x.x 格式的,在实际使用的过程,我们需要虚拟机的 IP 为 192.168.x.x 的格式,所以需要设置为桥接模式;

在Docker官网https://docs.docker.com/get-started/看了一些文档,以下为文档大致摘要。

测试Kubernetes

在电脑上安装好 Docker Desktop后,点击设置,选择启用Kubernetes

新建一个文件,命名为 pod.yaml ,写入以下内容:

1
2
3
4
5
6
7
8
9
apiVersion: v1
kind: Pod
metadata:
name: demo
spec:
containers:
- name: testpod
image: alpine:3.5
command: ["ping", "8.8.8.8"]

在命令行输入以下命令执行这个 yaml文件,创建你的 pod

1
kubectl apply -f pod.yaml

检查你的 pod 是否在运行

1
kubectl get pods

关闭运行中的 pod

1
kubectl delete -f pod.yaml

启用 Docker Swarm

初始化

1
docker swarm init

运行一个简单的Docker服务,用基于alpine的文件系统,同样也是 ping 一下 8.8.8.8

1
docker service create --name demo alpine:3.5 ping 8.8.8.8

确认一下你的服务是否创造了一个正在运行的container:

1
docker service ps demo

确认你可以获取到相关的logs信息

1
docker service logs demo

最后,关闭测试服务

1
docker service rm demo

容器化一个应用

从GitHub的样例来建造一个image吧。

准备工作

1
2
git clone -b v1 https://github.com/docker-training/node-bulletin-board
cd node-bulletin-board/bulletin-board-app

Dockerfile 描述怎样为一个container编译一个私有文件系统,同时可以包含一些meta数据,这些meta数据描述如何运行一个基于此image的container。例如这个示例的Dockerfile的内容为:

1
2
3
4
5
6
7
8
FROM node:6.11.5

WORKDIR /usr/src/app
COPY package.json .
RUN npm install
COPY . .

CMD [ "npm", "start" ]

编写一个 Dockerfile 是容器化一个应用的第一步。你可以一步步地猜测这些 Dockerfile 命令如何构建我们的image。例如上述的文件含义如下:

  • 在现有的image (名字为 node:6.11.5)的基础上
  • 使用 WORKDIR 指定所有的后续操作都在image文件系统的 /usr/src/app 下执行,即指定本image(在容器中)的工作目录
  • 使用 COPY 指令将 package.json 文件从宿主复制到image的当前位置(.),在本例中,就是复制到image的 /usr/src/app/package.json
  • 使用 RUN 指令在你的image文件系统中执行 npm install 命令,在本例,会读取 package.json 文件来安装你的应用的依赖;
  • 使用 COPY 指令将你的应用的资源代码从宿主复制到image的文件系统

以上命令是用于构造我们的image的文件系统,CMD 指令在image中,指定一些meta数据描述如何基于此image运行一个container。在本例中,image容器化的过程是 npm install

构建和测试你的image

在 node-bulletin-board/bulletin-board-app 目录下,打开命令行,输入以下指令

1
docker image build -t bolletinboard:1.0 .

构建成功后,使用构建出来的image启动一个container,可以先查看当前宿主的image列表

1
docker image ls

然后找到刚构建出来的image id,在命令行运行:

1
2
3
docker container run -p 8000:8080 --detach --name bb $IMAGE_ID
# 若想公开多个端口
docker container run -p 8000:8080 -p 9000:9090 --detach --name bb $IMAGE_ID

在这里,我们用了一些flag,例如:

  • -p告知docker宿主与container的端口映射关系,例如本例中,宿主的端口 8000 映射到 container的端口 8080
  • –detach 要求Docker把此container在后台运行;
  • –name 给运行起来的container起一个名字为 bb;

值得注意的是,我们并没有指定container要运行什么。由于我们在构建image的时候,在Dockerfile中使用了CMD指令,当container运行起来时,Docker自动执行 npm run 命令。

可以使用以下指令查看正在运行的container

1
docker container ls

进入容器内部

1
docker exec -ti container_name /bin/bash

如果你需要停止容器,可以使用指令

1
docker container rm --force $CONTAINER_ID

若需删除image,可以使用指令:

1
2
3
docker image rm -f $IMAGE_ID
#
docker image rm -f $IMAGE_NAME:$TAG

配置仓库镜像

由于Docker的中央仓库位于国外,拉去image的时候,速度会比较慢,所以建议配置国内镜像

编辑 /etc/docker/daemon.json 文件(如果目录或文件不存在,则创建之)

添加一下内容:

1
2
3
4
5
6
7
8
9
{
...
# 增加这个,就是配置了网易的镜像
"registry-mirrors": [
"https://hub-mirror.c.163.com"
]
#
...
}

然后重启docker,以CentOS 7为例

1
2
systemctl stop docker
systemctl start docker

创建Docker私有仓库

此处内容参考官网文档

在本地运行私有仓库

在创建Docker私有仓库前,请确保你的设备已经安装了docker并且在运行。

一个私有仓库,其实就是一个 registry 镜像的运行实例,在本地运行一个registry实例,并且绑定在5000端口上

1
docker run -d -p 5000:5000 --restart=always --name registry registry:2

这样,本地的私有仓库就跑起来了。

把镜像推送到本地私有仓库

现在,我们罗列一下当前本地有哪些image:

1
2
3
4
5
6
7
8
9
10
11
12
[root@node01 ~]# docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
registry.aliyuncs.com/google_containers/kube-proxy v1.17.4 6dec7cfde1e5 4 weeks ago 116 MB
docker.io/ubuntu 16.04 77be327e4b63 6 weeks ago 124 MB
registry.aliyuncs.com/google_containers/kube-proxy v1.17.3 ae853e93800d 8 weeks ago 116 MB
docker.io/kubernetesui/dashboard v2.0.0-rc5 fe0df1b24096 2 months ago 126 MB
localhost:5000/cm_in_centos7_front latest 895a50dc2bb7 2 months ago 2.86 GB
docker.io/kubernetesui/metrics-scraper v1.0.3 3327f0dbcb4a 2 months ago 40.1 MB
docker.io/registry 2 708bc6af7e5e 2 months ago 25.8 MB
localhost:5000/cm_in_centos7 latest 001a9b846404 3 months ago 2.66 GB
quay.mirrors.ustc.edu.cn/coreos/flannel v0.11.0-amd64 ff281650a721 14 months ago 52.6 MB
registry.aliyuncs.com/google_containers/pause 3.1 da86e6ba6ca1 2 years ago 742 kB

当前本地有一个ubuntu:16.04的image,我们想它推送到本地私有仓库(本地和本地私有仓库是不同的!

先把这个image起个新的名字吧:

1
2
# docker tag $CURRENT_NAME:CURRENT_VERSION $NEW_NAME:NEW_VERSION
docker tag ubuntu:16.04 localhost:5000/my-ubuntu:16.04

然后把这个image推送到本地私有仓库:

1
docker push localhost:5000/my-ubuntu:16.04

这样,本地私有仓库就有这个 my-ubuntu:16.04 的image了。

搭建文档

设备要求

  • 至少三台 Linux 设备,即至少一台 master 两台 node;

  • 每台设备需要至少 2 核 CPU,8G 内存和 40G 硬盘空间;

  • Linux 系统需要支持 overlay2 存储驱动,可用指令 xfs_info / 查看系统是否支持,

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    ## 如果 ftype=1 ,说明支持 overlay2 驱动
    [root@localhost ~]# xfs_info /
    meta-data=/dev/mapper/centos-root isize=512 agcount=4, agsize=3276800 blks
    = sectsz=512 attr=2, projid32bit=1
    = crc=1 finobt=0 spinodes=0
    data = bsize=4096 blocks=13107200, imaxpct=25
    = sunit=0 swidth=0 blks
    naming =version 2 bsize=4096 ascii-ci=0 ftype=1
    log =internal bsize=4096 blocks=6400, version=2
    = sectsz=512 sunit=0 blks, lazy-count=1
    realtime =none extsz=4096 blocks=0, rtextents=0

安装

修改系统设置

修改主机名

为了方便起见,修改主机的 hostname,以三台机器为例:

1
2
3
4
5
6
## 在 master 机器
hostnamectl set-hostname master
## 在 node1 机器
hostnamectl set-hostname node1
## 在 node2 机器
hostnamectl set-hostname node2

然后退出登录,重新登录进来,就可以看到 hostname 已经更改了。

关闭防火墙

由于是自行练习 kubernetes 使用,建议直接关闭防火墙,避免很多网络问题。若在生产环境,请相关负责网络的同事处理相关网络问题。

1
2
systemctl stop firewalld
systemctl disable firewalld

关闭 selinux

需要关闭 selinux,可以编辑 /etc/selinux/config 文件,设置 SELINUX=disabled,重启设备:

1
vi /etc/selinux/config

关闭 swap

由于 kuberntes 集群子节点重启时,需要关闭 swap ,建议直接设置在 /etc/profile

1
2
3
4
5
## 编辑该文件
echo "swapoff -a" >> /etc/profile

## 保存后,使之生效
source /etc/profile

安装 docker-ce

因为 kubernetes 集群依赖于 docker,所以我们需要给所有的 设备安装 docker-ce,可以参照以下步骤或官网

由于设备上可能有旧的包,所以这里先要进行移除

1
2
3
4
5
6
7
8
yum remove docker \
docker-client \
docker-client-latest \
docker-common \
docker-latest \
docker-latest-logrotate \
docker-logrotate \
docker-engine

安装 yum 工具

1
yum install -y yum-utils

添加 docker 的仓库

1
2
3
yum-config-manager \
--add-repo \
https://download.docker.com/linux/centos/docker-ce.repo

现在,可以执行 docker 的安装了

1
yum install -y docker-ce docker-ce-cli containerd.io

启动 docker 并设置开机启动

1
2
systemctl start docker
systemctl enable docker

编辑 /etc/docker/daemon.json 添加网易 docker image 镜像源,添加如下内容 :

1
2
3
4
5
6
{
...
"registry-mirrors": ["https://hub-mirror.c.163.com/"],
"exec-opts": ["native.cgroupdriver=systemd"]
...
}

然后重启 docker:

1
systemctl restart docker

安装 kubeadm

kubeadm 是 kubernetes 集群的管理工具,所有的设备都必须安装这个工具才能加入集群,由于kubernetes 官网在国外,网络问题,我们使用阿里源来安装 kubeadm 工具

添加 yum 源:

1
2
3
4
5
6
7
8
9
10

cat <<EOF > /etc/yum.repos.d/kubernetes.repo
[kubernetes]
name=Kubernetes
baseurl=http://mirrors.aliyun.com/kubernetes/yum/repos/kubernetes-el7-x86_64
enabled=1
gpgcheck=1
repo_gpgcheck=1
gpgkey=http://mirrors.aliyun.com/kubernetes/yum/doc/yum-key.gpg http://mirrors.aliyun.com/kubernetes/yum/doc/rpm-package-key.gpg
EOF

更新 yum 源

1
yum update

安装 kubeadm

1
yum install kubeadm -y

启动 kubelet 并设置开机启动

1
2
systemctl enable kubelet
systemctl start kubelet

部署集群

如果您已安装了 kubernetes 所需的各软件后,就可以执行部署啦。

部署流程大致分为三步:

  1. 初始化 master 节点;
  2. 部署网络插件;
  3. 各 node 节点加入集群;

初始化 Master 节点

集群(英文:Cluster)需要在 master 节点进行初始化,基础指令是 kubeadm init,在这个教程中,我们指定一下 api server 的IP地址和 CIDR 的 IP段,请在 master 机器上执行集群的初始化:

1
kubeadm init  --apiserver-advertise-address 0.0.0.0 --pod-network-cidr 10.244.0.0/16

这个初始化的过程可能需要好几分钟,需要从 k8s 的官网拉取很多 image 下来,如果网络较差,时间可能会更久。

如果在 master 机器上,ping k8s.gcr.io 不通,请在这个指令后加上阿里云源参数 —image-repository registry.aliyuncs.com/google_containers

完整的指令则是:

1
kubeadm init  --apiserver-advertise-address 0.0.0.0 --pod-network-cidr 10.244.0.0/16 —image-repository registry.aliyuncs.com/google_containers

集群初始化后,会提示执行以下操作,创建配置目录和修改文件所有者信息:

1
2
3
mkdir -p $HOME/.kube
sudo cp -i /etc/kubernetes/admin.conf $HOME/.kube/config
sudo chown $(id -u):$(id -g) $HOME/.kube/config

集群初始化后,还会有一条允许其它 node 节点加入集群的提示语,类似下面,请保存下来,下面 node 节点加入集群需要用到。

1
kubeadm join 192.168.200.20:6443 --token yzifqp.6p8o99bxp08xxrcc  --discovery-token-ca-cert-hash sha256:5f656ae26b5e7d4641a979cbfdffeb7845cc5962bbfcd1d5435f00a25c02ea50

安装网络插件

集群中的 pod 进行通讯需要网络插件,我们这里使用 flannel 插件。若您需要使用其它网络插件,请在 kubernetes 官网查询。

网络插件本质,是一种 kubernetes 资源,flannel 的项目在 GitHub 上,对应的配置文件地址在这里。把文件下来下来,或复制配置内容,写入本地文件,保存为 .yml 类型,例如这里保存为 kube-flannel.yml

在 master 机器上,执行以下操作:

上传 kube-flannel.yml 文件,然后在文件所在目录下,部署该文件:

1
kubectl apply -f kube-flannel.yml

部署可能需要一点时间,可以查看部署情况:

1
2
# kubectl get pods -n kube-system | grep kube-flannel
kube-flannel-ds-amd64-g667t 1/1 Running 1 19h

如果状态显示 running ,则网络插件部署成功了。

在部署网络插件 flannel 的过程中,可能出现 image 拉取错误,可以查看 log 看看具体是什么问题,有时候可能是 quay.io 访问异常,可以替换 kube-flannel.yml 中的 image 源为七牛云源 quay-mirror.qiniu.com ,然后重新部署 flannel

各 node 节点加入集群

在完成了 master 节点初始化集群和安装网络插件后,可在各 node 节点机器 使用初始化完 master 节点后出现的加入集群指令来加入集群:

1
2
3
## 这里 192.168.200.20 是你的集群的 api server 的 ip,在本例中是 master 机器的 ip
## 这里 --token 后的字段和 sha256: 后的字段会不同
kubeadm join 192.168.200.20:6443 --token yzifqp.6p8o99bxp08xxrcc --discovery-token-ca-cert-hash sha256:5f656ae26b5e7d4641a979cbfdffeb7845cc5962bbfcd1d5435f00a25c02ea50

提示已成功加入集群后,可在 master 节点机器上查看各 node 节点机器信息:

1
kbuectl get nodes -o wide

常见问题

重置集群

在创建集群的时候,可能因安装出错而想要重新来过,此时,你可以重置集群,分别在 master 和各 node 机器上进行重置即可:

在 master 机器上执行:

1
2
3
4
kubeadm reset
rm -rf /etc/cni/net.d
rm -rf ~/.kube/config
rm -rf /var/lib/cni/

在 node 机器上执行:

1
2
3
kubeadm reset
rm -rf /etc/cni/net.d
rm -rf ~/.kube

某个 node 节点需重置

在 node 节点加入集群的操作中,可能出现想要重置这个节点,而其它机器不变的情况,那么需要在该节点上执行重置:

1
2
3
4
kubeadm reset
rm -rf /etc/cni/net.d
rm -rf ~/.kube
rm /etc/kubernetes/kubelet.conf /etc/kubernetes/pki/ca.crt

然后在 master 机器上执行以下指令,删除该 node 节点:

1
2
## 假设是 node3
kubectl delete pod node3

然后在 node3 的机器上重新执行加入集群操作即可。

部分 image 拉取很慢

在初始化集群的过程中,需要拉取很多 image ,如果出现报错某些 image 拉取失败或者很慢,可以到对应的节点机器上,手动执行 docker pull $image_name:$image_tag 来拉取该 image;

常用指令

这里列出一些常用的指令,

在 master 机器执行:

1
2
3
4
## 查看当前集群的所有 node 机器信息
kubectl get nodes -o wide
## 描述某个 node 节点的信息
kubectl describe node $node_name

Linux 基础

Linux 文件管理

文件的时间

  • mtime 即 modification time 当文件的数据内容发生变动时,就会升级这个时间;
  • ctime 即 status time 当文件的状态改变时,会升级这个时间,例如权限或属性更改了,就会升级这个时间;
  • atime 即 access time 当文件内容被取用时,就会升级这个时间。例如使用 cat 指令读取文件内容,就会升级atime;

常见的Linux指令

系统工作命令

echo

用于输出字符串或者变量提取后的值,用法为

1
echo [字符或变量]
date

用于显示时间或日期,用法为

1
date [选项] [指定格式]
reboot

重启系统,默认需要root权限才能执行

poweroff

关闭系统,默认需要root权限才能执行

wget

用于下载网络文件,用法为:

1
wget [参数] 下载地址

参数可以是以下几个

  • -b 后台下载模式
  • -P下载到指定目录
  • -t 最大尝试次数
  • -c 断点续传
  • -p 下载页面内所有的资源,包括图片、视频等
  • -r 递归下载
ps

查看系统的进程状态,用法为

1
ps [参数]

参数可以是:

  • -a 显示所有进程(包括其他用户的进程)
  • -u 用户以及其它详细信息
  • -x 显示没有控制终端的进程
top

用于监视进程活动与系统负载等信息,

  • 第一行:系统时间、运行时间、登录终端数、系统负载(一分钟、五分钟、十五分钟内的平均值)
  • 第二行:进程总数、运行中的进程数、睡眠中的进程数、停止的进程数、僵死的进程数
  • 第三行:用户占用资源百分比、系统内核占用资源百分比等
  • 第四行:物理内存总量、可用内存量,内存使用量、缓存内存量
  • 第五行:虚拟内存总量、虚拟内存可用量、虚拟内存使用量、可用内存量
kill

终止指定的PID的服务进程,用法为

1
kill [参数][进程PID]

系统状态命令

ifconfig

获取网卡配置和网络状态等信息

uname -a

查看系统内核与系统版本等信息

free

查看系统内存使用情况,一般可以用参数 -h -m 或 -g

who

查看当前登入主机终端信息

文件与目录

cp

copy 复制文件,除了复制之外,还可以创建链接、对比两个文件新旧和复制整个目录等。

用法

1
cp 源路径 目标路径

复制数据的前提是,操作者必须拥有文件的read权限;

可选参数是 -a 或者 -p。带上可选参数后,可以把文件的权限也复制过来。

rm

remove 用于删除文件或目录,如果删除的是目录,带上 -rf

1
rm -rf 目录名称
mv

move 移动文件或目录,或者命名。

1
mv 源路径 目标路径

若是命名,直接把目标路径名字改成新的名字就好了。

tar

对文件进行打包压缩或解压,用法:

1
tar [选项][文件]

常用打包指令:

1
tar -cvf 生成的压缩包名.tar.gz 需要打包的目录

常用解压指令:

1
tar -xvf 压缩包名称.tar.gz

文件内容查阅

cat

concatenate (中文意思:连续) 从第一行开始到最后一行显示文件内容,如果加上 -n-b ,则在每一行前面加上行号。

tac

与cat相反 从最后一行开始到第一行显示文件内容;

more

从第一页开始,一页一页翻动 (无法往前翻,只能往后翻),提示语会在最下面一行,可以输入以下命令进行操作:

  • 空白键(space) 代表向下翻页;
  • 回车键(Enter) 代表向下翻一行;
  • /字符串 代表在这个显示的内容当中,向下搜寻输入的字符串关键字;
  • :f 立刻显示文件名和当前显示的行数;
  • q 代表立刻离开 more,不再显示该文件的内容;
  • b 代表往回翻页;
less

从第一页开始,一页一页地翻动,支持向前上翻页和向上搜索,带行号打开,请用

1
less -N 目标文件
  • 空白键(space) 向下翻一页;
  • [PageDown]键 向下翻一页;
  • [PageUp]键 向上翻一页;
  • /字符串 向下搜索字符串;
  • ?字符串 向上搜索字符串;
  • n 重复前一个搜索操作;
  • N 反向重复上一个搜索操作;
  • q 离开less这个程序;

读取前面几行,默认读取前10行,可以带上 -n 数字,读取文件的前数字行,例如

1
head -n 8 文件名

代表读取文件的前8行

tail

读取文件的后几行,默认读取后10行,例如

1
tail -n 8 文件名

代表读取文件的后8行。

可以带上 -f 参数,会一直等待新的数据加入,并且把新的数据也显示在屏幕上,可以按下 [ctrl]+c 离开;

1
tail -f 文件名
touch

常用于创建一个空的文件或修改文件时间;

tr

替换文件中的字符,用法为

1
tr [原始字符][目标字符]
wc

统计文件的行数、字数或字节数,用法为

1
wc [参数] 文件名

参数 -l 表示只显示行数

参数 -w 显示单词数

参数 -c 显示字节数

stat

查看文件的具体存储信息和时间

文件查找

whereis

通过Linux的数据库快速查找某个文件;

locate

通过Linux的数据库,模糊查找含有关键词的文件,例如:

1
locate keyword

可以通过updatedb命令手动升级Linux的记录文件数据库,记录文件的数据库会在每次Linux启动时更新。

find

在硬盘上根据条件搜索相关文件,可以是时间条件,可以是文件权限条件,查找速度可能不快,指令较复杂,这里不展开。

grep

在文本中执行关键词搜索,并显示匹配的结果,用法为:

1
grep [选项]文件名

常用参数:

  • -b 将可执行文件当作文本文件来搜索
  • -c 仅显示找到的行数
  • -i 忽略大小写
  • -n 显示行号
  • -v 反向选择(仅列出没有关键词的行)
  • -E ‘字符串’ 搜索包含字符串内容的行

重定向、管道和环境变量

重定向

在Linux系统中,输入重定向是指把文件导入命令中,输出重定向是指把原本要输出到屏幕的数据信息写入指定文件中

输入重定向
符号 作用
命令 < 文件 将文件作为命令的标准输入
命令 << 分界符 从标准输入中读入,知道遇见分界符才停止
命令 <文件1> 文件2 将文件1作为命令的标准输入并将标准输出到文件2
输出重定向
符号 命令
命令 > 文件 将标准输出重定向到一个文件中(清空原有文件的数据)
命令 2> 文件 将错误输出重定向到一个文件中(清空原有文件的数据)
命令 >> 文件 将标准输出重定向到一个文件中(追加到原有内容的后面)
命令 2>> 文件 将错误输出重定向到一个文件中(追加到原有内容的后面)
命令 &>> 文件 将标准输出和错误输出共同写入到文件中(追加到原有内容的后面)

管道

管道命令符,即 | 符号,意思为把前一个命令原本要输出到屏幕的数据,当作后一个命令的标准输入。

常用的转义字符

在写shell脚本时,最常用是以下四个转义字符:

  • 反斜杠 \ 使反斜杠后面的一个变量变为单纯的字符串
  • 单引号 ‘’ 转义其中所有的变量为单纯的字符串
  • 双引号 “” 保留其中的变量属性,不进行转义处理
  • 反引号`` 把其中的命令执行后返回结果

环境变量

可以使用 env 命令查看所有的环境变量

可以使用 export 命令将普通变量升级为全局变量,例如

1
2
3
4
# 定义一个变量
EKWONG_DIR=/home/ekwong
# 升级为全局变量
export EKWONG_DIR
路径

路径PATH是环境变量中重要的一个,一般存放着用户输入的命令文件

查看当前配置的路径:

1
echo $PATH

添加新的路径到当前定义的路径

1
PATH=$PATH:/you/path