分类目录归档:技术

Linux 删除 LVM 步骤

以下为删除 LVM 步骤,需要按照顺序执行:

Step1. 卸载文件系统

卸载 LV 上的文件系统。

a.执行命令 mount –l 命令查看目前LV挂载到本地的目录。 b. 执行 umount 挂载的目录卸载挂载在LV上的文件系统。

Step2. 移除 LV

使用 lvdisplay 命令查询LV信息,获取需要删除 LV 的 LV name

使用 lvremove LV name 命令删除LV

# lvremove /dev/vg0/lv0

提示是否删除:

Do you really want to remove active logical volume "lv0"? [y/n]:

输入y 确认后显示如下信息,说明LV删除成功。

Logical volume "lv0" successfully removed

Step3. 移除 VG

删除VG。

# vgremove /dev/vg0

显示如下信息,说明PV删除成功。

Labels on physical volume "/dev/sda1" successfully wipedd

Step4. 移除 PG

使用 pvremove 命令移除 PV

最后使用 fdisk 修改 ID

参考文献

Linux 禁用 SWAP

在服务器和容器平台建议关闭 SWAP,避免内存交换影响服务器性能,甚至引发数据丢失。

一、不重启电脑,禁用启用swap,立刻生效

# 禁用命令

sudo swapoff -a

# 启用命令

sudo swapon -a

# 查看交换分区的状态
sudo free -m

二、重新启动电脑,永久禁用Swap

把根目录文件系统设为可读写

sudo mount -n -o remount,rw /

用vi修改/etc/fstab文件,在swap分区这行前加 # 禁用掉,保存退出

vi /etc/fstab

i      #进入insert 插入模式

:wq   #保存退出
mount -a
# 使 fstab 文件生效

重新启动电脑,使用free -m查看分区状态

reboot

sudo free -m

参考文献

pkg-config 自动补全 C 编译库依赖

pkg-config 是一个在源代码编译时查询已安装的库的使用接口的计算机工具软件。

工作原理

其工作原理如下: 当安装一个库时(例如从RPM,deb或其他二进制包管理系统),会包括一个后缀名为 pc 的文件,它会放入某个文件夹下(依赖于你的系统设置)。 例如,在 Linux 为该软件的库文件所在文件夹 lib 之下的子文件夹 pkgconfig 。 并把该子文件夹加入 pkg-config 的环境变量 PKG_CONFIG_PATH 作为搜索路径,例如在 bash 配置文件中加入一行:

$ export PKG_CONFIG_PATH=/usr/local/`库的名字`/lib/pkgconfig:$PKG_CONFIG_PATH

在这个.pc文件里包含有数个条目。这些条目通常包含用于其他使用这个库的程序编译时需要的库设置,以及头文件的位置,版本信息和一个简介。

这是一个用于libpng的.pc文件的样例:

prefix=/usr/local  
 exec_prefix=${prefix}  
 libdir=${exec_prefix}/lib  
 includedir=${exec_prefix}/include  
    
 Name: libpng12  
 Description: Loads and saves PNG files  
 Version: 1.2.8  
 Libs: -L${libdir} -lpng12 -lz  
 Cflags: -I${includedir}/libpng12

这个文件告诉我们这些库可以在/usr/local/lib找到,头文件可以在/usr/local/include里找到,库的名字是libpng12并且版本号是1.2.8。它也提供了用于编译依赖于libpng的源代码时需要的链接器参数。

这儿是一个编译时使用pkg-config的样例:

gcc -o test test.c $(pkg-config --libs --cflags libpng)

pkg-config 同其他命令一样,有很多选项,不过我们一般只会用到 --libs 和 --cflags 选项,分别用于搜索指定头文件和库文件。

在 Makefile 中则是这样来用:

...
DEPENDENCIES=libcpg libcmap libquorum libqb glib-2.0 fuse sqlite3 librrd

CFLAGS += -I.
CFLAGS += $(shell pkg-config --cflags ${DEPENDENCIES})

LDFLAGS += $(shell pkg-config --libs ${DEPENDENCIES})

.c.o:
        $(CC) $(CFLAGS) -c -o $@ $< -MMD -MT $@ -MF $@.d
...

参考文献

在 linux 中解析 lib 文件

解析 lib 文件可以获取一些二进制库的版本历史信息,例如解析 /usr/lib64/libc.so.6 即可解析到 glibc 的版本历史。

