2024-08-19

syslog是一种用于记录系统和应用程序日志的标准协议。在Linux和UNIX系统中,syslog通常由守护进程syslogd或rsyslog来实现。syslog消息可以记录在本地文件或远程服务器上。

以下是syslog的一些基本概念:

  1. 优先级:syslog消息分为不同的优先级,如emerg(紧急)、alert(警告)、crit(严重错误)等。
  2. 配置文件:通常位于/etc/syslog.conf/etc/syslog-ng/syslog-ng.conf,控制syslog行为。
  3. 守护进程:syslogd或rsyslogd。
  4. 默认端口:UDP 514。

以下是一个简单的示例,展示如何使用syslog记录一条消息:




#include <syslog.h>
 
int main() {
    openlog("myapp", LOG_PID, LOG_USER); // 打开日志,设置标识和设施
    syslog(LOG_ERR, "This is an error message"); // 记录错误消息
    closelog(); // 关闭日志
    return 0;
}

在这个例子中,openlog函数初始化日志记录会话,并设置一个标识符"myapp"和选项LOG_PID和设施LOG_USERsyslog函数记录一条优先级为LOG_ERR的错误消息。最后,closelog函数关闭日志记录。

2024-08-19

在Linux环境下,理解不同的IO模型对于高效地编写并发程序是非常重要的。以下是五种常见的IO模型:

  1. 阻塞IO模型(Blocking IO)
  2. 非阻塞IO模型(Non-blocking IO)
  3. IO多路复用模型(IO Multiplexing)
  4. 信号驱动IO模型(Signal Driven IO)
  5. 异步IO模型(Asynchronous IO)

解释和示例代码:

  1. 阻塞IO模型:

    在这种模型中,进程会一直等待直到数据准备好,进而可以读写。这是最常见的IO模型,默认情况下所有的socket都是阻塞的。




