Linux基础与C高级
8月1号
Linux基础应用:
Linux的 主流的发行版: Ubuntu redhat centos
Linux系统结构: 类比银行 了解
用户空间: 大厅 VIP包间 应用程序 命令 ls ... 工具软件 gcc
shell: 命令解释器 大厅经理
连接层: 系统调用 (一些函数) 银行柜员窗口
内核空间: 系统调用
系统内部
硬件设备管理
驱动管理
文件系统
进程管理
内存管理
网络管理
linux文件系统: 一切皆文件
Linux中磁盘的 表示 /dev/sda 第一块磁盘 sd 表示这个硬盘是stat接口 m.2
/dev/sda1 磁盘分区 1
/dev/sda2 磁盘分区 2
磁盘分区查看命令
sudo fdisk -l
Disk /dev/sda: 40 GiB, 42949672960 bytes, 83886080 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: dos
Disk identifier: 0x0c1d422e
设备 启动 Start 末尾 扇区 Size Id 类型
/dev/sda1 * 2048 75493375 75491328 36G 83 Linux
/dev/sda2 75493376 83886079 8392704 4G 5 扩展
/dev/sda5 75495424 83884031 8388608 4G 83 Linux 虚拟的
Linux的根目录结构
/
/bin 存放二进制文件 系统命令 等
/dev 设备目录 存储系统设备文件等
/home 用户家目录的 总目录
/root 管理员用户的家目录
/etc 系统配置目录 存放系统或软件的一些配置文件
/proc 虚拟文件系统, 存放系统中的 一些进程或系统属性
/lib 存放库文件
/opt 存储第三方软件 安装包
/usr 用户相关的 文件
/mnt 系统挂载目录
文件系统的类型:
存储方式分 本地文件系统 网络文件系统 虚拟文件系统(内存文件系统)
文件的路径: 找到一个文件的 字符串位置
Windows: D:\WorkSpace\Linux\5子棋.rar
Linux: /home/xwq/c基础
相对路径: 相对于某个位置的路径 ../ ~/c基础
在某些情况下 路径才是正确的
绝对路径: 从根目录开始的一个路径 /home/xwq/c基础
在当前计算机中 任何位置 都可以使用绝对路径访问文件
Linux与Windows 文件系统区别:
文件命名: Linux区分大小写 Windows 不区分大小写
Linux中有些类型文件 在Windows中不支持
shell命令: 用于方便使用者 更好的使用Linux操作系统 而设计的一些 命令
这些命令 通过shell 解释器 进行解释
格式: 各个部分间 至少有一个空格分隔 选项和参数可以有 也可以没有
命令名 选项 参数
选项: 以-开头的 通常为单个字母 用于选择一些额外功能或结构
参数: 一般给定 操作目标 或 对象
使用man 手册 查看命令
ls -a 显示当前目录中 的 所有文件包括隐藏文件的 名字
ls ../ 显示 ../ 目录中的 文件名字
ls -l a.txt 显示当前目录中 名叫a.txt文件的 详细信息
ls -la 显示当前目录中 所有文件包括隐藏文件的 详细信息列表
shell命令 中的 特殊符号:
1. 通配符 通过通配符 来描述 一系列有 相似结构的文件名
* 代指 任意长度 任意字符
*.c 代指所有.c结尾的文件
for*.txt 代指所有for开头.txt结尾的文件名
? 代指 一个长度 任意字符
[] 中间给定一些字符, 表示该位置 匹配[]中列举的任何一个字符 区分大小写
[123]*.txt 表示 所有1或2或3 开头的 以.txt 结尾的文件
[-] 表示匹配给定区间的 字符, 不区分大小写
[^] 表示匹配除去给定区间的 其他字符
练习: 若有文件 123.txt 1.txt 2.txt abc.txt a.c A.c a.txt BBB.txt b.c
1. ls 第2个是数字字符的 文件 ?[0-9]*
2. 有3个字符开头的 .txt文件 即 abc.txt BBB.txt 123.txt
???.txt
2. 管道符 | 作用 连接两个命令 将上一个命令的输出 作为一下命令的输入
printf() scanf()
wc 命令 用于 统计输入的 字符的 -l 行数 -w 单词数
grep 命令 用于字符串筛选 可以对输入的字符串进行规则筛选(正则表达式)
ls -l | grep -E "^d" | wc -l 统计目录中有多少个目录
3. 转义符 \ 作用: 将一个普通字符转义为特殊含义或将特殊字符 转义为其本身的含义
4. 目录分隔符 / 根目录符 一个不能被转义的符号
了解:
5.输入输出重定向符
> 以新建模式 输出重定向
>> 以追加模式 输出重定向
< 输入重定向
6.命令置换符 (shell脚本中有使用)
`` 将一个命令的输出作为 另一个命令的参数
关于查找:
查找文件名 find 指定路径 -name 文件名
在多个文件中 查找文件内容
grep -rn "hello" ./
shell中 常用的命令:
目录与文件相关命令:
cd
ls
mkdir
rmdir
du -sh 目录 用于查看目录的 存储大小
tree 用于 树状结构查看目录
mv 移动+改名字
cp 复制+改名字 -r 复制目录
touch 创建普通文件
rm 删除文件 rm -r 递归删除 目录及目录中的文件
编辑:
vim gedit echo "hello" > 文件中
查看文件内容
cat head tail more less
全看 开头 末尾 翻页 换行看
文件或目录的权限设置:
-rw-rw-r-- 1 xwq xwq 422 7月 31 10:33 main.c
权限码: 110 110 100 = 0664
修改文件权限 chmod 0666 main.c
修改文件的所有者 sudo chown 用户名 文件或组名
改变文件或目录所属的组 sudo chgrp 组名 文件或目录名
sudo 在命令运行前添加 表示该命令 暂时使用管理员权限运行
root 用户 管理员 上帝
Linux中的链接文件:
ln 命令 来创建链接文件 :
软链接: 效果等同于 Windows中的快捷方式
ln -s 1.txt ln_1.txt
硬链接: 了解
ln
用户相关:
用户名: 用于登录一个计算机的 凭证
口令 : 密码 登录用户的密码
家目录: 用户的初始工作目录
用户组: Linux中 可以将多个用户 放到一个组中
用户ID(UID) 一个值 唯一标记一个用户
用户组ID
用户相关命令: 管理员身份运行
adduser 添加一个用户到Linux中
deluser 删除一个用户
su 用户名 切换用户身份
passwd 修改当前用户自己的密码
管理员改其他用户的密码
usermod -p 123456 username
Linux密码文件 /etc/passwd
进程相关命令:
进程: 一个运行起来的程序 程序运行结束 进程就消失了
PID: 进程的ID号, 在系统中 是一个唯一的数
前台进程: 占用终端,终端的输入将会传输给 前台进程
后台进程: 没有占用终端,在后台运行的 进程 输出会在终端显示 依附终端存在
服务进程: 通常没有终端输入输出
1. 查看系统中 所有的 进程
ps -aux
ps -aux | grep ./a.out 筛选指定名字的进程
2. 给指定进程发送 杀死信号
kill -9 进程PID
3. top 命令 动态显示进程
4. 更改运行中的进程的优先级
renice +/-n -p pid
进程的状态: 了解
D: 不可中断的静止
R: 正在执行中
S: 阻塞状态
T: 暂停执行
Z: 不存在但暂时无法消除
W: 没有足够的内存分页可分配
<: 高优先级的进程
N: 低优先级的进程
L: 有内存分页分配并锁在内存中
# jobs //查看任务,返回任务编号n和进程号
# bg %n //将编号为n的任务转后台运行
# fg %n //将编号为n的任务转前台运行
# ctrl+z //挂起当前任务 前台转后台
# ctrl+c //结束当前任务 结束前台进程
运行程序时 就在后台运行 ./a.out &
Ubuntu软件包的管理:
本地软件包管理器 dpkg
在线软件包管理器 apt-get 应用商店
软件包: 格式
Windows .exe
Linux: .deb 软件包 : Ubuntu系统专用
.rpm 软件包 : Redhat系统通用型
示例: 次版本号
sogoupinyin_2.2.0.0108_amd64.deb
软件包名 主版本号 体系架构
1. 查看系统中的 所有软件包
dpkg -l 列出本地所有的软件包
2. 本地安装 与 卸载软件包
sudo dpkg -r 软件包名 卸载指定软件包
sudo dpkg -P 软件包名 移除已卸载软件的配置文件
sudo dpkg -i 软件安装包.deb
dpkg : 1. 无需网络 本地安装
2. 无法自动解决依赖问题
apt-get : 联网安装 有网/源上要有该软件包
1. 可以自动解决依赖问题
软件源: apt-get 工具会从服务器(软件源) 上去搜索 指定软件包
sudo apt-get update 更新源
1.在线安装一个软件包
sudo apt-get install 软件包名
软件原列表文件/etc/apt/sources.list
练习: 卸载 gedit 软件包
apt-get 安装 gedit
Ubuntu网络相关:
TPCIP 以太网
IP地址: 计算机在网络中的 唯一ID 用于确定在网络中的 逻辑位置
格式: 点分法 显示 192.168.124.9 本质是一个32bit的数
0-255
A类B类 与C类 3类IP地址
局域网: 局部访问
广域网: 外网 全球通用, 任何地方都可以访问
IPv4 地址 . . . . . . . . . . . . : 192.168.124.9
子网掩码 . . . . . . . . . . . . : 255.255.255.0
默认网关. . . . . . . . . . . . . : 192.168.124.1
网络号: 局域网中 主机地址 最小的那个 192.168.124.0
主机地址: 除去网络号 余下部分 作为主机地址
广播地址: 局域网中 主机号最大的那个IP 192.168.124.255
子网掩码: 区分 网络号 与主机号的一个 掩码
网关地址: 局域网中 主机号 最小可以使用的那个 192.168.124.1
1. Linux 查看系统IP
ifconfig
ens33 Link encap:以太网 硬件地址 00:0c:29:2f:76:27
inet 地址:192.168.124.117 广播:192.168.124.255 掩码:255.255.255.0
inet6 地址: fe80::2c6d:3b87:26bc:a3ea/64 Scope:Link
UP BROADCAST RUNNING MULTICAST MTU:1500 跃点数:1
接收数据包:23463 错误:0 丢弃:117 过载:0 帧数:0
发送数据包:5686 错误:0 丢弃:0 过载:0 载波:0
碰撞:0 发送队列长度:1000
接收字节:7933725 (7.9 MB) 发送字节:402275 (402.2 KB)
lo Link encap:本地环回
inet 地址:127.0.0.1 掩码:255.0.0.0
inet6 地址: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 跃点数:1
接收数据包:3084 错误:0 丢弃:0 过载:0 帧数:0
发送数据包:3084 错误:0 丢弃:0 过载:0 载波:0
碰撞:0 发送队列长度:1000
接收字节:264009 (264.0 KB) 发送字节:264009 (264.0 KB)
2. 测试 连通性
ping ip地址或域名 DNS 域名服务器 域名 --> IP
xwq@xwq-pc:~$ ping 192.168.1.1
PING 192.168.1.1 (192.168.1.1) 56(84) bytes of data.
64 bytes from 192.168.1.1: icmp_seq=1 ttl=63 time=1.40 ms
64 bytes from 192.168.1.1: icmp_seq=2 ttl=63 time=1.13 ms
DHCP: 动态IP分配 局域网 租用IP
nslookup 用于解析域名 访问域名服务器
Ubuntu配置网卡:
1. 图形化配置 配置DHCP 动态模式
配置静态 ip 手动指定一个IP
2. 使用配置文件 方式配置
修改配置文件
sudo vim /etc/network/interfaces
参考如下配置:
# interfaces(5) file used by ifup(8) and ifdown(8)
auto lo
iface lo inet loopback
auto ens33
#配置网络 ens33 为DHCP模式
#iface ens33 inet dhcp
#配置网络 ens33 为静态IP模式
iface ens33 inet static
address 192.168.3.201
netmask 255.255.255.0
gateway 192.168.3.1
配置完成后 重启网卡
xwq@xwq-pc:~$ sudo /etc/init.d/networking restart
[ ok ] Restarting networking (via systemctl): networking.service.
若 出现网络未托管 情况
1.编辑托管配置文件
xwq@xwq-pc:~$ sudo vim /etc/NetworkManager/NetworkManager.conf
[main]
plugins=ifupdown,keyfile,ofono
dns=dnsmasq
[ifupdown]
managed=true
2.重启 托管服务
sudo /etc/init.d/network-manager restart
[ ok ] Restarting network-manager (via systemctl): network-manager.service.
安装两个服务器:
文件共享的两个服务器 tftp nfs
tftp服务器: 文件传输服务 以cs(客户端与服务器模型)
客户端 可以通过tftp 上传或下载文件到服务器 云盘
安装 tftp客户端
tftp服务器端
1.安装 软件包 apt-get
sudo apt-get install tftp //安装客户端
sudo apt-get install tftpd-hpa //安装服务器
2.配置服务器
编辑配置文件 sudo vim /etc/default/tftpd-hpa
参考如下配置
# /etc/default/tftpd-hpa
TFTP_USERNAME="tftp"
# TFTP_DIRECTORY="/var/lib/tftpboot"
TFTP_DIRECTORY="/home/xwq/tftpboot"
TFTP_ADDRESS=":69"
TFTP_OPTIONS="--secure -c"
配置文件修改
TFTP_DIRECTORY="/home/xwq/tftpboot" // 修改了 tftp的工作目录 /home/xwq/tftpboot
TFTP_OPTIONS="--secure -c" // 添加了-c 选项 可以上传文件
若工作目录 /home/xwq/tftpboot 不存在, 就手动创建这个目录
mkdir /home/xwq/tftpboot
给权限
chmod 777 /home/xwq/tftpboot
3. 重启服务 使能配置生效
sudo /etc/init.d/tftpd-hpa restart
[ ok ] Restarting tftpd-hpa (via systemctl): tftpd-hpa.service.
4. 使用 tftp
客户端 下载文件
xwq@xwq-pc:~/tmp$ tftp 192.168.124.117
tftp> get test.txt
Received 13 bytes in 0.1 seconds
tftp> quit
客户端 上传文件
tftp 192.168.124.117
tftp> put 1.txt
Sent 13 bytes in 0.0 seconds
tftp> quit
nfs: 目录共享服务
1.安装服务器
sudo apt-get install nfs-kernel-server
2.配置 nfs
sudo vim /etc/exports
添加一行配置
/home/xwq/nfshome *(ro,sync,no_subtree_check)
工作目录 *不限制ip ro 只读 rw 可读可写
若工作目录 /home/xwq/nfshome 不存在, 就手动创建这个目录
mkdir /home/xwq/nfshome
给权限
chmod 777 /home/xwq/nfshome
3. 重启服务生效
sudo /etc/init.d/nfs-kernel-server restart
4. 使用nfs
客户端使用nfs 挂载客户端提供的 目录 到本地 的 一个 目录上
sudo mount 192.168.124.117:/home/xwq/nfshome /mnt/nfs
卸载 挂载点 退出挂载点目录
sudo umount /mnt/nfs
shell脚本: 本质 shell命令的 有序集合
一种解释型 语言 不需要编译
方便操作者 对重复性的劳动进行 编程
一种无类型语言 变量没有类型 或 字符串类型
注意事项: 对标点符号 和 格式 非常严格 特别是空格
创建一个shell脚本步骤:
1. 创建一个普通文件 通常 后缀.sh
touch hello.sh
2. 修改权限 添加可执行权限
chmod 777 hello.sh
3. 写脚本
vim hello.sh
第一行 #!/bin/bash
打印 echo "hello world"
4. 运行脚本 ./hello.sh
练习: 写一个创建脚本的 创建2.sh
变量: 多用于 代指文件名 各种名字 或参数 命令等
用户自定义变量:
变量定义 变量名=值 等号两边 没有空格
变量使用 引用其值 $变量名 本质是字符替换
位置变量:
$0 运行脚本的指令本身
$1,$2,……$9 分别包含第一个到第九个命令行参数
预定义变量: 有终端预先定义的一些变量
由系统保留和维护的一组特殊的变量,这些变量通常用于保存程序运行状态等
$# 包含命令行参数的个数
$@ 包含所有命令行参数:“$1,$2,……$9”
$? 包含前一个命令的退出状态
$* 包含所有命令行参数:“$1,$2,……$9”
$$ 包含正在执行进程的ID号
环境变量: 一组存储终端环境参数的 变量
export 命令 可以打印输出 终端所有的环境变量
PWD 存储当前工作路径
USER 存储当前终端的登录用户
HOME 存储当前用户的家目录
PATH 存储当前终端 的命令搜索路径
echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/gcc-4.6.4/bin:/home/xwq/esp8266/xtensa-lx106-elf/bin:/home/xwq/.local/bin
shell脚本的 输入输出:
echo 输出字符串
read 从终端读取字符串
shell中 的算数运算
expr 数学表达式 每个符号与数值 间都要有空格分开
支持 + - \* / % 但只能做 整数运算 不能做小数运算
程序结构:
if 结构
if [ 表达式 ]
then
命令块1
else
命令块2
fi
没有else 可以省略
if [ 表达式 ]
then
命令块1
fi
shell 表达式
字符串测试
s1 == s2 测试两个字符串的内容是否完全一样
s1 != s2 测试两个字符串的内容是否有差异
-z s1 测试s1 字符串的长度是否为0
-n s1 测试s1 字符串的长度是否不为0
整数测试
a -eq b 测试a 与b 是否相等
a -ne b 测试a 与b 是否不相等
a -gt b 测试a 是否大于b
a -ge b 测试a 是否大于等于b
a -lt b 测试a 是否小于b
a -le b 测试a 是否小于等于b
-d name 测试name 是否为一个目录
-e name 测试一个文件是否存在
-f name 测试name 是否为普通文件
-L name 测试name 是否为符号链接
-r name 测试name 文件是否存在且为可读
-w name 测试name 文件是否存在且为可写
-x name 测试name 文件是否存在且为可执行
-s name 测试name 文件是否存在且其长度不为0
f1 -nt f2 测试文件f1 是否比文件f2 更新
f1 -ot f2 测试文件f1 是否比文件f2 更旧
练习 输入一个文件名 判断该文件 是否存在, 若存在 判断是否为 普通文件且是空的
则 删除它
ggvG=
case 多分支结构
结构:
case $变量名 in
值1) 命令块1
;;
值2) 命令块2
;;
...
*) 命令块n
esac
运行逻辑 将变量中字符串 与 ) 左边的字符串比较 相等 就 执行后面的命令块
若 不相等 继续向后比较
值可以使用通配符
练习: 输入成绩 输出 优良中差
循环结构:
for循环 结构1:
for (( I=0;I<10;I++ ))
do
循环命令块
done
示例: 创建10个文件 文件名为 file_数.txt
结构2:
for 变量名 in 取值列表
do
循环命令块
done
取值列表: 以空格 回车 等分隔开的的字符串
每次循环 变量的值 就是 取值列表 中的一个
顺序的
示例: 打印输出 当前目录中 所有.sh 文件的内容都打印出来
练习: 写一个脚本实现 将当前目录中 所有的 空的 普通文件 删除
while循环:
while [ 条件表达式 ]
do
循环语句块
done
与C的运行逻辑完全一样
循环控制语句 与C的break与continue关键字效果完全一样
break
continue
break 2
continue 2
了解: shell 的函数
函数定义:
函数名()
{
命令块
}
函数调用
函数名
参数传递 使用位置变量