2024-08-23

以下是一个简化的示例,展示如何使用Traefik和frp进行内网穿透,以便远程访问Linux开源云原生网关。

  1. 安装Traefik:



# 下载最新版本的 Traefik
wget https://github.com/traefik/traefik/releases/download/v2.4.8/traefik_linux-amd64
# 重命名二进制文件
mv traefik_linux-amd64 /usr/local/bin/traefik
# 赋予执行权限
chmod +x /usr/local/bin/traefik
  1. 创建Traefik配置文件:



# traefik.yaml
log:
  level: INFO
 
api:
  insecure: true
 
entrypoints:
  web:
    address: ":80"
 
providers:
  file:
    filename: /etc/traefik/config/dynamic_conf.yaml
 
serversTransport:
  insecureSkipVerify: true
  1. 启动Traefik:



traefik --configfile traefik.yaml
  1. 安装并配置frp:



# 下载 frp 服务端和客户端
wget https://github.com/fatedier/frp/releases/download/v0.32.0/frp_0.32.0_linux_amd64.tar.gz
# 解压缩
tar -zxvf frp_0.32.0_linux_amd64.tar.gz
# 客户端和服务端放在同一台机器上,因此复制 frp 文件夹到另一个位置
cp -r frp_0.32.0_linux_amd64 /usr/local/frp-server
# 编辑 frps.ini 配置文件
[common]
bind_port = 7000
 
# 启动 frp 服务端
/usr/local/frp-server/frps -c /usr/local/frp-server/frps.ini
 
# 另外一台机器上
# 编辑 frpc.ini 配置文件
[common]
server_addr = <服务器公网IP>
server_port = 7000
 
[web]
type = http
local_port = 80
custom_domains = traefik.yourdomain.com
 
# 启动 frp 客户端
/usr/local/frp-server/frpc -c /usr/local/frp-server/frpc.ini
  1. 修改本地的 DNS 或 hosts 文件,将 traefik.yourdomain.com 指向你的服务器公网 IP。
  2. 通过浏览器访问 traefik.yourdomain.com,你将能够远程访问到你的 Traefik 仪表板。

请注意,这个示例假设你有一个公网IP的服务器,并且你已经设置了内网穿透服务(如frp),这样你的本地网络的其他设备才能访问到你的Traefik服务。

这个示例提供了一个简化的方法来部署Traefik,并通过内网穿透来远程访问,但是你需要根据你的实际网络环境和安全需求来调整配置。

2024-08-23

gethostbyname 函数用于将主机名转换为IP地址。它在网络编程中非常常见,特别是在编写基于TCP/IP的客户端和服务器程序时。

函数原型如下:




struct hostent *gethostbyname(const char *hostname);

返回值:成功返回指向 hostent 结构的指针,该结构包含了所请求主机的信息。失败返回 NULL,并设置 h_errno 全局变量为下列值之一:HOST_NOT_FOUND, TRY_AGAIN, NO_RECOVERY, NO_DATA

下面是一个简单的使用 gethostbyname 函数的C语言示例:




#include <stdio.h>
#include <stdlib.h>
#include <netdb.h>
#include <sys/socket.h>
 
int main(int argc, char *argv[]) {
    char *hostname;
    struct hostent *h;
    struct in_addr **addr_list;
    int i;
 
    if (argc != 2) {
        fprintf(stderr, "Usage: %s <hostname>\n", argv[0]);
        exit(1);
    }
 
    hostname = argv[1];
    h = gethostbyname(hostname);
 
    if (h == NULL) {
        herror("gethostbyname");
        exit(1);
    }
 
    addr_list = (struct in_addr **)h->h_addr_list;
 
    for (i = 0; addr_list[i] != NULL; i++) {
        printf("Address %d: %s\n", i, inet_ntoa(*addr_list[i]));
    }
 
    return 0;
}

这段代码接受一个主机名作为命令行参数,然后调用 gethostbyname 来解析这个主机名。如果解析成功,它会打印出所有的IPv4地址。注意,这个例子中使用了IPv4地址,因此主机必须至少有一个IPv4地址。如果你需要处理IPv6地址,你应该使用 h->h_addrtype 而不是硬编码使用 AF_INET

2024-08-23

在Linux系统中,管道是一种常见的进程间通信(IPC)机制,它可以把一个进程的输出作为另一个进程的输入。管道主要有两种类型:无名管道和命名管道。

无名管道是单向的,只能在有亲缘关系的进程间使用。它通过调用pipe()函数创建,该函数会填充一个整型数组包含两个元素,其中fd[0]用于读取,而fd[1]用于写入。

以下是一个使用无名管道的示例代码:




#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
 