int socket, n;
char buffer[1024];
socket = socket(AF_INET, SOCK_STREAM, 0);
connect(socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
 
// 阻塞IO操作
n = recv(socket, buffer, 1024, 0);
  1. 非阻塞IO模型:

    在这种模型中,如果数据没有准备好,进程会立即返回一个错误,而不是等待数据准备好。




int socket, n;
char buffer[1024];
socket = socket(AF_INET, SOCK_STREAM, 0);
 
// 设置socket为非阻塞
fcntl(socket, F_SETFL, O_NONBLOCK);
connect(socket, (struct sockaddr *)&server_addr, sizeof(server_addr));
 
// 尝试非阻塞IO操作
n = recv(socket, buffer, 1024, 0);
// 如果数据没有准备好,n会返回-1,errno设置为EWOULDBLOCK
  1. IO多路复用模型:

    这种模型使用selectpoll函数来监视多个文件描述符,当其中任何一个描述符准备好(可读、可写)时,就进行相应的IO操作。




int socket, n;
char buffer[1024];
fd_set read_set;
struct timeval timeout;
socket = socket(AF_INET, SOCK_STREAM, 0);
 
// 初始化文件描述符集合
FD_ZERO(&read_set);
FD_SET(socket, &read_set);
 
// 设置超时时间
timeout.tv_sec = 1;
timeout.tv_usec = 0;
 
// IO多路复用
n = select(socket + 1, &read_set, NULL, NULL, &timeout);
if (n > 0) {
    // 数据准备好,可以读取
    n = recv(socket, buffer, 1024, 0);
}
  1. 信号驱动IO模型:

    在这种模型中,进程使用sigaction系统调用来注册一个信号处理函数,当数据准备好时,就发送一个信号,然后在信号处理函数中进行IO操作。




// 信号处理函数
void sig_handler(int sig) {
    int n;
    char buffer[1024];
    // 在这里执行IO操作
    n = recv(socket, buffer, 1024, 0);
}
 
int socket;
struct sigaction act;
socket = socket(AF_INET, SOCK_STREAM, 0);
 
// 设置信号处理函数
act.sa_handler = sig_handler;
sigemptyset(&act.sa_mask);
act.sa_flags = 0;
sigaction(SIGIO, &act, 0);
 
// 启用信号驱动IO
fcntl
2024-08-19

在Kali Linux中更换软件源,你需要编辑/etc/apt/sources.list文件,将其中的官方源地址替换为中国大陆地区的镜像站点。以下是一些中国大陆地区的常用软件源站点,你可以选择一个或多个添加到sources.list中。

  1. 中科大源:



deb https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
deb-src https://mirrors.ustc.edu.cn/kali kali-rolling main non-free contrib
  1. 阿里云源:



deb https://mirrors.aliyun.com/kali kali-rolling main non-free contrib
deb-src https://mirrors.aliyun.com/kali kali-rolling main non-free contrib
  1. 浙大源:



deb https://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free
deb-src https://mirrors.zju.edu.cn/kali kali-rolling main contrib non-free
  1. 清华源:



deb https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free
deb-src https://mirrors.tuna.tsinghua.edu.cn/kali kali-rolling main contrib non-free
  1. 东软大学源:



deb https://mirrors.sustech.edu.cn/kali kali-rolling main non-free contrib
deb-src https://mirrors.sustech.edu.cn/kali kali-rolling main non-free contrib
  1. 重庆大学源:



deb https://mirrors.cqu.edu.cn/kali kali-rolling main non-free contrib
deb-src https://mirrors.cqu.edu.cn/kali kali-rolling main non-free contrib

更换源后,执行以下命令更新软件列表并升级系统:




sudo apt-get update
sudo apt-get upgrade
sudo apt-get dist-upgrade

请根据网络连接情况和需求选择合适的源,并确保源的可用性。如果源不可用,你可能需要切换回官方源或选择其他可用的中国大陆软件源。

2024-08-19

在Linux系统中,信号是一种进程间通信的方式,用以通知接收进程某个事件已经发生。

一、认识信号:

信号是软件中断,是一种异步事件处理机制。每个信号都有一个名字,如SIGINT、SIGTERM等,这些名字都以SIG开头。

二、信号的产生:

  1. 键盘产生信号:如用户按下Ctrl+C,产生SIGINT信号。
  2. 系统调用产生信号:如进程执行kill()系统调用,可以发送信号给其他进程。
  3. 硬件异常产生信号:如除以0、无效内存访问等,产生如SIGSEGV的信号。
  4. 系统状态变化产生信号:如定时器信号SIGALRM,通过alarm()setitimer()设置定时器时间。

三、深层次理解信号:

  1. 信号的处理方式:

    • 忽略信号:对信号不做任何处理,但是有两个信号不能忽略:SIGKILL和SIGSTOP。
    • 捕获信号并处理:定义信号处理函数,当信号发生时,执行相应的处理函数。
    • 执行默认动作:对于大部分信号,系统默认动作是终止进程。
  2. 信号的阻塞:

    • 信号阻塞是指,在一段时间内,阻止信号的传递。
    • 使用sigprocmask()函数可以阻塞信号,使用sigpending()可以查看当前被阻塞的信号。
  3. 实时发送信号:

    • 使用sigqueue()函数,可以向一个进程发送信号,并附带额外的信息。

四、Term与Core:

这两个信号通常用于请求进程正常退出或者core dump。

  • SIGTERM:是一个结束信号,它默认的动作是终止进程。
  • SIGCORE:是当进程因为某种异常条件(如内存访问错误)导致进程非正常退出时,生成的core dump后进程被发送的信号。

在实际编程中,可以通过signal()或sigaction()函数来设置信号处理函数,以对信号进行处理。

示例代码:




#include <stdio.h>
#include <signal.h>
#include <unistd.h>
 
void handler(int sig) {
    printf("Caught signal %d\n", sig);
    // 处理信号...
}
 
int main() {
    struct sigaction sa;
    sa.sa_handler = &handler;
    sa.sa_flags = 0;
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT, &sa, NULL);  // 注册信号处理函数
 
    while(1) {
        sleep(1);
    }
    return 0;
}

在这个例子中,程序会注册SIGINT(Ctrl+C 产生的信号)的处理函数handler。当用户按下Ctrl+C时,系统会发送SIGINT信号给该进程,进程会调用handler函数来处理这个信号。

2024-08-19

以下是一个简化的LAMP环境搭建脚本,包括安装Apache、MariaDB和PHP,并配置防火墙规则。




#!/bin/bash
 
# 更新系统
sudo yum update -y
 
# 安装Apache
sudo yum install -y httpd
sudo systemctl start httpd
sudo systemctl enable httpd
 
# 安装MariaDB
sudo yum install -y mariadb-server mariadb
sudo systemctl start mariadb
sudo systemctl enable mariadb
 
# 设置MariaDB root用户密码
sudo mysql_secure_installation
 