在Linux中,有许多工具可以用来解析库文件( .lib 文件)。 可以使用工具如 nm , objdump 和 readelf 来查看库文件的符号表,包含在库文件中的对象文件的信息,以及库文件的其他信息。

下面是一些常用的命令:

`nm`: 这个命令可以显示符号表信息。你可以运行 `nm <library-name>.lib` 来查看库文件的符号表信息。

`objdump`: 这个命令可以显示包含在库文件中的对象文件的信息。你可以运行 `objdump -p <library-name>.lib` 来查看库文件的信息。

`readelf`: 这个命令可以显示库文件的其他信息,包括符号表信息和对象文件信息。你可以运行 `readelf -a <library-name>.lib` 来查看库文件的信息。

这些命令可以帮助你解析库文件并查看其中包含的信息。

内容参考自 ChatGPT

阿里云域名续费优惠口令(com和cn续费优惠)- 2022

购买/续费云产品之前,找找优惠码是一个好习惯。

最近续费自己的 .com 域名,发现官方提供了优惠码,可以便宜一些。

获取方法是: 关注公众号“阿里云企航”,在输入框中输入“优惠口令”,即可自动回复当前最新可用的优惠口令 ,下面是我在2022年12月获取到的。

商品 行为 口令
com英文域名 续费 商标优选即买即用
cn英文域名 续费 商标智能在线检索
xin(普通词) 注册 只争朝夕
xin(普通词) 续费 不负韶华
xin(溢价词) 续费 抱诚守信

使用优惠码优惠前续费 .com 需要 75 :

使用优惠码后便宜了 6 块钱:

省的少也是钱,这是最近发现的省钱技巧,欢迎一起交流~

参考文献

查询谷歌账号注册时间方法(2022)

谷歌查看注册时间 具体方法如下:

打开“管理您的 Google 帐号”

打开“数据和隐私设置”

打开“您使用的应用和服务中的数据”-“下载或删除您的数据”-“下载您的数据”

选择 “Google 导出”选择“Google 帐号”

下载压缩包后,就可以查看html数据内容了

参考文献

Linux (Debian 系) 安装官方微信 (Electron,非 wine 版)

使用 Linux 作为唯一主力系统的阻力之一,就来自于微信。

微信大概是目前大多数人都无法离开的软件,而在 Linux 下安装微信在此前是比较复杂的,这对于使用 Linux 工作生活存在一些障碍。

最近才发现微信有推出基于 Electron.js 的一款桌面程序,不需要依赖 Wine 那复杂和冗余的依赖,只需要装一个稍微“大”一点的 deb 包就可以。

而且因为是基于 deb,理论来说 debian 系操作系统,如 Ubuntu、Kali 等都是可以直接安装的。

软件可以从优麒麟官网的软件下载页面找到:

https://www.ubuntukylin.com/applications/106-cn.html

在这个页面直接下载就可以,不要在其他陌生的地方下载。

下载下来之后看一下,一个平平无奇的 deb 软件包, debian 系操作系统直接 dpkg -i xx.deb 安装即可,基本不会出现依赖问题。

实测在 kali 下正常使用。安装完成,就可以在软件清单找到微信了,直接打开即可,扫码登录即可使用。

不要抱有太高期待,现阶段只是能用。不过这对于大部分会考虑使用 linux 做主系统的人们来说,应该是够用了。

实际上在优麒麟官网还可以找到其他一些常用软件,可以看到 QQ 和微信还有提供一种 crosscover 版,也就是基于 wine 的,在 linux 运行 windows 的方式运行,这种方式也许功能会多一些,但依赖实在太多,配置复杂,用起来很繁琐,不推荐使用。

总结一下,当前国产操作系统发展越来越好,虽然与 windows、macos 的差距还很大,而且对于底层技术的掌控也比较有限,但这是一个很好的趋势,提升自己在 linux 下的工作能力,对于技术人员或是工作离不开计算机的人们来说,长期来看很有益处。

另外,在 linux 下几乎可实现所有想要的功能,相对 windows 或 macos 的直接使用,可以在这一过程中获得更多成就感。

参考文献

ChatGPT 注册方法(附万能接码方法)

ChatGPT 是一个训练有素的语言模型,由 OpenAI 公司训练而成。目的是帮助回答问题,提供信息和支持,但不具备人类的感知能力,也不会回答所有问题。

