环境

能比 bash 还要晦涩, zsh 可谓让人起敬.

脚本

I’ve never seen any language more obsecure than bash… probably except English. – Hoblovski

寻找当前目录下所有的 ASCII 文本文件

$ find . -type f -exec file '{}' \; | ag "ASCII text" | awk -F: '{print $1}'

或者使用 cut, 一般情况下 cutawk

$ find . -type f -exec file '{}' \; | ag "ASCII text" | cut -d: -f1

递归替换某个字符串

一般替换字符串都只发生在文本文件上, 因此使用 ripgrep rg 而非 grep. 它比 aggrep 都快.

$ rg stdio -l | xargs sed -i 's/stdio/llstdio/g'

或者也可以

$ find . -type f -exec sed -i 's/stdio/llstdio/g' {} +

显示所有发生超过 100000 次的中断

发生次数是所有核上之和, 使用 /proc/interrupts 内核文件来访问中断发生次数.

$ awk '$2+$3+$4+$5 > 10000 || NR == 1 {print $0;}' /proc/interrupts

打印两个目录中有那些文件不同

这里要求文件在两个目录中都存在, 但是不同. 也就是 A/path/path/fileB/path/path/file 都存在, 但是不同.

$ diff -rq linux-4.17.3 linux-4.17.3-mychanges | awk '$NF=="differ" {print $2, $4;}' | column -t

同样可以使用 cut

$ diff zfs_v3.12/ zfs_v3.13/ -rq | cut -d\  -f2,4 | column -t

当然一般使用 meld 就好.

统计 Linux 内核中使用了多少 down_interruptible

也是使用 awk. 不过需要注意, 本文并不是 awk 专场.

ag -cw down_interruptible | awk -F: 'BEGIN{s=0} {s+=$2} END{print s}'

顺带一提, 4.16 内核中使用了 147 次 down_interruptible.

从多个备选版本中选取程序

这个我只能用 if 做, 不知道有没有方法用 && 做.

$ if clang-3.9 --version; then CL=clang-3.9; elif clang-3.8 --version; then CL=clang-3.8; else CL=""; fi
$ echo $CL

Advanced Bash Scripting 给出了更好的方法, 就是使用 type 命令.

后来我看 riscv toolchains 中给出了更好的方法

# Use gmake instead of make if it exists.
MAKE=`command -v gmake || command -v make`

从 txt 生成 pdf

如果只有英文倒是可以使用 vim, 但是有中文的话不知道为什么就会有乱码. 可能是因为我用的系统是英文的缘故吧. 不过可以使用 libreoffice

$ libreoffice --convert-to "pdf" xxx.txt

寻找某个 C 项目中用了那些宏来完成条件编译

$ ag --nofilename '#ifn?def' | sed 's@^\s*#\s*ifdef\s\+\(\w*\).*@\1@' | sort | uniq

不含历史的 git clone 加速

$ git clone https://github.com/torvalds/linux.git --depth=1 && rm linux/.git -rf

查询每个 host 访问 nginx 的次数并排序

居然有脚本小子想访问我的 vps…

$ awk '{print $1}' /var/log/nginx/access.log.1 | sort | uniq -c | sort

去掉文件前缀

$ for X in *; do mv $X ${X##learning-}; done

vim 强制设置高亮类型

:set syntax=c

cd 之后自动 ls

这个设置舒服啊, 最好加到 zshrc / bashrc 里面去

cd() {
	builtin cd "$@" && ls -F
}

命令行下 wifi 操作

Ubuntu 操作网络用的是 NetworkManager, 命令行下使用其 nmcli

$ nmcli dev wifi	# 扫描可用 AP
$ nmcli dev wifi con SSID  # 连接到 wifi
$ nmcli con up SSID	# 连接一个曾经连过的 wifi, 不用输密码

将文件名中的换行符替换成空格

使用 rename 命令. stackoverflow 上面的答案不准确.

$ rename 's/\n/ /g' *

还可以用 rename 来做文件名小写, 如

$ rename 'y/A-Z/a-z/' *

寻找当前目录下最近一分钟内改变的文件

通常对工具做黑箱分析的时候会有这样的需求.

$ find . -cmin -1

检查 gcc 的预定义宏

从 riscv glibc 的角落中发现的, 他居然用这个东西然后 grep XLEN 来检查目标的 XLEN.

$ gcc -E -xc -dM /dev/null

检查 gcc 的默认 include 路径

$ echo | gcc -E -Wp, -v -

惊喜

$ echo c3VycHJpc2UgbW90aGVyZnVja2VyCg== | base64 -d | spd-say -e >/dev/null

vim 在 normal mode 下复制某一行内容到光标行之下

:76t.

gcc 的选项默认值

$ gcc -Q --help=target
$ riscv64-unknown-linux-gnu-gcc -Q --help=target

比如用来找出默认的 arch.

检查 ELF 的 .comment

readelf -p .comment hello_world

简化 locate 输出

locate 输出经常很大一串, 这种时候我希望找到相关的路径就好

$ locate mqueue | cut -b -40 | sort | uniq

ld 默认的库搜索路径

$ ld --verbose | ag SEARCH

检视端口使用情况

$ netstat -tlunp

抽取第 A 字节开始 N 个

$ dd ibs=1 skip=0 count=512 if=ubuntu.iso of=mbr

反汇编 raw 二进制文件

$ objdump -D -b binary -mi386 -Maddr16,data16 mbr

将 pdf 转换成 png

通常用来发到中国使用的群聊中.

$ xelatex git.tex && pdftoppm git.pdf outputname -png && convert -append outputname-*.png out.png

上一条命令的第n个参数

$ echo 1 2 3
$ echo !!:0 !!:1 !!:2

显示 apt 安装软件的详情

$ apt-cache show vim

搜索 man

一个词可能在不同的 man section 中出现

$ man -k ulimit

搜索 errno

perror 也是命令行工具

$ perror 19

限制进程使用的内存

简单的就是 ulimit, 其不同选项可以用 ulimit -a 显示.

$ ulimit -v 1536 chrome

让 make 打印失败的命令

$ make SHELL="/bin/bash -x"

寻找提供某个文件的包

$ dpkg -S c++config.h

让 sed 做 line filter

$ rg -l -- -posix-runtime | sed '/^test/d'		# negative filter
$ rg -l -- -posix-runtime | sed -n '/^test/p' # positive filter

检查系统安装了那些字体

$ fc-list

vim 替换模式为换行

:%s/^M/\r/g

某进程打开的文件: lsof 的快速使用方法

lsof -nP -p PID
~~

## 检视 screen-256color 的颜色

for i in {0..255}; do printf “\x1b[38;5;${i}mcolor%-5i\x1b[0m” $i ; if ! (( ($i + 1 ) % 8 )); then echo ; fi ; done


## 获得随机浮点数

echo “scale=10; ${RANDOM} / 65536” | bc ~~

并行运行

之前并行运行都是手动 ./task &,但直接使用 GNU parallel 就很舒服了。 尤其是 parallel 会保证并行运行的每个 job 的 stdout 输出不会混杂在一起。

cat >t.sh <<'EOF'
f() { sleep $1 ; echo $1 ; sleep 4 ; echo $1 ; }
export -f f
parallel --halt now,fail=1 f ::: `seq 4`
EOF
bash t.sh

cat 的 heredoc 不要 shell expand

如上,cat <<'EOF' 注意单引号。