Linux技术栈 —— 运维基础

〇、基础知识

0.1 安装虚拟机

首先,既然接触了Linux,就永远不要怕把机器折腾坏,装一个用来测试的Linux虚拟机,就用来玩这些危险命令,或者是你觉得可能把机器搞坏、搞的别扭的命令,不要担心重装系统,多重装几遍到时候你真遇到问题反而是好事,要不怕操作Linux的任何命令,就是干!

参考文章
[1] CentOS 7 5 Installation with LVM Partitioning

0.2 Linux目录详解

参考文章
《Linux系统中目录的内容详解—bin、dev、etc、home、lib、opt、usr、var》

一、进程管理

1.1 查找特定name进程并杀死

# 定义颜色
RED='\033[0;31m'  # 红色
NC='\033[0m'      # 没有颜色(重置)

proc_name="xxxx" 
proc_id=$(ps -ef | grep ${proc_name} | grep -v grep | awk '{print $2}') 
# 注意,这里的过滤条件还是比较粗糙的,为避免误杀,请给proc_name的命名以严格限制,或者多加几道grep过滤条件
# 如: ps -ef | grep ${proc_name} | grep -v grep | grep .. | grep .. | [grep ..]
if [ -n "${proc_id}" ]; then
    echo "找到进程名为${proc_name}的进程,其PID为:${proc_id}"
    kill -9 ${proc_id}
else
    echo -e "${RED}未找到名为${proc_name}的进程!${NC}"
fi

对上面这几行命令做下解释
(1) ps -ef | grep ${proc_name} 意思为找到所有 名字包含了proc_name 的进程
(2) grep -v grep 即过滤掉grep查找进程本身
(3) awk '{print $2}' 提取找到的进程行记录中第二列的参数,也就是flask的进程号,printawk的一个内置函数, awk '{print $2}' 文件名会读取文件名指定的文件,并输出每一行的第二个字段的值。
(4) if [ -n xx]Shell scripting: -z and -n options with if-n的意思是用来判断字符串非空的

然后,我们还可以对这段脚本做一下升级,用一个名字数组,以后就可以批量化查杀进程了。

#!/bin/bash
# 定义颜色
RED='\033[0;31m'  # 红色
NC='\033[0m'      # 没有颜色(重置)
GREEN='\033[0;32m' # 绿色

# 定义包含进程名称的数组或读取自文件
# 方法 1: 使用数组
process_names=("process_name_1" "process_name_2" "process_name_3")

# 方法 2: 从文件读取(每行一个进程名称)
# process_names=($(cat process_list.txt))

# 遍历每个进程名称
for proc_name in "${process_names[@]}"; do
    echo "正在查找进程名为 ${proc_name} 的进程..."

    # 查找进程 ID
    proc_ids=$(ps -ef | grep "${proc_name}" | grep -v grep | awk '{print $2}')
    
    # 检查是否找到进程
    if [ -n "${proc_ids}" ]; then
        echo -e "${GREEN}找到进程名为 ${proc_name} 的进程,其PID为:${proc_ids}${NC}"
        
        # 遍历找到的进程 ID 并查杀
        for pid in ${proc_ids}; do
            echo "正在杀掉进程 PID: ${pid}..."
            kill -9 ${pid}
            if [ $? -eq 0 ]; then
                echo -e "${GREEN}成功杀掉进程 PID: ${pid}${NC}"
            else
                echo -e "${RED}无法杀掉进程 PID: ${pid},请检查权限或进程状态。${NC}"
            fi
        done
    else
        echo -e "${RED}未找到名为 ${proc_name} 的进程!${NC}"
    fi
done
参考文章
《Linux下如何通过一行命令查找并杀掉进程》

1.2 查找特定port的进程并杀死

1.3 jar包启动脚本

#!/bin/bash

JAR_NAMES=("yourApp.jar")
PID_FILES=("yourApp.pid")
LOG_FILES=("yourApp.log")

