Linux Shell

本文章随时可能更新

随着东西越来越多,可能不限于 Linux 了,-_-b

环境配置

bash

.bashrc

# If not running interactively, don't do anything
[[ $- != *i* ]] && return

PS1='[\u@\h \W]\$ '

# 快速 push
function gpush() {
    Branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
    if [[ $? -ne 0 ]]; then
        echo "not a git repository"
        return
    fi

    git push origin ${Branch}:${Branch}
}

# 快速 commit 备份
function gsave() {
    if [[ -n "$WF" ]]; then
        if [[ "$WF" != "$(pwd)" ]]; then
            echo "pwd is directory:     $(pwd)"
            echo "not in workspace:     $WF"
            return
        fi
    fi 

    Branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)
    if [[ $? -ne 0 ]]; then
        echo "not a git repository"
        return
    fi

    Now=$(date +%Y%m%d%H%M%S)
    NewBranch="ohyee-backup-$Now"
    git checkout -b $NewBranch && git add . && git commit -c $Branch

	git status
	echo "use `gpush` to push"
}


# alias
alias ls='ls --color=auto'
alias ll="ls -l"
alias pc="proxychains"
alias sb="source ~/.bashrc"
alias h=history
alias hh="history | grep"
alias cnpm="npm --registry=http://registry.npm.taobao.org" 		
alias tnpm="npm --registry=http://registry.npm.alibaba-inc.com"

# history
export HISTCONTROL=ignoredups
export HISTSIZE=100000
export HISTFILESIZE=100000
export HISTTIMEFORMAT='%F %T '
export HISTCONTROL=ignoreboth

# PATH
export PATH=$PATH:/home/ohyee/.local/bin
export PATH=$PATH:/home/ohyee/.cargo/bin
export PATH=$PATH:/home/ohyee/go/bin
export PATH=$PATH:/home/ohyee/.yarn/bin

export ENV_FOLDER=$HOME/env
mkdir -p $ENV_FOLDER
export PATH=$PATH::$ENV_FOLDER/bin
for folder in $(ls -alR $ENV_FOLDER  | grep "^l" | tr -s " " | cut -d " " -f 9); do
    export PATH=$PATH:$ENV_FOLDER/$folder/bin
done

# PS1
export PS1='$(if [ $? -eq 0 ]; then echo -ne "\[\e[1;32m\]$\[\e[0m\]"; else echo -ne "\[\e[1;31m\]$\[\e[0m\]"; fi) \[\e[95m\]\t\[\e[0m\] \[\e[33m\]\u\[\e[0m\]@\[\e[96m\]\H\[\e[0m\]:\[\e[36m\]\w\[\e[0m\]$(branch=$(git status 2>/dev/null | head -n 1 | cut -d " " -f 3 2>/dev/null);if [[ -n ${branch} ]]; then echo -ne "@\[\e[1;91m\]${branch}\[\e[0m\]";fi) \[\e[1;37m\]\n>\[\e[0m\] '

# Chromeium headless broswer
export PUPPETEER_SKIP_CHROMIUM_DOWNLOAD=true
export CHROME_PATH=/home/ohyee/chrome
export PUPPETEER_EXECUTABLE_PATH=$CHROME_PATH
export PATH=$PATH:$CHROME_PATH

# WSL
export WINIP=$(cat /etc/resolv.conf | grep 'nameserver' | cut -f 2 -d ' ')
export WSLIP=$(ip addr show eth0 | grep 'inet ' | cut -f 6 -d ' ' | cut -f 1 -d '/')
sed -i "s/socks5 .* 7890/socks5 $WINIP 7890/" /etc/proxychains.conf  	# 需要对应的文件权限
sed -i "s/Socks5Proxy.*$/Socks5Proxy $WINIP:7890/" /etc/tor/torrc		# 需要对应的文件权限

# GWSL
export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}'):0.0 #GWSL
export PULSE_SERVER=tcp:$(cat /etc/resolv.conf | grep nameserver | awk '{print $2; exit;}') #GWSL
export LIBGL_ALWAYS_INDIRECT=1 #GWSL