int main() {
    int fd[2];
    pid_t pid;
    char buf;
 
    if (pipe(fd) == -1) {
        perror("pipe");
        exit(EXIT_FAILURE);
    }
 
    if ((pid = fork()) == -1) {
        perror("fork");
        exit(EXIT_FAILURE);
    }
 
    if (pid == 0) { 
        /* 子进程 */
        close(fd[1]); // 关闭写端
        while (read(fd[0], &buf, 1) > 0) {
            write(STDOUT_FILENO, &buf, 1);
        }
        close(fd[0]);
        _exit(EXIT_SUCCESS);
    } else {
        /* 父进程 */
        close(fd[0]); // 关闭读端
        write(fd[1], "Hello, World!", 14);
        close(fd[1]);
        wait(NULL);
    }
 
    return 0;
}

在这个例子中,父进程创建了一个管道,然后创建了一个子进程。父进程关闭了读端,通过写端发送数据“Hello, World!”,子进程关闭了写端,通过读端读取数据并打印。

命名管道(FIFO)允许无亲缘关系进程间通信。它通过mkfifo()函数创建一个文件,然后像读写文件一样对它进行操作。

以下是一个使用命名管道的示例代码:




#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
 
#define FIFO_NAME "/tmp/my_fifo"
 
int main() {
    char buf_r;
    int fd;
 
    // 创建命名管道
    if (mkfifo(FIFO_NAME, 0666) < 0) {
        perror("mkfifo");
        exit(1);
    }
 
    // 打开管道进行读取
    fd = open(FIFO_NAME, O_RDONLY | O_NONBLOCK, 0);
    if (fd < 0) {
        perror("open");
        exit(1);
    }
 
    while (1) {
        int n = read(fd, &buf_r, 1);
        if (n > 0) {
            printf("Received: %c\n", buf_r);
        }
    }
 
    close(fd);
    unlink(FIFO_NAME);
 
    return 0;
}

在这个例子中,首先创建了一个命名管道,然后打开它进行非阻塞读取。这样,即使当前没有数据可读,读取操作也不会阻塞,可以继续执行其他任务。

2024-08-23

在Linux中,tail 命令用于输出文件的最后几行。如果你想实时监控文件的更新,可以使用 tail -f 命令。

tail -f 命令的功能是:输出文件的最后几行,并在文件增长时输出增加的数据。-f 选项是 "follow" 的简写,意思是持续监控文件的更新。

例如,你可以使用 tail -f 命令来实时查看系统日志文件:




tail -f /var/log/syslog

如果你只是想查看文件的最后几行,那么使用 tail 命令就可以了:




tail /var/log/syslog

注意:tailf 并不是一个标准的 tail 命令的用法。可能你是想输入 tail -f。如果你的意图是监控文件的更新,那么使用 tail -f 是正确的命令。

2024-08-23

软硬链接和动态/静态库在Linux系统中都是常用的概念,下面是简要介绍和示例:

  1. 软链接(Symbolic Link):

    创建软链接的命令是ln -s,它创建的是一个符号链接,类似于Windows系统中的快捷方式。




ln -s /path/to/original /path/to/link
  1. 硬链接(Hard Link):

    创建硬链接的命令是ln,没有 -s 参数。硬链接会创建一个新的文件名指向同一个文件数据。




ln /path/to/original /path/to/link
  1. 动态库(Dynamic Library):

    在Linux中,动态库通常以.so(Shared Object)结尾,例如libexample.so。在编译时,只有在运行时才会将程序与动态库链接。

  2. 静态库(Static Library):

    静态库以.a结尾,例如libexample.a。在编译时,静态库的内容会被直接复制到程序中,程序运行时不再依赖静态库。

创建动态库的例子:




// example.c
int add(int a, int b) {
    return a + b;
}

编译为动态库:




gcc -shared -o libexample.so example.c

创建静态库的例子:




ar rcs libexample.a example.o

在这里,example.o 是通过 gcc -c example.cexample.c 源文件生成的目标文件。

2024-08-23

在Linux系统中,free命令用于显示系统内存的使用情况。free命令会报告总计的、已用的、空闲的物理内存和交换内存,还会报告共享内存和缓冲区。

free命令输出中的Mem行(对于总计的内存)和-/+ buffers/cache行(对于可用的内存),有时会造成理解上的混淆。

总计的内存(Mem)= 物理内存总量(total)

已使用的内存(used)= 总内存量 - 空闲内存量(free)

空闲的内存(free)= 缓冲区和缓存(buffers + cached)

可用的内存(available)是从应用程序的角度来看的可以被用来进行新分配的内存量,它考虑了内核的预留和当前的需求。

可用内存(available)≈ 空闲的内存(free) + 缓冲区被释放的内存(buffers) + 缓存被释放的内存(cached)

注意,这里的“释放”意味着内存被交换出来,可以立即被用于其他用途。

在命令行中,你可以通过以下命令来获取freeavailable内存的信息:




free -h

这将以易读的格式(如GB、MB)显示内存信息。-h参数是可选的,但它会让输出更易于阅读。

如果你想要获取可以用Python脚本来获取这些信息,你可以使用psutil库,这是一个跨平台的进程和系统实用工具模块。




import psutil
 