start() {
    local jar_to_start=$1
    for i in "${!JAR_NAMES[@]}"; do
        JAR_NAME="${JAR_NAMES[$i]}"
        PID_FILE="${PID_FILES[$i]}"
        LOG_FILE="${LOG_FILES[$i]}"

        if [ -n "$jar_to_start" ] && [ "$jar_to_start" != "$JAR_NAME" ]; then
            continue
        fi

        if [ -f "$PID_FILE" ]; then
            echo "应用程序 $JAR_NAME 已在运行,PID: $(cat $PID_FILE)"
        else
            echo "启动应用程序 $JAR_NAME..."
            nohup java -jar "$JAR_NAME" > "$LOG_FILE"  &
            echo $! > "$PID_FILE"
            echo "应用程序 $JAR_NAME 已启动,PID: $(cat $PID_FILE)"
        fi
    done
}

stop() {
    local jar_to_stop=$1
    for i in "${!JAR_NAMES[@]}"; do
        JAR_NAME="${JAR_NAMES[$i]}"
        PID_FILE="${PID_FILES[$i]}"

        if [ -n "$jar_to_stop" ] && [ "$jar_to_stop" != "$JAR_NAME" ]; then
            continue
        fi

        if [ -f "$PID_FILE" ]; then
            echo "停止应用程序 $JAR_NAME,PID: $(cat $PID_FILE)..."
            kill $(cat "$PID_FILE")
            rm -f "$PID_FILE"
            echo "应用程序 $JAR_NAME 已停止"
        else
            echo "没有找到运行中的应用程序 $JAR_NAME"
        fi
    done
}

restart() {
    local jar_to_restart=$1
    stop "$jar_to_restart"
    start "$jar_to_restart"
}

status() {
    local jar_to_status=$1
    for i in "${!JAR_NAMES[@]}"; do
        JAR_NAME="${JAR_NAMES[$i]}"
        PID_FILE="${PID_FILES[$i]}"

        if [ -n "$jar_to_status" ] && [ "$jar_to_status" != "$JAR_NAME" ]; then
            continue
        fi

        if [ -f "$PID_FILE" ]; then
            echo "应用程序 $JAR_NAME 正在运行,PID: $(cat $PID_FILE)"
        else
            echo "应用程序 $JAR_NAME 未运行"
        fi
    done
}

case "$1" in
    start)
        start "$2"
        ;;
    stop)
        stop "$2"
        ;;
    restart)
        restart "$2"
        ;;
    status)
        status "$2"
        ;;
    *)
        echo "用法: $0 {start|stop|restart|status} [jar_name]"
esac

exit 0

1.4 查看Nvidia GPU显存情况

#!/bin/bash

# 检查 nvidia-smi 是否可用
if ! command -v nvidia-smi &> /dev/null; then
    echo "nvidia-smi 命令未找到,请确保已安装 NVIDIA 驱动程序和工具。"
    exit 1
fi

# 函数:将 MiB 转换为 GB(保留前导零和两位小数)
convert_mib_to_gb() {
    printf "%.2f" "$(echo "scale=2; $1 / 1024" | bc)"
}

# 获取 GPU 数量
gpu_count=$(nvidia-smi --query-gpu=name --format=csv,noheader | wc -l)

