* 为什么我在 Windows 下写的 shell 脚本在 WSL 中运行失败?
Windows 与 Linux 的文件换行符不同,使用 dos2unix 进行转换
* 我不想使用 less 命令,我要如何在 WSL 中向上移动?
在 WSL 中使用 SHIFT CTRL ⬆
* 一些命令输出的文件大小或时间太难读了怎么办?
一般这种命令都会由 -h 或 --human-readable 选项,并可以自定义单位
* 管道是重定向吗?和普通重定向的区别是什么?
是(标准输出重定向到标准输入),从方向上看,普通重定向可以重定向标准输入,标准输出,标准错误
甚至是标准输出和标准错误的组合,从重定向的对象上看,管道的目标对象是命令,普通重定向的目标对象是
文件,另外,普通重定向支持 HERE 文档,允许将多行文本作为输入,这对一些 SHELL 脚本有很大帮助
* 救命!我的 WSL 没有 message 日志文件
运行 VMWare 下的虚拟 Linux 操作系统,或使用 Kali 进行便携式 Linux 操作系统的安装
* shell、bash、terminal 这么多词,为什么我感觉都差不多?
确实,随着计算机的发展,他们几乎没有区别了(虽然在某些时刻依然能够很明显的感觉到脚本解释器
与脚本解释器宿主程序的区别),只会在一些细小的地方发现明显差异,如:
- 隶属于哪一个操作系统
- 是使用 c# 还是 c 或 c++ 或 python 或 perl 或 ruby
- 区不区分大小写等
* CLI 还是 GUI?
- CLI 又叫命令行接口,以 Python 为例,使用 argparse 模块可以让原先构建的 API 快速变成一个可以运行的命令
- GUI 又叫用户界面接口,现如今,PC 端的图形界面大多使用 Qt 进行开发
* GNU?
GNU not is Unix 的缩写,该写法利用了递归,由 MIT 的理察·斯托曼发起,1991 年林纳斯·托瓦兹
使用 GNU 许可证发布了 Linux 初代内核,随后 GNU 与 Linux 在相互帮助,相互前进
* Unix 设计哲学?
Unix 设计哲学是指对 Unix 的发展产生过重大影响的开发者的设计思想,现摘录部分如下:
- 少即是多
- 数据都应保存为文本
- 过早优化是万恶之源
- 要对代码进行详尽的测试
- 每个函数应只负责一件事情
* 如何理解 Linux 文件系统?
在 Linux 中,以“/” 作为文件系统的根,目录作为内部节点,其他文件作为叶子节点从而形成一颗倒放的树
* WSL 的原理是什么(假设只有 C 盘、D 盘)
将 C 盘、D 盘当作目录挂载到 /mnt 目录下 (因为磁盘本身就是设备)
其他
* Linux 是大小写敏感的,也就是区分大小写
* Linux 操作系统维护了两个目录 "."、"..",分别代表当前目录和当前目录的父目录
* Linux 操作系统无扩展名这一概念,但 Linux 应用程序会通过扩展名来区分不同文件
* Linux 操作系统中以 "." 开头的文件会被操作系统隐藏,也就是应用程序扫描不到被隐藏的文件
* Linux 操作系统将一切视为文件,并分为五种类型 -、d、l、(b,c)、p
复制
* cp 命令可以将文件内容复制到文件也可以将多个文件复制到目录
* -n 若 DEST 存在被复制地文件则不重写该文件
* -f 若 DEST 已存在并且无法打开,对该目录执行删除操作,再将文件复制到新建立的 DEST 中,不能和 -n 选项同时出现
* -r 递归 SOURCE 目录并全部复制到 DEST 目录中
移动
* mv 可以将文件或目录进行移动,也可以对文件进行改名
数组
* declare -a 可以声明一个数组
* echo ${#hours[*]} # 显示数组长度
* hours=(0,1,2,3,4,5,6,7,8,9) # 声明 1~9 的序列
* for i in {0..23};do hours[i] = 0;done # 大小为 24 每个值为 0 的数组
* hours=(1 2 3 4 5 6 7 8); for i in "${hours[@]}"; do echo $i; done # 将每一个元素单独处理
* hours=(1 2 3 4 5 6 7 8); for i in "${hours[*]}"; do echo $i; done # 将每一个元素整体处理
函数
sorted_numbers=($(printf "%s\n" "${numbers[@]}" | sort -n)) # 对数组进行排序
文本匹配
* 通配符,被预先定义的用于匹配的量词
* 正则表达式,用于文本匹配的一种语言
* 基础正则表达式,正则表达式的一种变体
* 扩展正则表达式,正则表达式的一种变体
* Perl 正则表达式,基于 Perl 的对扩展正则表达式的一种扩展
* 前导项,在基础正则表达式中往往需要对一个或多个字符进行限定,在这些被限定的字符后方往往会出现通配符,这些被限定的字符被称为前导项
基础正则表达式通配符:
* “*” 表示任意数量
* “.” 表示任意字符(既是通配符又是前导项)
* “?” 0 次或 1 次
* ”+“ 1 次或多次
* {n,m} 精确匹配 n 到 m 次,(m,n 可为 0)
基础正则表达式其他元字符:
* “[]” 表示需要匹配的字符集
* “^” 表示以……开头
* “$” 表示以……结尾
* 基础正则表达式可以匹配强密码吗?
不能,强密码用到了前瞻元字符,基础正则表达式没有
* grep 默认使用基础正则表达式
* grep 的一种使用格式是 grep {pattern} {file},但在大多数情况下,使用管道会和 grep 搭配使用
* -iw 忽略大小写的单词匹配
* -iwn 忽略大小写的单词匹配,若匹配成功输出匹配的行号
少即是多
* less 符合 UNIX 软件设计哲学的向后滚动文本阅读软件,通过按需加载,减少了大文件的系统开销,
至今仍由 Nudelman 维护,通常和管道符搭配使用
选项:
-N 显示行号,会有较为严重的排版问题
-m 显示从开始到现在已阅读的文本字节数
操作:
* /pattern 在文本中搜索
* q 退出
* b 向上翻页
* f 向下翻页
* n 向下移动 2 行 SHIFT n 向上移动两行
连接文件
* 从本质上讲 cat 从标准输入或输入流中复制并输出到标准输出,一般而言为避免连接后的文件过大,常常会通过管道输出给 less
* 诸如 cat > test.txt 格式的命令,可以实现一个简单的字处理器
* cat 有没有一些好玩的参数?
-A 可以显示换行符,通过该选项可以看出 Windows 和 Unix 换行符的差异
删除文件
* rm 默认情况下不将目录视为文件
* 为什么 rm 命令是一个危险的命令
“*”、-r、-f 三者组合中的某些可以轻易摧毁整个目录(包括系统本身)
发现文件
* find 是 Linux 下的一种流式过滤器,有时会和 xargs 命令搭配使用
* 和 xargs 搭配使用时,需要线程并发进程数(xargs 会尽可能多的创建进程来加速,在 find 返回的结果集过多时会造成性能异常)
定位文件
* locate 在背后通过定时任务维护了文件系统的目录数据库,和 find 相比更加简洁与方便
内存信息
* free 可以显示内存和交换区的详细信息
* -s 可以在屏幕上实时滚动内存和交换器的信息
* 例子
* free -hs 4 # 每 4 秒,以易于阅读的格式滚动内存和交换区的信息
文件打包
* 在 Apache 等软件提供商经常可以看到 .tat.gz 的身影,其中 tar 表示打包, gz 表示压缩
* -c 表示创建归档文件
* -f 表示被创建或被解包的归档文件名
* -x 表示从归档文件中提取
* 例子:
* tar -cf test.tar A.txt B.txt # 将 A.txt 与 B.txt 进行打包
* tar -xf test.tar.gz # 将 test.tar.gz 解包
* tar -xzf test.tar.gz test # 使用 gzip 对目录进行压缩打包
* 其他压缩算法
* --bzip2
* --xz
* --lzip
* --lzma
* --lzop
* 为什么 zip 和 gz 通常会配套出现?
Unix 社区下的约定 zip 表示可在 Windows 下运行,gz 表示可在 Unix 下运行
删除空目录
* rmdir 只能移除空目录
* rmdir 和 rm 是两个不同的命令
测试连通性
* ping 命令会向目标服务器发送 ICMP 报文
* -c 用于指定发送的 ICMP 报文数量(部分 Linux 发行版的 ping 会进行 flood ping)
列出目录内容
* -A 不列出 ".",".."
* -R 递归列出目录及其子目录
* --format 的取值有 commas、horizontal、long、single-column、verbose、vertical
* --sort 支持排序的键有 size、time、version、extension
* 长格式中出现的箭头是什么?
箭头发起方是被指向目录的符号链接
* -A 不列出 ".",".."
* -R 递归列出目录及其子目录
* --format 的取值有 commas、horizontal、long、single-column、verbose、vertical
* --sort 支持排序的键有 size、time、version、extension
* 长格式中出现的箭头是什么?
箭头发起方是被指向目录的符号链接
* 什么是符号连接
* 能不能让长格式以八进制格式显示?
ls 无原生支持,以下是两个简易脚本
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $0 file1 file2 ..."
exit 1
fi
for file in "$@"
do
if [ -e "$file" ]; then
permissions=$(stat -c '%a' "$file")
printf "%s %s\n" "$permissions" "$file"
else
echo "File '$file' not found."
fi
done
#########################################################
#!/bin/bash
if [ $# -eq 0 ]; then
echo "Usage: $0 file1 file2 ..."
exit 1
fi
for file in "$@"
do
if [ -e "$file" ]; then
permissions=$(stat -c '%a' "$file")
owner=$(stat -c '%U' "$file")
group=$(stat -c '%G' "$file")
size=$(stat -c '%s' "$file")
modified=$(stat -c '%y' "$file")
printf "%s Owner: %s Group: %s Size: %s bytes Last modified: %s File: %s\n\n" \
"$permissions" "$owner" "$group" "$size" "$modified" "$file"
else
echo "File '$file' not found."
fi
done
改变工作目录
* 使用 cd 可以将当前工作目录改变到 dir 目录下,默认的 dir 是用户的主目录
* ~ 代表用户中目录(与系统变量 HOME 同值)由 Linux 系统维护
绝对路径 ::= {/}[{路径名}/].. || {/}|{/路径名}[{/路径名}]..
例如:
/
/var/
/var/lock/
/
/var
/var/lock
显示进程快照
* ps 各字段含义:
* PID 进程 ID
* TTY 进程的控制终端
* TIME 进程所占用的 CPU 时间
* STAT 进程当前状态,R 表示运行,S 表示正在睡眠,D 不可中断睡眠,T 已停止,Z 僵尸进程(父进程没有把已经终止的子线程从表中删除),< 高优先级进程,N 低优先级进程
* USER 进程持有者的用户 ID
* %CPU CPU 使用率
* %MEM 内存使用率
* VSZ 虚拟内存大小
* RSS 进程占用的物理内存大小
* START 进程运行时间
* COMMAND 与进程有关的命令名
* 例子:
* ps x|less
* ps aux|grep redis
动态查看进程
* 与 ps 不同 top 展示的信息的实时同步的
* top 的 RES 类似于 ps 的 PSS 字段
* top 的 VIRT 类似于 ps 的 VSZ
* PR 和 NI 进程的优先级和友好度,PR 越低,NI 越低
修改文件权限
* Linux 操作系统文件权限格式 ::= {文件类型}{文件权限}
* 文件类型 ::= {-|d|l|c|b}
* {文件权限} ::= {用户权限}{组权限}{其他用户权限}
* {用户权限} ::= {r|w|x|X|s|t|-}{r|w|x|X|s|t|-}{r|w|x|X|s|t|-}
* {组权限} ::= {r|w|x|-}{r|w|x|-}{r|w|x|-}
* 默认情况下 chmod 若赋予目录以权限则子目录与文件不会继承父目录权限(除非使用 -R)
* 目录的默认权限是 rwxr-xr-x (sudo or 普通)
* 文件的默认权限是 rw-r--r-- (sudo or 普通)
八进制权限表示法 ::= [{八进制数字}]{八进制数字}{八进制数字}{八进制数字} <==> [{特殊权限}]{用户权限}{组权限}{其他用户权限}
八进制数字 ::= {0|1|2|3|4|5|6|7}
特殊权限映射表 ::= {X : 无, s : 4 | 2, t : 1, - : 0}
读写执行权限映射表 ::= {r : 4, w : 2, x : 1,- : 0}
例子:
chmod 755 test # 特殊权限置空 用户权限赋予读,写,执行(4+2+1),同组用户具有读,执行(4+1),其他用户具有读,执行(4+1)
chmod 000 test # 将目录修改为死文件(如果不修改权限,一般情况下死文件仍可删除,因为删除取决于当前目录权限,而非死文件)
符号权限表示法 ::= {范围}{运算符}{权限}
范围 ::= {u|g|o|a}
运算符 ::= {+|-|=}
权限 ::= {r|w|x|X|s|t|-}
* chmod 的默认范围为 a
例子:
chmod -rw test 移除所有用户的读、写权限
chmod =rw test 与 chmod +rw 类似
监控网络流量
* sar -n DEV 1 可以很好的弥补 top 或 ps 无法监控网络流量的缺陷
* 上述命令是滚动式的,可以使用 iftop 进行实时监控
更新文件时间戳
* 默认情况下 touch 只会修改文件的上次访问时间为系统当前时间,而不修改文件内容,若文件不存在,touch 会创建该文件,并赋予默认权限
* -c 可以修改 touch 的修改若文件不存在就创建的默认行为
* --time=modify 可以修改 touch 的修改上次访问时间为当前系统时间的默认行为,通常和 t 参数搭配使用
* -t 用于定义时间戳 timestamp
* timestamp ::= [[CC]YY]MMDDhhmm[.ss] 类似于 ISO 8601
操作系统性能调优
* 网络:
# 开启 TCP 窗口缩放
sudo sysctl net.ipv4.tcp_window_scaling=1
# 开启 TCP 快速打开
sudo sysctl net.ipv4.tcp_fastopen=3
# 设置 TCP 连接的最大保持时间(单位:秒)
sudo sysctl net.ipv4.tcp_keepalive_time=600
# 设置 TCP 接收缓冲区大小(单位:字节)
sudo sysctl net.core.rmem_max=8388608
# 设置 TCP 发送缓冲区大小(单位:字节)
sudo sysctl net.core.wmem_max=8388608
# 设置网卡 eth0 的接收和发送队列大小为 4096
sudo ethtool -G eth0 rx 4096 tx 4096
# 限制 TCP 端口 80 的并发连接数不超过 100 个
sudo iptables -A INPUT -p tcp --dport 80 -m connlimit --connlimit-above 100 -j REJECT
# 在 eth0 网络接口上添加一个 Token Bucket Filter(令牌桶过滤器),限制带宽为 1Mbps,突发大小为 10KB,延迟为 50ms
sudo tc qdisc add dev eth0 root tbf rate 1mbit burst 10kb latency 50ms
* CPU:
# 安装 cpufrequtils
sudo apt-get install cpufrequtils # 对于 Debian/Ubuntu
sudo yum install cpufrequtils # 对于 CentOS/RHEL
# 设置 CPU 性能模式
sudo cpufreq-set -r -g performance
# 设置 CPU 节能模式
sudo cpufreq-set -r -g powersave
# 安装 tuned
sudo apt-get install tuned # 对于 Debian/Ubuntu
sudo yum install tuned # 对于 CentOS/RHEL
# 启用和应用预定义的配置(例如高吞吐量性能)
sudo tuned-adm profile throughput-performance
# 绑定进程到 CPU 核心 0 到 3
taskset -c 0-3 command_to_run
* 内存:
# 设置虚拟内存区域大小(单位:页)
sudo sysctl vm.max_map_count=65536
# 开启内存透明大页(Transparent Huge Pages)
sudo sysctl vm.nr_hugepages=2048
# 修改内存回收策略(vm.swappiness 范围为 0 到 100,默认为 60)
sudo sysctl vm.swappiness=10
显示系统平均负载快照
* uptime 是 w 命令的简化版,只含有 w 命令的表头信息
显示环回接口和网卡接口
* ifconfig 可以显示出本机的网卡(eh 开头)和环回地址(lo)的 IPV4、IPV6、mtu 广播地址等硬件信息
用户信息与系统平均负载快照
* w 命令输出的表头会含有 load average
* w 命令还会显示出已经登陆的用户和用户进程占用的系统资源信息
输出每个文件的前十行到标准输出
* head 与 tail 对应,可以使用 -n [-]NUM 控制输出的行数(若含有 - 则功能等价于不反转的 tail)
* head 与 tail 虽然可以互相反转,但反转的本质是遍历到末尾或首部,大文件反转会有性能问题
输出每个文件的后十行到标准输出
* tail 与 head 对应,可以使用 -n [+]NUM 控制输出的行数(若含有 + 则功能等价于不反转的 head)
* head 与 tail 虽然可以互相反转,但反转的本质是遍历到末尾或首部,大文件反转会有性能问题
其他
冗余磁盘阵列
* 将相同型号的磁盘进行组装,来提高性能,节约成本的一项技术
inode
* 每个 inode 保存了文件系统对象数据的属性和磁盘块位置。文件系统对象属性包含了各种元数据 ,也包含用户组和权限数据。
软硬链接
硬链接:Linux 下的文件是通过 inode 来识别文件,硬链接可以认为是一个指针,指向文件索引节点的指针,系统并不为它重新分配 inode 。每添加一个一个硬链接,文件的链接数就加 1
* 软连接类似于浅拷贝,可以跨区
* 硬链接类似于深拷贝,不可以跨区