mem = psutil.virtual_memory()
 
print(f"Total: {mem.total / 1024 ** 2} MB")
print(f"Available: {mem.available / 1024 ** 2} MB")
print(f"Used: {(mem.total - mem.available) / 1024 ** 2} MB")

这段Python代码会输出总计的内存、可用的内存和已使用的内存,所有的值都是以MB为单位。

2024-08-23



#!/bin/bash
 
# 创建云盘
create_volume() {
    echo "创建云盘中..."
    volume_id=$(huaweicloud ecs CreateVolume --availability-zone "az1.example.com" --size 100 --volume-type SATA --profile "default" | grep "| id" | awk '{print $4}')
    echo "云盘创建成功,云盘ID: ${volume_id}"
}
 
# 等待云盘就绪
wait_for_volume_status() {
    echo "等待云盘就绪中..."
    huaweicloud ecs WaitForVolumeStatus --volume $1 --status "available" --profile "default"
    echo "云盘就绪"
}
 
# 挂载云盘
attach_volume() {
    echo "挂载云盘中..."
    device_name=$(huaweicloud ecs AttachVolume --volume $1 --instance-id "i-xxxxx" --device "/dev/vdc" --profile "default" | grep "device" | awk '{print $4}')
    echo "云盘挂载成功,设备名: ${device_name}"
}
 
# 初始化云盘
initialize_volume() {
    echo "初始化云盘中..."
    mkfs.ext4 /dev/vdc
    echo "云盘初始化成功"
}
 
# 挂载点目录
mount_point="/mnt/cloud_disk"
 
# 主程序
main() {
    create_volume
    volume_id=$(echo ${volume_id##*id = })
    wait_for_volume_status ${volume_id}
    attach_volume ${volume_id}
    mkdir -p ${mount_point}
    mount /dev/vdc ${mount_point}
    echo "${mount_point} /dev/vdc ext4 defaults 0 0" >> /etc/fstab
}
 
main

这段代码首先定义了创建云盘、等待云盘就绪、挂载云盘和初始化云盘的函数。主程序中依次调用这些函数来完成一个完整的流程。这个流程展示了如何在Linux环境下管理云盘,包括创建、挂载和格式化。

2024-08-23

在Linux上安装CMake通常可以通过包管理器来完成。以下是一些常见Linux发行版的安装命令:

对于基于Debian的系统(如Ubuntu):




sudo apt-update
sudo apt-get install cmake

对于基于RedHat的系统(如Fedora或CentOS):




sudo yum install cmake

对于Fedora(使用dnf代替yum):




sudo dnf install cmake

对于Arch Linux:




sudo pacman -S cmake

对于openSUSE:




sudo zypper install cmake

安装完成后,可以通过运行cmake --version来检查CMake是否正确安装。

2024-08-23

为了交叉编译适用于Linux aarch64平台的Qt5,你需要设置合适的交叉编译工具链并配置Qt源码编译系统。以下是一个基本的步骤概述:

  1. 安装交叉编译工具链,例如Linaro的Aarch64编译器。
  2. 下载Qt5的源码。
  3. 配置源码以进行交叉编译。
  4. 编译并安装Qt5。

以下是具体的命令示例:




# 安装交叉编译工具链
sudo apt-get install g++-aarch64-linux-gnu
 
# 下载Qt5源码
wget http://download.qt.io/official_releases/qt/5.15/5.15.2/single/qt-everywhere-src-5.15.2.tar.xz
tar xf qt-everywhere-src-5.15.2.tar.xz
cd qt-everywhere-src-5.15.2
 
# 配置Qt编译环境
./configure -prefix /usr/aarch64-linux-gnu -opensource -confirm-license -release -make libs -xplatform linux-aarch64-gnu-g++ -optimized-qmake -pch -qt-libjpeg -qt-libpng -qt-zlib -nomake examples -nomake tests
 
# 编译并安装Qt
make -j$(nproc)
sudo make install

请注意,你需要根据你的目标平台和Qt版本调整交叉编译选项。上面的示例使用了Linaro的Aarch64交叉编译器,并假设你的目标平台是基于GNU的系统。如果你的目标平台有不同的ABI,你可能需要使用相应的交叉编译工具链和调整xplatform参数。

2024-08-23

在 Linux 中,可以使用 >>> 操作符来将命令的输出重定向到文件中。> 用于将输出重定向到文件,如果文件已存在则会覆盖它。而 >> 会将输出追加到文件的末尾,如果文件不存在则会创建它。

同时,可以使用 tee 命令将输出同时发送到文件和标准输出(屏幕)。

例子:

ls 命令的输出重定向到 list.txt 文件中,覆盖文件内容:




ls > list.txt

ls 命令的输出追加到 list.txt 文件的末尾:




ls >> list.txt

ls 命令的输出同时重定向到 list.txt 文件和屏幕:




ls | tee list.txt

ls 命令的输出同时追加到 list.txt 文件和屏幕:




ls | tee -a list.txt