以上自我介绍原始内容来自 ChatGPT 回答。

目前已经有人用 ChatGPT 开始水帖、水回答,目前 Stack Overflow 已经暂时屏蔽来自 ChatGPT 的回答。

V2ex,即刻等社交媒体的 ChatGPT 浓度极高,这样一款充满争议性和未来感的 AI,目前处于公测阶段,可以尝试,本文介绍其注册方法。

注册步骤

注册步骤就是常规的帐号密码,难点主要在短信验证,其余部份暂时略过。

短信验证

使用 sms-man 接码,一次几美分,失败可退款重试。

充值有最低值限制,也不浪费,还能用于注册各种平台,如 Apple ID, PayPal 等。

注册充值后,购买一次 OpenAI 的短信接码,之后不断点击接收,若长时间无法接收,则删除重试:

成功后将验证码回填 OpenAI 即可。

对了,这个 OpenAI 登陆时的验证码是区分大小写的:

演示

可以请他帮忙写文章:

甚至实现常见算法:

有没有一种强烈的危机感。

这款软件的出现,将大神和菜鸟的差距进一步拉大。

一次简单的对话

tl.song: Can you help me implement insertion sort in python

ChatGPR: Yes, I’d be happy to help you implement insertion sort in Python! Here’s an implementation you can use as a starting point:

def insertion_sort(arr):

# Iterate over the array, starting at index 1

for i in range(1, len(arr)):

# Save the value at the current index

current_value = arr[i]

# Iterate backwards over the sorted portion of the array

j = i
while j > 0 and arr[j - 1] > current_value:
# Shift the larger value to the right
arr[j] = arr[j - 1]
j -= 1

# Insert the saved value into the correct position

arr[j] = current_value

return arr

To use this implementation, you can call the insertion_sort function and pass in the array you want to sort. For example:

arr = [5, 1, 4, 2, 8]
sorted_arr = insertion_sort(arr)

# sorted_arr will be [1, 2, 4, 5, 8]

Insertion sort is a simple sorting algorithm that works well for small arrays or partially-sorted arrays, but it is not very efficient for large arrays. It has a time complexity of O(n^2) in the worst case, so it is not suitable for sorting very large arrays.

不仅实现了代码,还附带分析时间复杂度,程序员这碗饭越来越难抢了。

参考文献

部署 Prometheus 主机监控完全体

监控完全体 = Prometheus + Node Exporter + cadvisor + grafana

Prometheus 作为轮转数据库,从各个服务器采集数据; node-exporter 作为数据采集器,接受 prometheus 采集请求,上报主机各项参数; vadvisor 作为容器数据采集器,接受 prometheus 采集请求,上报主机 docker 各项参数; grafana 作为看板,从 prometheus 查询数据做数据可视化。

部署 Promoetheus

准备配置文件 /data/docker/prometheus/prometheus.yml

global:
  scrape_interval:     15s # By default, scrape targets every 15 seconds.

  # Attach these labels to any time series or alerts when communicating with
  # external systems (federation, remote storage, Alertmanager).
  external_labels:
    monitor: 'codelab-monitor'

# A scrape configuration containing exactly one endpoint to scrape:
# Here it's Prometheus itself.
scrape_configs:
  # The job name is added as a label `job=