快捷键

  • Ctrl + A: 移到命令行首
  • Ctrl + E: 移到命令行尾
  • Ctrl + F: 按字符前移(右向)
  • Ctrl + B: 按字符后移(左向)
  • Alt + F: 按单词前移(右向)
  • Alt + B: 按单词后移(左向)
  • Ctrl + XX: 在命令行首和光标之间移动
  • Ctrl + U: 从光标处删除至命令行首
  • Ctrl + K: 从光标处删除至命令行尾
  • Ctrl + W: 从光标处删除至字首
  • Alt + D: 从光标处删除至字尾
  • Ctrl + D: 删除光标处的字符
  • Ctrl + H: 删除光标前的字符
  • Ctrl + Y: 粘贴至光标后
  • Alt + C: 从光标处更改为首字母大写的单词
  • Alt + U: 从光标处更改为全部大写的单词
  • Alt + L: 从光标处更改为全部小写的单词
  • Ctrl + T: 交换光标处和之前的字符
  • Alt + T: 交换光标处和之前的单词
  • Alt + Backspace: 与 Ctrl + w 相同类似,分隔符有些差别
  • Ctrl + R: 逆向搜索命令历史
  • Ctrl + G: 从历史搜索模式退出
  • Ctrl + P: 历史中的上一条命令
  • Ctrl + N: 历史中的下一条命令
  • Alt + .: 使用上一条命令的最后一个参数
  • Ctrl + L: 清屏
  • Ctrl + O: 执行当前命令,并选择上一条命令
  • Ctrl + S: 阻止屏幕输出
  • Ctrl + Q: 允许屏幕输出
  • Ctrl + C: 终止命令
  • Ctrl + Z: 挂起命令
  • !!: 执行上一条命令

zsh

安装插件

yay -Syu zsh-syntax-highlighting zsh-autosuggestions zsh-autocomplete-git

zsh 相关配置项

PROMPT='%F{10}%n@%m%f:%F{12}%~%f> '

ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE="fg=blue"

source /usr/share/zsh/plugins/zsh-syntax-highlighting/zsh-syntax-highlighting.zsh
source /usr/share/zsh/plugins/zsh-autosuggestions/zsh-autosuggestions.zsh

bindkey '^I'   complete-word       # tab          | complete
bindkey '^[[Z' autosuggest-accept  # shift + tab  | autosuggest

ZSH_AUTOSUGGEST_CLEAR_WIDGETS+=(buffer-empty bracketed-paste accept-line push-line-or-edit)
ZSH_AUTOSUGGEST_STRATEGY=(history completion)
ZSH_AUTOSUGGEST_USE_ASYNC=true

用户组

usermod -a -G groupA user
usermod -a -G docker ohyee
usermod -a -G root ohyee

开发环境

依赖于用户目录下的 env 环境自动识别实现

export ENV_FOLDER=$HOME/env:$HOME/env/bin
for folder in $(ls -alR $ENV_FOLDER  | grep "^l" | tr -s " " | cut -d " " -f 9); do
    export PATH=$PATH:$ENV_FOLDER/$folder/bin
done

使用 ln -s 将不同版本的依赖注册到环境变量里

Java

同时,还需要设置相关的环境变量

export JAVA_HOME=${HOME}/env/openjdk
export PATH=${PATH}:${JAVA_HOME}/jre/bin

需要注意的是,全局的 Maven setting.xml 位于 $HOME/env/maven/conf/setting.xml

NodeJS

Go

Python

python3 -m pip install xxx -i https://pypi.tuna.tsinghua.edu.cn/simple some-package

基础命令

yay

  • 安装、更新

    yay -S vim 				# 安装软件
    yay -Sy vim 			# 更新列表并安装软件
    yay -Syu vim 			# 更新可更新的包,并安装软件
    yay -Syyu vim 			# 更新系统,并安装软件
    yay -Su 				# 更新所有包
    yay -Sw vim 			# 下载安装包不安装
    yay -U xxx.pkg.tar.gz 	# 安装本地包
    
  • 卸载

    yay -R vim 		# 卸载软件
    yay -Rs vim 	# 卸载软件,并卸载其可卸载依赖
    yay -Rsc vim 	# 卸载软件,卸载其依赖,并卸载依赖其的软件
    yay -Ru vim 	# 卸载软件,同时卸载所有不被依赖的依赖
    
  • 搜索

    yay -Ss vim 		# 搜索软件
    yay -Sl archlinuxcn # 从指定仓库搜索
    yay -Qs vim 		# 搜索已安装的软件
    yay -Qu 			# 搜索可更新的软件
    yay -Qt 			# 搜索任何不被依赖的软件
    yay -Qi 			# 搜索并查看信息
    yay -Ql 			# 搜索并查看其安装的文件路径
    yay -Sg 			# 查找软件包
    yay -Qg 			# 查看已安装的软件包
    
  • 清理

    yay -Sc # 清理未安装的包缓存
    yay -Scc # 清理所有缓存
    