# 安装PHP
sudo yum install -y php php-mysql php-gd php-pear
 
# 创建一个示例页面
echo "<?php phpinfo(); ?>" | sudo tee /var/www/html/phpinfo.php
 
# 配置Apache配置文件
sudo sed -i 's/DirectoryIndex index.html/DirectoryIndex index.php index.html/' /etc/httpd/conf/httpd.conf
 
# 重启Apache
sudo systemctl restart httpd
 
# 配置防火墙,开放HTTP和HTTPS服务
sudo firewall-cmd --permanent --zone=public --add-service=http
sudo firewall-cmd --permanent --zone=public --add-service=https
sudo firewall-cmd --reload
 
echo "LAMP环境安装完成。"

这个脚本首先更新系统,然后安装Apache、MariaDB和PHP。之后,它配置MariaDB并启动服务,运行mysql_secure_installation设置root用户密码。接下来,安装PHP及其相关模块,并创建一个phpinfo页面以测试PHP安装。脚本还修改了Apache配置以识别PHP文件作为索引,并重启Apache服务。最后,配置防火墙以允许HTTP和HTTPS流量,并输出安装完成的消息。

2024-08-19

在Linux下安装和配置Sunshine串流以进行远程办公,您可以按照以下步骤操作:

  1. 安装VcXsrv Windows X Server 程序:

  2. 在Linux上安装X11-forwarding:

    • 确保ssh配置文件 /etc/ssh/sshd_config 中包含以下行并重启ssh服务:

      
      
      
      X11Forwarding yes
      X11DisplayOffset 10
      X11UseLocalhost no
    • 在客户端,使用ssh时加上 -X 参数来启用X11转发:

      
      
      
      ssh -X username@your_server_ip
  3. 在远程会话中安装sunshine串流服务器和客户端:

    • 服务器端安装(在Linux服务器上):

      
      
      
      sudo apt-get update
      sudo apt-get install sunshine-server
    • 客户端安装(在Windows上使用VcXsrv):

      
      
      
      sudo apt-get update
      sudo apt-get install sunshine-client
  4. 配置Sunshine:

    • 编辑服务器端的Sunshine配置文件 /etc/sunshine/sunshine-server.conf,设置监听端口和允许连接的客户端IP。
    • 在客户端机器上,设置环境变量DISPLAY指向VcXsrv监听的X server的地址(通常是:0)。
  5. 启动Sunshine服务:

    • 在服务器端启动Sunshine服务:

      
      
      
      sudo systemctl start sunshine-server
    • 在客户端,启动Sunshine客户端连接到服务器:

      
      
      
      sunshine-client [server_ip]
  6. 使用Sunshine进行远程桌面或应用程序:

    • 在Sunshine客户端启动远程桌面或应用程序,它们将在本地Windows桌面上显示。

请注意,Sunshine项目可能不再活跃,您可能需要查找替代解决方案,如XRDP或X2Go。同时,确保您的Linux服务器安全,并且仅允许信任的设备和用户进行X11转发。

2024-08-19

以下是一个简单的Linux进度条小程序示例,使用Shell脚本编写:




#!/bin/bash
 
# 进度条函数
progress_bar() {
    # 初始化进度条长度
    let progress_length=10-1
    for i in $(seq 1 $progress_length)
    do
        # 打印进度条
        echo -ne "[\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80\xe2\x96\x80]"
        sleep 0.5
        # 清除当前行的输出
        echo -ne "\r"
    done
    echo -ne "\n"
}
 
# 调用进度条函数
progress_bar

将以上代码保存为progress_bar.sh,并给予执行权限:




chmod +x progress_bar.sh

然后执行脚本:




./progress_bar.sh

这个脚本会打印出一个简单的ASCII进度条。每隔0.5秒更新一次进度条,并在完成后换行。

2024-08-19



# 查看当前系统的磁盘设备
lsblk
 
# 假设新磁盘为/dev/sdb,开始分区
sudo fdisk /dev/sdb
 
# 在fdisk命令行中,输入'n'创建新分区
# 输入'p'创建主分区
# 输入'1'为分区编号
# 输入第一个可用的扇区号
# 输入最后一个扇区号或者+大小G为分区大小
 
# 输入'w'保存并退出fdisk
 
# 格式化分区为ext4文件系统
sudo mkfs.ext4 /dev/sdb1
 
# 创建挂载点
sudo mkdir /mnt/newdisk
 