<job_name>` to any timeseries scraped from this config.
  - job_name: 'prometheus'

    # Override the global default and scrape targets from this job every 5 seconds.
    scrape_interval: 5s

    static_configs:
      - targets: ['localhost:9090']

  # 采集node exporter监控数据
  - job_name: 'vps2'
    static_configs:
      - targets: ['10.28.0.1:9100']

准备数据文件夹,并设置访问权限为 nobody

# 创建文件夹
mkdir -p /data/docker/prometheus/data

# 取得nobody的uid
docker run --rm quay.io/prometheus/busybox cat /etc/passwd
···
nobody:x:65534:65534:nobody:/home:/bin/false

# 配置文件夹权限
chown 65534:65534 -R /data/docker/prometheus/data

启动 prometheus

$ docker run -d \
    --name=prometheus \
    -p 9090:9090 \
    --network=myDefault \
    --restart always \
    --volume /data/docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
    --volume /data/docker/prometheus/data:/prometheus \
    prom/prometheus:v2.40.4 \
    --web.enable-lifecycle \
    --config.file=/etc/prometheus/prometheus.yml \
    --storage.tsdb.path=/prometheus \
    --storage.tsdb.retention=365d

$ docker run -d \
    --name=prometheus \
    -p 9090:9090 \
    --network=myDefault \
    --restart always \
    --volume /data/docker/prometheus/prometheus.yml:/etc/prometheus/prometheus.yml \
    --volume /data/docker/prometheus/data:/prometheus \
    prom/prometheus:v2.40.4 \
    --web.enable-lifecycle \
    --config.file=/etc/prometheus/prometheus.yml \
    --storage.tsdb.path=/prometheus \
    --storage.tsdb.retention=365d
# --web.enable-lifecycle 允许热加载配置文件
# 注意放在镜像名后面的内容为映射到内部的配置标志

部署 Node Exporter 采集主机数据

可采用编译安装或包管理器直接安装。

编译安装

# x86
$ curl -OL https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-amd64.tar.gz
$ tar -xzf node_exporter-1.5.0.linux-amd64.tar.gz
$ cp node_exporter-1.5.0.linux-amd64/node_exporter /usr/local/bin/
# arm64
$ curl -OL https://github.com/prometheus/node_exporter/releases/download/v1.5.0/node_exporter-1.5.0.linux-arm64.tar.gz
$ tar -xzf node_exporter-1.5.0.linux-arm64.tar.gz
$ cp node_exporter-1.5.0.linux-arm64/node_exporter /usr/local/bin/

$ sudo useradd -rs /bin/false nodeusr

$ echo "[Unit]
Description=Node Exporter
After=network.target

[Service]
User=nodeusr
Group=nodeusr
Type=simple
ExecStart=/usr/local/bin/node_exporter

[Install]
WantedBy=multi-user.target" > /etc/systemd/system/node_exporter.service

$ sudo systemctl daemon-reload
$ sudo systemctl enable node_exporter && systemctl start node_exporter

Ubuntu 等直接安装:

$ apt search node_exporter
Sorting... Done
Full Text Search... Done
prometheus-node-exporter-collectors/focal 0+git20200110.fc91c86-1 all
  Supplemental textfile collector scripts for Prometheus node_exporter

$ apt install -y prometheus-node-exporter-collectors

# 启动服务
$ systemctl enable prometheus-node-exporter.service && systemctl start prometheus-node-exporter.service
Synchronizing state of prometheus-node-exporter.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install enable prometheus-node-exporter

# OpenWRT
opkg update
opkg install prometheus-node-exporter-lua \
prometheus-node-exporter-lua-nat_traffic \
prometheus-node-exporter-lua-netstat \
prometheus-node-exporter-lua-openwrt \
prometheus-node-exporter-lua-wifi \
prometheus-node-exporter-lua-wifi_stations

curl localhost:9100/metrics

cat /etc/config/prometheus-node-exporter-lua
config prometheus-node-exporter-lua 'main'
        option listen_ipv6 '0'
        option listen_port '9100'
        option listen_interface 'lan'

/etc/init.d/prometheus-node-exporter-lua restart

重载 prometheus 配置文件

# 方法一  使用 SIGHUP 信号
kill -HUP $(pidof prometheus)
# 方法二 使用 POST 请求,需 --web.enable-lifecycle
curl -X POST http://localhost:9090/-/reload
# 实测两种方法在 Docker 下均不生效,猜测外部修改必须重启才能映射入容器,原因待查

部署 cadvisor

# 这里使用了我在 docker hub 镜像的官方 gcr 源镜像
# 避免无法拉取问题
# 普通 docker hub 镜像即可拉取
$ sudo docker run \
  --restart always \
  --volume=/:/rootfs:ro \
  --volume=/var/run:/var/run:ro \
  --volume=/sys:/sys:ro \
  --volume=/var/lib/docker/:/var/lib/docker:ro \
  --volume=/dev/disk/:/dev/disk:ro \
  --publish=8080:8080 \
  --detach=true \
  --name=cadvisor \
  --privileged \
  --device=/dev/kmsg \
  --net=myDefault \
  songtianlun/cadvisor:v0.46.0
$ curl http://localhost:8080

部署 grafana

docker run -d \
    --name=grafana \
    -p 3000:3000 \
    --network=myDefault \
    --restart always \
    grafana/grafana

默认帐号: admin/admin

看板模版在这里找: https://grafana.com/grafana/dashboards/

参考文献