# 遍历每个 GPU 获取显存信息和运行的进程
for ((i=0; i<gpu_count; i++)); do
    gpu_name=$(nvidia-smi --query-gpu=name --format=csv,noheader,nounits -i $i)
    memory_total_mib=$(nvidia-smi --query-gpu=memory.total --format=csv,noheader,nounits -i $i)
    memory_used_mib=$(nvidia-smi --query-gpu=memory.used --format=csv,noheader,nounits -i $i)
    memory_free_mib=$(nvidia-smi --query-gpu=memory.free --format=csv,noheader,nounits -i $i)
    
    memory_total_gb=$(convert_mib_to_gb $memory_total_mib)
    memory_used_gb=$(convert_mib_to_gb $memory_used_mib)
    memory_free_gb=$(convert_mib_to_gb $memory_free_mib)
    
    echo "GPU $i: $gpu_name"
    echo "  总显存: ${memory_total_gb} GB"
    echo "  已用显存: ${memory_used_gb} GB"
    echo "  空闲显存: ${memory_free_gb} GB"
    
    echo "  正在运行的进程及其显存使用情况:"
    
    # 获取正在使用该 GPU 的进程
    nvidia-smi --query-compute-apps=pid,process_name,used_memory --format=csv,noheader,nounits -i $i | while IFS=',' read -r pid process_name used_memory_mib; do
        if [ -n "$pid" ]; then
            used_memory_gb=$(convert_mib_to_gb $used_memory_mib)
            # 显示进程信息
            echo "    PID: ${pid}, 进程名: ${process_name}, 使用显存: ${used_memory_gb} GB"
        fi
    done
    
    echo ""
done

也可以安装nvitop进行查看。

1.5 会话与窗口解绑之tmux

一个典型的例子就是,SSH 登录远程计算机,打开一个远程窗口执行命令。这时,网络突然断线,再次登录的时候,是找不回上一次执行的命令的。因为上一次 SSH 会话已经终止了,里面的进程也随之消失了。

为了解决这个问题,会话与窗口可以解绑:窗口关闭时,会话并不终止,而是继续运行,等到以后需要的时候,再让会话"绑定"其他窗口。

1.4 参考视频或文章链接
[1] Tmux 使用教程

二、磁盘管理

2.1 磁盘挂载

2.2 磁盘空间分配与扩容

如果是单磁盘,可以偷个懒,在VMware中直接扩展磁盘容量,然后重新分配大小即可

2.2 参考视频或文章链接
[1] 《VMware上的linux虚拟机磁盘空间满了,如何扩充磁盘空间?》—— 优快云
[2] 《为虚拟机指定磁盘容量》—— VMware DOC
[3] 《VMware虚拟机扩展磁盘空间》—— 优快云
[4] 《增加 VM虚拟机硬盘容量》—— 优快云
[5] Ubuntu-Server服务器版本重点查看,可快速解决 《ubuntu 里根文件系统的扩容,/dev/ubuntu-vg/ubuntu-lv 文件系统扩充到整个分区》—— 优快云
[6] LVM Extending Fails
[7] Resizing Ubuntu partition with resize2fs
[8] Linux分区工具:Fdisk与Parted以及GParted
[9] 笔者实战,可以参考 Linux技术栈 —— 记一次Ubuntu系统 / 目录磁盘扩容

2.3 parted对Linux进行磁盘扩容

2.3 参考视频或文章链接
[1] 《使用parted命令为磁盘扩容》—— 优快云
[2] 《linux下无损扩容分区方法》—— 知乎

三、文件管理

3.1 删除文件