# 挂载新分区
sudo mount /dev/sdb1 /mnt/newdisk
 
# 查看挂载情况
df -h
 
# 为了让开机自动挂载,需要编辑/etc/fstab文件
# 添加一行如下:
echo '/dev/sdb1 /mnt/newdisk ext4 defaults 0 0' | sudo tee -a /etc/fstab

以上是创建Linux磁盘分区并挂载的基本步骤。在实际操作时,需要根据磁盘的实际情况(如磁盘的实际设备名称、分区大小等)进行相应的调整。

2024-08-19

在Linux系统中,进程可以处理一系列预定义的信号。信号是异步事件,表示一个进程发生了某种特定的条件或状态。

以下是一个简单的例子,展示了如何在Linux下编写一个进程,该进程能够捕获并处理SIGINT信号:




#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
#include <unistd.h>
 
void handle_sigint(int sig) {
    write(1, "Captured SIGINT\n", 16);
    exit(0);
}
 
int main() {
    struct sigaction sa;
    sa.sa_handler = &handle_sigint;
    sa.sa_flags = 0; 
    sigemptyset(&sa.sa_mask);
    sigaction(SIGINT, &sa, NULL);
 
    while(1) {
        sleep(1); // 让出CPU给其他进程,同时监听是否有信号到来
    }
 
    return 0;
}

这段代码首先定义了一个信号处理函数handle_sigint,它会在捕获到SIGINT信号时被调用。然后在主函数中,我们设置了一个sigaction结构体来配置我们的行为,当捕获到SIGINT信号时,调用handle_sigint函数。程序主循环中使用sleep(1)来避免CPU使用过度。

当你运行这个程序,并且通过按下Ctrl+C(这发送SIGINT信号给前台进程组中的所有进程),你会看到程序捕获信号并退出。

2024-08-19



#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <liburing.h>
 
#define BUFFER_SIZE 1024
 
int main(int argc, char *argv[]) {
    if (argc != 2) {
        printf("Usage: %s <file>\n", argv[0]);
        return 1;
    }
 
    struct io_uring ring;
    if (io_uring_queue_init(8, &ring, 0) != 0) {
        perror("io_uring_queue_init");
        return 1;
    }
 
    int fd = open(argv[1], O_RDONLY | O_NONBLOCK);
    if (fd < 0) {
        perror("open");
        return 1;
    }
 
    char *buffer = malloc(BUFFER_SIZE);
    if (!buffer) {
        perror("malloc");
        return 1;
    }
 
    struct io_uring_sqe *sqe = io_uring_get_sqe(&ring);
    if (!sqe) {
        fprintf(stderr, "No space for a new SQE\n");
        return 1;
    }
 
    io_uring_prep_read(sqe, fd, buffer, BUFFER_SIZE, 0);
    io_uring_sqe_set_data(sqe, buffer);
 
    int submit_ret = io_uring_submit(&ring);
    if (submit_ret != 1) {
        fprintf(stderr, "io_uring_submit: %d\n", submit_ret);
        return 1;
    }
 
    struct io_uring_cqe *cqe;
    unsigned head = 0;
    for (;;) {
        io_uring_wait_cqe(&ring, &cqe);
        if (cqe->res != BUFFER_SIZE) {
            fprintf(stderr, "Read failed: %ld\n", cqe->res);
            return 1;
        }
 
        char *buffer = (char *)io_uring_cqe_get_data(cqe);
        printf("Read: %s\n", buffer);
        free(buffer);
 
        io_uring_cq_advance(&ring, head);
        head++;
 
        // 重新提交读取操作
        sqe = io_uring_get_sqe(&ring);
        if (!sqe) {
            fprintf(stderr, "No space for a new SQE\n");
            return 1;
        }
 
        buffer = malloc(BUFFER_SIZE);
        if (!buffer) {
            perror("malloc");
            return 1;
        }
 
        io_uring_prep_read(sqe, fd, buffer, BUFFER_SIZE, 0);
        io_uring_sqe_set_data(sqe, buffer);
 
        submit_ret = io_uring_submit(&ring);
        if (submit_ret != 1) {
            fprintf(stderr, "io_uring_submit: %d\n", submit_ret);
            return 1;
        }
 
        // 退出循环条件:读取到文件末尾或发生错误
        if (cqe->res == 0) {
            break;
        }
    }
 
    close(fd);
    io_uring_queue_exit(&ring)