cut

cut 可以对字符串进行分割,并取出特定列的内容

echo "1|2|3|45|6" | cut -d "|" -f 2

如上面的命令,则可以取出用 | 分割的第二部分内容(2

echo "1|2|3|45|6" | cut -d "|" -f 2-4

-f 2-4 则可以取出 2~4 部分内容(2|3|45

tr

tr 可以删除或替换字符

  • 大小写转换
    使用下面的命令,可以将小写转换为大写,输出 ABCD

    echo "abcd" | tr a-z A-Z
    
  • 合并相邻字符
    可以将字符串中多余的空格合并为一个,输出 Hello World !,通常用于和 cut 配合

    echo "Hello  World    !" | tr -s " "
    
  • 删除字符
    将满足条件的字符删除,输出 Hi!

    echo "Hi   !" | tr -d " "
    

sed

sed 是用来处理文本文件的命令

  • -e: 要执行的操作
  • -n: 只显示修改的部分
  • -i: 执行操作,并将改动写入文件

操作指令

  • a: 在对应行数后新增一行
  • c: 修改对应的行
  • d: 删除对应的行
  • i: 在对应行数前新增一行
  • p: 打印对应的行
  • s: 正则表达式替换

命令格式 {要修改的位置}{命令}{改动后的结果}
要修改的位置可以是行数,也可以是使用 / 包裹的正则表达式。如果要修改 2~5 行,则可以使用 2,5

  • 在第一行后新增

    $ echo -e "12345\n246810" | sed -e "1aabcdefg"
      
    12345
    abcdefg
    246810
    
  • 删除第 2 行

    $ echo -e "12345\n246810" | sed -e "2d"
      
    12345
    
  • 正则表达式替换

    $ echo -e "12345\n246810" | sed -e "s/1/a/"
      
    a2345
    2468a0
    

grep

grep -5 'xxx'   // 匹配同时输出上下 5 行 
grep -C 5 'xxx' // 匹配同时输出上下 5 行 
grep -A 5 'xxx' // 匹配同时输出后 5 行 
grep -B 5 'xxx' // 匹配同时输出前 5 行 

$ a=`for i in {1..10}; do echo "$i"; done`; echo $a | grep -C 2 "5"
3
4
5
6
7

其他命令

FFMpeg

所有的参数都会作用于参数后的第一个文件

参数解释

基本参数 解释 音频参数 解释 视频参数 解释
-i 设定输入流 -aframes 音频帧数 -vframes 视频帧数
-f 设定输出格式 -b:a 音频码率 -b:v 视频码率
-ss 开始时间 -ar 采样率 -r 帧速率
-t 持续长度 -acodec 声音解码器 -vcodec 视频解码器
-an 不处理音频 -vn 不处理视频
-af 音频过滤器 -vf 视频过滤器
-ac 声音频道数 -s 画面大小
-aspect 横纵比

常用命令

  • flv转换为mp4: ffmpeg -i input.flv output.flv

  • 裁剪视频:

    • 粗略裁剪(如果没有关键帧则无法精确裁剪): ffmpeg -ss 00:00:00 -t 00:00:30 -i input.mp4 -vcodec copy -acodec copy output.mp4
    • 直接裁剪(无视关键帧,可能会导致黑屏): ffmpeg -i input.mp4 -ss 00:00:00 -t 00:00:30 -vcodec copy -acodec copy output.mp4
  • 帧内编码: ffmpeg -i input.mp4 -strict -2 -qscale 0 -intra output.mp4

  • 视频拼接: ffmpeg -f concat -i list.txt -c copy output.mp4

    • 其中,list.txt的内容应该是如下格式

      file ./split.mp4
      file ./split1.mp4
      
  • 截图:

    • 输入截图(很快): ffmpeg -ss 00:1:05 -i input.mp4 -frames:v 1 output.jpg
    • 输出截图(需要重新编码,较慢): ffmpeg -i input.mp4 -ss 00:1:05 -frames:v 1 output.jpg
  • 视频静音: ffmpeg -i input.mp4 -an output.mp4

  • 只要音频:

    • ffmpeg -i input.mp4 -an output.mp3
    • ffmpeg -i input.mp4 output.mp3
  • 视频转换为图片: ffmpeg -i input.mp4 -t 5 -s 640x360 -r 15 frame%03d.jpg

  • 音频调整音量: ffmpeg -i input.mp3 -filter "volume=20dB" output.mp3

screen 命令

参数

screen -ls          # 列举所有 screen 会话
screen -d           # 后台运行会话
screen -r           # 恢复会话
screen -S <name>    # 预设会话名称
screen -wipe        # 清除宕机的会话 
screen -s <shell>   # 设定 shell

screen 会话内部

<C-a> d             # 后台运行会话

# 窗口相关
<C-a> w             # 显示窗口列表
<C-a> c             # 启动一个新的 shell 并切换到该窗口
<C-a> <0~9>         # 快速切换到指定窗口
<C-a> '             # 交互式切换至指定窗口
<C-a> <C-a>         # 上一个使用的窗口
<C-a> p             # 前一个窗口
<C-a> n             # 后一个窗口
<C-a> Space         # 顺序切换窗口

# 分屏相关
<C-a> |             # 左右分屏
<C-a> S             # 上下分屏
<C-a> X             # 关闭当前分屏
<C-a> Tab           # 分屏间切换

如果希望使用鼠标切换分屏,可以在~/.screenrc中修改

mousetrack ondefmousetrack on

添加如下配置,则可以允许鼠标滚轮滚动

termcapinfo xterm* ti@:te@

tmux

tmux 本身包含会话(session)、窗口(window)、窗格(panel)三层概念,其中会话和窗口实际上并没有特别明显的界限(可以使用快捷键直接在不同会话内切换),因此通常根据任务进行逻辑上划分

所有的快捷键都需要使用 ctrl + b 作为前缀(后续省略)
同时,也可以直接在 tmux 内部的终端内执行相应的命令来实现快捷键同样的效果

会话操作

# 新建会话
tmux new [-s {会话名}] [-n {窗口名}]

# 列出会话
tmux ls

# 进入会话
tmux attach [-t {会话名}]
tmux at [-t {会话名}]
tmux a [-t {会话名}]

# 退出会话
tmux detach
tmux det

# 结束会话
tmux kill-session

# 关闭其他会话
tmux kill-session -t {会话名} 

# 切换会话
tmux switch -t {会话名}

# 重命名会话
tmux rename-session -t 0 {会话名}
  • s: 列出所有会话
  • $: 重命名当前会话
  • :new: 启动新会话
  • d: 退出会话
  • (: 上一个会话
  • ): 下一个会话

窗口相关

# 创建窗口
tmux new-window

# 切换窗口
tmux select-window -t {窗口编号}

# 重命名窗口
tmux
 rename-window {窗口名}
  • c: 创建新窗口
  • w: 列出所有窗口
  • n: 后一个窗口
  • p: 前一个窗口
  • f: 查找窗口
  • ,: 重命名窗口
  • &: 关闭窗口
  • number: 切换到对应序号的窗口

窗格相关

# 上下拆分窗格
tmux split-window 

# 左右拆分窗格
tmux split-window -h

# 移动光标
tmux select-pane [-U] [-D] [-L] [-R]

# 交换窗格位置
tmux swap-pane [-U] [-D] [-L] [-R]
  • %: 左右分割
  • ": 上下分割
  • arrow key: 切换窗格
  • ;: 下个窗格
  • o: 上个窗格
  • x: 关闭窗格
  • !: 将窗格拆分为窗口
  • z: 全屏窗格
  • ctrl + arrow key: 调整窗格大小
  • q: 显示窗格编号

其他

# 查看快捷键
tmux list-keys

# 查看命令
tmux list-commands

# 查看会话信息
tmux info

# 重新加载 tmux 配置
tmux source-file ~/.tmux.conf
  • t: 显示时钟
  • ?: 列出快捷键

docker

  • 删除所有启动中的容器

    docker ps | cut -d " " -f 1 | grep -v CONTAINER | xargs docker stop
    
  • 获取特定 Container IP

     docker inspect --format='{{.NetworkSettings.IPAddress}}' $ContainerID
    
  • 删除 none 镜像

    docker images | grep none | tr -s " " | cut -f 3 -d " " | xargs docker rmi
    

axel

轻量级命令行多线程下载

axel xxx.tar -n 16 

清理 vhdx(Docker、WSL)

Optimize-VHD -Path $Env:LOCALAPPDATA\Docker\wsl\data\ext4.vhdx -Mode Full
Optimize-VHD -Path $Env:LOCALAPPDATA\Packages\yuk7.archwsl_35zwpb4sx6e50\LocalState\ext4.vhdx -Mode Full