操作方式评价
rm -rf /path/to/xxxfolder[file]-r是recursively递归删除,-f是forcely强制删除,一旦在root权限下执行,可能造成不可逆的损失
trash filename先使用sudo apt install trash-cli安装该工具,该命令删除的文件会在垃圾箱中,即~/.local/share/Trash/files目录下,确认要清空垃圾箱,请使用trash-empty
mv filename ~/.local/share/Trash/filesmv命令,把文件移动至垃圾箱中,使用find ~/.local/share/Trash/* -delete命令清空,这个命令不用安装trash-cli

总结:其实Linux中,删除文件或文件夹的命令常用的还是rm,但是一旦获取了root用户权限,这个命令就比较危险了,要安全方向的删除文件的话,考虑trashmv,其实trash底层彻底清空文件也是用rm,但是它封装好了,就比较安全。另外,选中文件Shift + Delete是永久删除。并且root用户如果没有执行过trash命令的话,是没有对应的Trash文件夹的,那root用户能执行trash吗?答案是可以,trash会自动创建。

参考视频或文章链接
《你不知道Linux的10个最危险的命令》
How to Empty the Trash in Linux CLI - Baeldung Linux
How to Delete a File in Linux (5 Methods)

3.2 查找指定内容的文件

你想找到这样的一份文件,这份文件的某一行出现了你感兴趣的数据,那么在linux中如何完成这件事?

# 1.搜索多个文件并显示行号
grep -rn "example" *.txt
# 2.递归搜索当前目录中所有文件
grep -rn "example" .
# 3.正则表达式搜索
grep -rnE "exa(mple|ct)" /path/to/directory

3.3 解压文件到指定目录

mkdir -p /your_path/demo_dir/ && tar -zxvf demo.tar.gz -C /your_path/demo_dir/

四、Shell编程

4.1 脚本接受多个参数并选择执行

稍微有点项目经验的话,你可能运行过类似于startApplication.sh startstartApplication.sh restart这样的命令,可以根据参数的不同,决定是启动还是重启,那么这样的脚本实现原理是什么?

#!/bin/bash
#test.sh
# 获取参数
param1=$1
param2=$2
# 使用case语句判断参数值并执行相应命令
case $param1 in
"option1")
        echo "执行命令1"
        ;; # case语句中的结束符,表示当前条件分支已经处理完毕。
"option2")
        echo "执行命令2"
        ;;
*)
        echo "未知参数,请输入正确的选项"
        ;;
esac # case语句的结束。
echo "第2个参数为:${param2}"

赋予文件可执行权限,你会看到以下效果,因此你可以在此基础上继续延伸,开发出你想要的脚本文件功能。

# ./test.sh option1 args2
执行命令1
第2个参数为:args2
# ./test.sh option2 args2
执行命令2
第2个参数为:args2

五、系统配置

5.1 配置网络代理proxy

基本的方法是配置HTTP_PROXYHTTPS_PROXY

# /etc/profile 或 ~/.bashrc 中添加
export HTTP_PROXY="http://{your_ip}:7890"
export HTTPS_PROXY="https://{your_ip}:7890"

另外,就是要打开CFW的Allow LAN配置,最后如果还是不行,再升级下openssl

# 升级 OpenSSL
sudo apt upgrade openssl

5.2 开机自启动

参考文章或视频链接
[1] How to start program at Linux boot automatically

六、用户管理

6.1 普通用户权限

在一个新安装的 Linux 操作系统中,普通用户对系统文件夹的权限通常是受到严格限制的,以确保系统安全性和稳定性。普通用户(非 root 用户)通常拥有以下文件夹的权限:

# 用户主目录。
/home/username
# 临时目录。一个公共的临时存储区域,常用于程序运行时的临时文件存储
/tmp
# /var/tmp 目录中的文件在系统重启后通常不会被清除,适合存储需要在重启后仍然可用的临时文件
/var/tmp
# 系统在登录时为每个用户动态创建的,用于存放与用户会话相关的临时文件(例如,锁文件、socket 文件等)。UID 是用户的用户 ID。
/run/user/UID

# 其他具有全局 读 权限的目录
/root:超级用户(root)的主目录,普通用户没有权限。
/etc:存放系统配置文件,普通用户一般只具有读权限。
/boot:存放启动加载器及其配置文件,普通用户没有写权限。
/var(除 /var/tmp 外):用于存放日志文件、锁文件、缓存等系统级文件,普通用户通常没有写权限(但某些子目录可能有例外)。
/opt:用于存放第三方软件包,普通用户通常没有写权限。

所以说,安装的软件如果要全局用户可见,一般只能由 root 或具有 sudo 权限的用户来进行,普通用户在Linux操作系统中没有民主,Linux是典型的中央集权设计操作系统,只有早期的OS才不是中央集权设计,未来如果区块链盛行,OS也可能接纳区块链的设计理念,回归到更高阶的分布式用户OS上来。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值