SHELL工具和脚本

笔记

Copy
$_ # 上一个参数
!! # 上一条命令
$? # 运行命令的结束代码
$# # 参数个数
$@ # 所有参数
$$ # SHELL本身的PID
$0 # 本身的文件名

创建文件夹并进入文件夹

Copy
# mcd.sh
mcd(){
mkdir -p "$1"
cd "$1"
}

source mcd.sh
mcd test

Copy
# example.sh

#!/bin/bash

echo "Start program at $(date)" # Date will be substituted

echo "Running program $0 with $# arguments with pid $$"

for file in "$@";do
grep foobar "$file" > /dev/null 2> /dev/null
# When pattern is not found,grep has exit status
# We redirect STDOUT and STDERR to a null register ..
if [[ "$?" -ne 0 ]]; then
echo "File $file does not have any foobar, adding one"
echo "# foobar" >> "$file"
fi
done

查看命令如何使用：

tldr 更直白明了

Copy
sudo apt-get install tldr
mkdir -p ~/.local/share/tldr
tldr -u

查找文件

fd

Copy
sudo apt-get install fd-find
sudo ln -s $(which fdfind) /usr/bin/fd

查找代码

riggrep(rg)

Copy
sudo apt-get install riggrep

# 查找所有使用了 requests 库的文件
rg -t py 'import requests'
# 查找所有没有写 shebang 的文件（包含隐藏文件）
rg -u --files-without-match "^#!"
# 查找所有的foo字符串，并打印其之后的5行
rg foo -A 5
# 打印匹配的统计信息（匹配的行和文件的数量）
rg --stats PATTERN

通用模糊查找工具

fzf

Copy
sudo apt-get install fzf

ps aux | fzf
fzf --query "sh"

文件夹导航

fasd

autojump

tree

broot

nnn

ranger

练习

保存当前位置

Copy
#!/bin/bash
marco(){
echo $(pwd) > ~/dev/class/missing-semester/marco_history.log
echo "save pwd $(pwd)"
}
polo(){
cd "$(cat ~/dev/class/missing-semester/marco_history.log)"
}

#!/bin/bash
marco() {
export MARCO=$(pwd)
}
polo() {
cd "$MARCO"
}

调试错误并捕获输出

Copy
# buggy.sh

#!/usr/bin/env bash

n=$(( RANDOM % 100 ))

if [[ n -eq 42 ]]; then
echo "Something went wrong"
>&2 echo "The error was using magic numbers"
exit 1
fi

echo "Everything went according to plan"

# debug_while.sh
#!/usr/bin/env bash
count=1

while true
do
./buggy.sh &>> out.log
if [[ $? -ne 0 ]]; then
# cat out.log
echo "failed after $count times"
break
fi
((count++))
done

# debug_for.sh
#!/usr/bin/env bash
for ((count=1;;count++))
do
./buggy.sh &>> out.log
if [[ $? -ne 0 ]]; then
# cat out.log
echo "failed after $count times"
break
fi
done

# debug_until.sh
#!/usr/bin/env bash
count=0
until [[ "$?" -ne 0 ]];
do
count=$((count+1))
./buggy.sh &>> out.log
done
# cat out.log
echo "found error after $count runs"

递归地查找文件夹中所有的 HTML 文件，并将它们压缩成 zip 文件

Copy
mkdir -p html_root/html
touch html_root/{1..10}.html
touch html_root/html/xxxx.html
fd --extension html | xargs -d '\n' tar -cvzf html.zip

编写一个命令或脚本递归的查找文件夹中最近使用的文件

Copy
find -type f -print0 | xargs -0 ls -lt | head -1
# find -print0 在查询的每一个结果后加一个NULL字符，替换默认的换行符
# xargs -0 xargs命令用NULL做分隔符