Linux——使用相关笔记


内存查看

  • top 看到的内存会将 分配的 bufffer 等也算作已经使用
    • 注:遇到过 top 出 Bug 的情况,会让人感觉资源已经占满,实际上并没有,此时建议使用 free -h 看看
  • 使用 free -h 可看到更真实的内存
    • total:物理内存总量
    • used:已使用(不包含 buffers/cache)
    • free:完全未使用
    • buff/cache:缓存和缓冲区(可回收)
    • available:真正还能给应用用的内存(最重要),评估系统还能提供多少内存给新启动的应用程序使用
      • 它等于 free 加上 buff/cache 中可回收的部分
      • 判断系统是否缺内存,主要看这个指标,而不是看 free

查看文件

  • 抽取文件:输出某个文件的某一行(比如第二行)

    1
    sed -n '2p' filename
    • 2 是行号
    • p 是 print 的含义
  • 批量统计文件行数

    1
    wc -l *.jsonl
  • 批量统计文件行数并排序

    1
    wc -l *.jsonl | sort -nr
    • sort -nr:对结果按数字倒序排序
      -n:按数值排序(不是字符串)
      -r:倒序(从大到小)
  • 批量统计文件函数并删除最后的 total 行

    1
    wc -l *.jsonl | grep -v total | sort -nr
  • 抽取某个文件下所有文件的前 100 行(or 随机抽取):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
       # 抽取前 100 行
    head -q -n 100 xxx/*.jsonl > output.jsonl

    # 随机抽取(错误示例):shuf 会将后面的文件视作一个,shuf 期望输入是一个文件,但 *.jsonl 会展开成多个文件,导致错误
    shuf -n 100 /path/to/dir/*.jsonl > output.jsonl

    # 正确随机抽取示例:
    find /path/to/dir/ -name "*.jsonl" -exec shuf -n 100 {} \; > output.jsonl
    ## 或者
    for f in /path/to/dir/*.jsonl; do shuf -n 100 "$f"; done > output.jsonl # 注: `> output.jsonl` 作用于整个 `for … done` 结构,而不是某一次 shuf
    • 注:head在同时处理多个文件时,默认会输出类似下面的结果,-q(quiet)用来关闭这些文件名分隔符
      1
      2
      3
      4
      ==> file1.jsonl <==
      line1
      ==> file2.jsonl <==
      line1

SSH 使用相关

SSH 登陆

  • 登录命令

    1
    ssh -p 22 user@host
    • 注意:端口默认为 22

SSH 复制远程文件

  • 复制命令,拉取文件

    1
    scp -P 2222 user@host:/remote/file.txt /local/
    • -P 是大写的,不是 -p-p是保留修改时间
  • 复制命令,拉取目录

    1
    scp -P 2222 -r user@host:/remote/dir /local/

vim 或 less 查看中文乱码

  • 表现:Linux 中,直接 cat 得到的结果是正常的,但是 less 或者 vim 打开得到的中文是乱码的
  • 根本原因: lessvim 的字符集设置,与系统或文件本身的编码不一致
    • cat 命令的输出直接显示在终端上,继承了终端的编码设置
    • lessvim 作为独立程序,有自己的一套编码处理逻辑,需要单独配置

修复 less 中文乱码

  • 仅针当前文件时,可以 -r 参数,让 less 直接显示原始控制字符(亲测好用)

    1
    less -r 文件名
  • 或者在终端执行以下命令,立即生效

    1
    export LESSCHARSET=utf-8
    • 注:可将环境变量写入配置文件,避免每次都要手动设置
    • 注:如果设置 utf-8 无效,可以尝试 latin1
      1
      export LESSCHARSET=latin1

修复 vim 中文乱码

  • vim 乱码通常是文件编码与 vim 的内部编码(encoding)或解码顺序(fileencodings)不匹配

  • vim 中执行以下命令,尝试手动指定编码

    1
    2
    3
    # 一般第一个命令后生效了
    :set encoding=utf-8
    :set fileencodings=utf-8,gbk,gb2312,gb18030
  • 注:可以考虑编辑 vim 的配置文件 ~/.vimrc(如果不存在则新建),添加以下内容:

    1
    2
    3
    4
    5
    6
    " 设置 vim 内部使用的编码
    set encoding=utf-8
    " 设置终端使用的编码
    set termencoding=utf-8
    " 设置打开文件时尝试的解码顺序(从左到右)
    set fileencodings=utf-8,gbk,gb2312,gb18030,ucs-bom
    • 这样设置后,vim 会按顺序尝试解码,能适应大部分中文文件

wait 命令

  • 在 Shell 脚本中,wait 是一个内置命令 ,其核心含义是:暂停当前 Shell 进程的执行,直到指定的后台子进程结束
    • 不带参数时:等待当前 Shell 的所有后台子进程 全部结束
    • 带参数时:wait PIDwait %任务号,等待指定的某一个 后台进程结束
  • 执行 wait 时,脚本会卡在这一行,直到被监控的进程退出
  • 返回值(退出码):wait 会返回被等待进程的退出状态(Exit Code)
    • 如果被等待的进程正常退出(exit 0),wait 返回 0
    • 如果被等待的进程异常退出(exit 1),wait 返回 1
    • 如果等待的是一个不存在的进程(比如已经结束),wait 会立即返回 127

常用示例

  • wait 最常用的场景:在脚本中实现简单的多任务并发

    • 没有 wait 的情况(串行执行,耗时 6 秒):

      1
      2
      3
      sleep 3
      sleep 3
      echo "完成" # 总耗时 6 秒
    • 有 wait 的情况(并发执行,耗时 3 秒):

      1
      2
      3
      4
      sleep 3 &  # 后台运行(& 让它在后台执行)
      sleep 3 & # 后台运行
      wait # 等待上述两个后台任务全部完成
      echo "完成" # 总耗时约 3 秒,且“完成”一定会在两个 sleep 结束后才打印

进阶用法:捕获退出状态

  • 如果想并发执行任务,但又想拿到每个任务的执行结果,可以这样做:
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    sleep 5 &
    pid1=$!
    sleep 2 &
    pid2=$!

    # 分别等待并获取状态
    wait $pid1
    echo "任务1退出码: $?" # 输出 0
    wait $pid2
    echo "任务2退出码: $?" # 输出 0

特别说明

  • 仅限子进程:
    • wait 只能等待当前 Shell 的直接子进程
    • 如果你启动了一个子 Shell(比如 (sleep 10) &)或者孙子进程,wait 对非直接子进程无效
  • 信号处理:如果在 wait 阻塞期间,脚本收到了 SIGINT(Ctrl+C),wait 会被中断,脚本会退出