Linux基本操作
1. Linux基本操作
1.1 文件和目录操作
- ls: 列出目录内容
ls
ls -l # 详细列表
ls -a # 显示隐藏文件
- cd: 切换目录
cd /path/to/directory
cd .. # 返回上一级目录
cd ~ # 返回家目录
- pwd: 显示当前目录
pwd
- mkdir: 创建目录
mkdir new_directory
- rmdir: 删除空目录
rmdir empty_directory
- rm: 删除文件或目录
rm file.txt
rm -r directory # 递归删除目录
- cp: 复制文件或目录
cp source.txt destination.txt
cp -r source_directory destination_directory
- mv: 移动或重命名文件或目录
mv old_name.txt new_name.txt
mv file.txt /path/to/directory/
- touch: 创建空文件或更新文件时间戳
touch new_file.txt
1.2 文件查看和编辑
- cat: 查看文件内容
cat file.txt
- more 和 less: 分页查看文件内容
more file.txt
less file.txt
- head: 查看文件开头部分
head file.txt
head -n 10 file.txt # 查看前10行
- tail: 查看文件末尾部分
tail file.txt
tail -n 10 file.txt # 查看最后10行
tail -f file.txt # 实时查看文件更新
- nano: 简单的文本编辑器
nano file.txt
- vim: 强大的文本编辑器
vim file.txt
1.3 系统信息和管理
- uname: 显示系统信息
uname -a
- top: 显示系统进程和资源使用情况
top
- ps: 显示当前进程
ps aux
- kill: 终止进程
kill PID
kill -9 PID # 强制终止
- df: 显示磁盘使用情况
df -h
- du: 显示目录或文件的磁盘使用情况
du -sh /path/to/directory
- free: 显示内存使用情况
free -h
1.4 网络操作
- ping: 测试网络连接
ping google.com
- ifconfig: 显示和配置网络接口
ifconfig
- netstat: 显示网络连接、路由表、接口统计信息等
netstat -tuln
- ssh: 远程登录
ssh user@hostname
- scp: 安全复制文件
scp file.txt user@hostname:/path/to/destination
1.5 权限管理
- chmod: 修改文件或目录权限
chmod 755 file.txt
chmod +x script.sh # 添加执行权限
- chown: 修改文件或目录的所有者
chown user:group file.txt
- sudo: 以超级用户权限执行命令
sudo command
1.6 包管理
- apt (Debian/Ubuntu): 包管理工具
sudo apt update
sudo apt install package_name
sudo apt remove package_name
- yum (CentOS/RHEL): 包管理工具
sudo yum install package_name
sudo yum remove package_name
- dnf (Fedora): 包管理工具
sudo dnf install package_name
sudo dnf remove package_name
1.7 其他常用命令
- grep: 文本搜索
grep "pattern" file.txt
- find: 查找文件
find /path/to/search -name "filename"
- tar: 打包和解包文件
tar -cvf archive.tar /path/to/directory # 打包
tar -xvf archive.tar # 解包
- wget: 下载文件
wget http://example.com/file.txt
- curl: 传输数据
curl -O http://example.com/file.txt
2. Linux网络编程
Linux 网络编程主要基于 Socket API,它允许程序通过网络进行通信。常见的协议包括 TCP 和 UDP。
2.1 Socket 编程基础
- Socket 是网络通信的端点,可以是面向连接的(如 TCP)或无连接的(如 UDP)。
- IP 地址 和 端口号 用于标识网络中的主机和服务。
2.2 TCP编程
TCP是面向连接的协议,即提供可靠的数据传输
客户端client.c:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sock = 0;
struct sockaddr_in serv_addr;
char *message = "Hello from client";
char buffer[BUFFER_SIZE] = {0};
// 创建 socket
if ((sock = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("Socket creation error");
return -1;
}
// 设置服务器地址
serv_addr.sin_family = AF_INET;
serv_addr.sin_port = htons(PORT);
if (inet_pton(AF_INET, "127.0.0.1", &serv_addr.sin_addr) <= 0) {
perror("Invalid address/ Address not supported");
return -1;
}
// 连接到服务器
if (connect(sock, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
perror("Connection failed");
return -1;
}
// 发送数据
send(sock, message, strlen(message), 0);
printf("Message sent\n");
// 接收响应
read(sock, buffer, BUFFER_SIZE);
printf("Server: %s\n", buffer);
// 关闭 socket
close(sock);
return 0;
}
服务器端server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int server_fd, new_socket;
struct sockaddr_in address;
int addrlen = sizeof(address);
char buffer[BUFFER_SIZE] = {0};
char *response = "Hello from server";
// 创建 socket
if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
perror("Socket failed");
exit(EXIT_FAILURE);
}
// 绑定 IP 和端口
address.sin_family = AF_INET;
address.sin_addr.s_addr = INADDR_ANY;
address.sin_port = htons(PORT);
if (bind(server_fd, (struct sockaddr *)&address, sizeof(address)) < 0) {
perror("Bind failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 监听连接
if (listen(server_fd, 3) < 0) {
perror("Listen failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 接受连接
if ((new_socket = accept(server_fd, (struct sockaddr *)&address, (socklen_t*)&addrlen)) < 0) {
perror("Accept failed");
close(server_fd);
exit(EXIT_FAILURE);
}
// 读取客户端数据
read(new_socket, buffer, BUFFER_SIZE);
printf("Client: %s\n", buffer);
// 发送响应
send(new_socket, response, strlen(response), 0);
printf("Response sent\n");
// 关闭 socket
close(new_socket);
close(server_fd);
return 0;
}
2.3 UDP编程
UDP是无连接的协议,传输速度快,不保证可靠性。
客户端client.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sockfd;
struct sockaddr_in servaddr;
// 创建 socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 设置服务器地址
servaddr.sin_family = AF_INET;
servaddr.sin_port = htons(PORT);
servaddr.sin_addr.s_addr = INADDR_ANY;
// 发送数据
sendto(sockfd, "Hello from client", strlen("Hello from client"), 0, (const struct sockaddr *)&servaddr, sizeof(servaddr));
printf("Message sent\n");
// 接收响应
char buffer[BUFFER_SIZE];
int len = sizeof(servaddr);
int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&servaddr, &len);
buffer[n] = '\0';
printf("Server: %s\n", buffer);
close(sockfd);
return 0;
}
服务器端server.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <arpa/inet.h>
#define PORT 8080
#define BUFFER_SIZE 1024
int main() {
int sockfd;
char buffer[BUFFER_SIZE];
struct sockaddr_in servaddr, cliaddr;
// 创建 socket
if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
perror("Socket creation failed");
exit(EXIT_FAILURE);
}
// 绑定 IP 和端口
servaddr.sin_family = AF_INET;
servaddr.sin_addr.s_addr = INADDR_ANY;
servaddr.sin_port = htons(PORT);
if (bind(sockfd, (const struct sockaddr *)&servaddr, sizeof(servaddr)) < 0) {
perror("Bind failed");
close(sockfd);
exit(EXIT_FAILURE);
}
// 接收数据
int len = sizeof(cliaddr);
int n = recvfrom(sockfd, buffer, BUFFER_SIZE, 0, (struct sockaddr *)&cliaddr, &len);
buffer[n] = '\0';
printf("Client: %s\n", buffer);
// 发送响应
sendto(sockfd, "Hello from server", strlen("Hello from server"), 0, (struct sockaddr *)&cliaddr, len);
printf("Response sent\n");
close(sockfd);
return 0;
}
3. Linux串口编程
串口编程用于与硬件设备(如传感器、嵌入式设备)进行通信。Linux 提供了 termios 库来配置串口。
3.1 串口编程步骤
- 打开串口设备文件(如 /dev/ttyS0 或 /dev/ttyUSB0)。
- 使用 termios 配置串口参数(波特率、数据位、停止位、校验位等)。
- 使用 read 和 write 进行数据读写。
- 关闭串口。
示例:基本的串口读写
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define SERIAL_PORT "/dev/ttyS0"
#define BUFFER_SIZE 256
int main() {
int fd;
char buffer[BUFFER_SIZE];
struct termios tty;
// 打开串口
fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
if (fd < 0) {
perror("Error opening serial port");
return -1;
}
// 获取当前串口配置
if (tcgetattr(fd, &tty) != 0) {
perror("Error getting terminal attributes");
close(fd);
return -1;
}
// 设置波特率
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
// 配置数据位、停止位、校验位
tty.c_cflag &= ~PARENB; // 无校验
tty.c_cflag &= ~CSTOPB; // 1 位停止位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 位数据位
// 应用配置
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("Error setting terminal attributes");
close(fd);
return -1;
}
// 写入数据
char *message = "Hello from serial";
write(fd, message, strlen(message));
// 读取数据
int n = read(fd, buffer, BUFFER_SIZE);
if (n > 0) {
buffer[n] = '\0';
printf("Received: %s\n", buffer);
}
// 关闭串口
close(fd);
return 0;
}
示例:非阻塞模式串口读写
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define SERIAL_PORT "/dev/ttyUSB0"
#define BUFFER_SIZE 256
int main() {
int fd;
char buffer[BUFFER_SIZE];
struct termios tty;
// 打开串口
fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY | O_NONBLOCK);
if (fd < 0) {
perror("Error opening serial port");
return -1;
}
// 获取当前串口配置
if (tcgetattr(fd, &tty) != 0) {
perror("Error getting terminal attributes");
close(fd);
return -1;
}
// 设置波特率
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
// 配置数据位、停止位、校验位
tty.c_cflag &= ~PARENB; // 无校验
tty.c_cflag &= ~CSTOPB; // 1 位停止位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 位数据位
// 应用配置
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("Error setting terminal attributes");
close(fd);
return -1;
}
// 非阻塞读取数据
while (1) {
int n = read(fd, buffer, BUFFER_SIZE);
if (n > 0) {
buffer[n] = '\0';
printf("Received: %s\n", buffer);
} else if (n < 0) {
if (errno == EAGAIN) {
// 没有数据可读
printf("No data available\n");
} else {
perror("Read error");
break;
}
}
sleep(1); // 等待 1 秒
}
// 关闭串口
close(fd);
return 0;
}
示例:设置超时读取
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#define SERIAL_PORT "/dev/ttyUSB0"
#define BUFFER_SIZE 256
int main() {
int fd;
char buffer[BUFFER_SIZE];
struct termios tty;
// 打开串口
fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
if (fd < 0) {
perror("Error opening serial port");
return -1;
}
// 获取当前串口配置
if (tcgetattr(fd, &tty) != 0) {
perror("Error getting terminal attributes");
close(fd);
return -1;
}
// 设置波特率
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
// 配置数据位、停止位、校验位
tty.c_cflag &= ~PARENB; // 无校验
tty.c_cflag &= ~CSTOPB; // 1 位停止位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 位数据位
// 设置超时
tty.c_cc[VMIN] = 0; // 最小读取字符数
tty.c_cc[VTIME] = 10; // 超时时间(单位:0.1 秒)
// 应用配置
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("Error setting terminal attributes");
close(fd);
return -1;
}
// 读取数据
int n = read(fd, buffer, BUFFER_SIZE);
if (n > 0) {
buffer[n] = '\0';
printf("Received: %s\n", buffer);
} else {
printf("No data received within timeout\n");
}
// 关闭串口
close(fd);
return 0;
}
示例:多线程串口通信
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <termios.h>
#include <pthread.h>
#define SERIAL_PORT "/dev/ttyUSB0"
#define BUFFER_SIZE 256
int fd;
void* read_serial(void* arg) {
char buffer[BUFFER_SIZE];
while (1) {
int n = read(fd, buffer, BUFFER_SIZE);
if (n > 0) {
buffer[n] = '\0';
printf("Received: %s\n", buffer);
}
}
return NULL;
}
int main() {
pthread_t tid;
struct termios tty;
// 打开串口
fd = open(SERIAL_PORT, O_RDWR | O_NOCTTY);
if (fd < 0) {
perror("Error opening serial port");
return -1;
}
// 获取当前串口配置
if (tcgetattr(fd, &tty) != 0) {
perror("Error getting terminal attributes");
close(fd);
return -1;
}
// 设置波特率
cfsetospeed(&tty, B9600);
cfsetispeed(&tty, B9600);
// 配置数据位、停止位、校验位
tty.c_cflag &= ~PARENB; // 无校验
tty.c_cflag &= ~CSTOPB; // 1 位停止位
tty.c_cflag &= ~CSIZE;
tty.c_cflag |= CS8; // 8 位数据位
// 应用配置
if (tcsetattr(fd, TCSANOW, &tty) != 0) {
perror("Error setting terminal attributes");
close(fd);
return -1;
}
// 创建读取线程
pthread_create(&tid, NULL, read_serial, NULL);
// 主线程写入数据
while (1) {
char *message = "Hello from serial";
write(fd, message, strlen(message));
sleep(1); // 每隔 1 秒发送一次
}
// 关闭串口
close(fd);
return 0;
}