欢迎来到猫猫的Shell实验室喵!
跟着沨鸾学shell,学到最后只会喵喵喵。
文章非入门教程,不要妄想本猫亲自教你基础知识,哼!
本文不定期更新。
正经部分:
语法规范:
变量要加{}括起来。
函数最好加个function关键字。
头部一定要有释伴(shebang)。
记得写注释,要不然也就上帝能看懂你写的什么了。
退出时要有返回状态。
能用[[]]就别用[]。
尽量用printf代替echo使用以提供更好的兼容性。
没用的输出记得丢弃。
> /dev/null丢不掉就2>&1 > /dev/null。
不要定义太复杂的架构,比如函数互相调用。
当然猫猫基本没怎么遵守过。
最高端的输出颜色自定义:
使用rgb代码定义输出颜色。
\033[1;38;2;R;G;Bm
比如moe-container里的这行:
printf("\033[1;38;2;254;228;208mUsage:\n");
当然这是C语言。
等下这是shell技巧……对吧。
输出居中:
首先你得知道要居中的输出有多长。
然后:
WIDTH=$(($(($(stty size|awk '{print $2}')))/2-居中字符长度的一半))
echo -e "\033[${WIDTH}C内容"
除了花哨点也没啥大用。
输出一行分割线:
WIDTH=$(stty size|awk '{print $2}')
echo $(yes "="|sed $WIDTH'q'|tr -d '\n')
当然可以玩的更花哨一点:
WIDTH=$(stty size|awk '{print $2}')
WIDTH=$((WIDTH/2-2))
echo "$(yes "="|sed $WIDTH'q'|tr -d '\n')xxxx$(yes "="|sed $WIDTH'q'|tr -d '\n')"
$WIDTH定义参照上一条。
或者像termux-container里这样:
WIDTH=$(stty size|awk '{print $2}')
WIDTH=$((WIDTH-13))
echo -e "\e[30;48;5;159mCONTAINER_RUN$(yes " "|sed $WIDTH'q'|tr -d '\n')\033[0m"
莫名科技感。
sed正则匹配:
echo 123abc > test
sed -i "s/[0-9]*/数字替换/" test
cat test
正则表达式具体内容请自行利用搜索引擎。
想当年猫猫要是会用,termux-container里的屎山也能少点。
更改光标样式:
printf '\e[2 q'
printf '\e[6 q'
printf '\e[4 q'
仅在termux验证成功过。
Ctrl+D信号捕获:
不是说好EOF不是信号的吗?
事实上read可以捕获。
read无论读到什么东西加回车都会将结果记录并正常退出。
但是,读到EOF却未换行会返回1。
可以read后用$?的值是否为0来作为条件进行捕获。
似乎挺没用的。
(termux-container将会利用这一特性)
网易云歌曲名称格式化:
网易云默认下载的音乐命名格式是这样的:
Akie秋绘 - なんでもないや 没什么大不了的(翻自 Radwimps).mp3
ENE - パズル.mp3
Hanser - 勾指起誓.mp3
のぶなが - 深海少女.mp3
南杉 - 樱花樱花想见你.mp3
鹿乃 - 小夜子.mp3
鹿乃 - 心拍数#0822.mp3
鹿乃 - 桜のような恋でした.mp3
(浓度过纯)
咱们可以这样:
ls *.mp3|while read music
do
artist=${music%% -*}
name=${music##*-\ }
name=${name%%.mp3}
name=${name%%"("*}
name=${name%%"("*}
mv "$music" "$name-[$artist].mp3"
done
于是文件名就成了这样:
なんでもないや 没什么大不了的-[Akie秋绘].mp3
パズル-[ENE].mp3
勾指起誓-[Hanser].mp3
深海少女-[のぶなが].mp3
樱花樱花想见你-[南杉].mp3
小夜子-[鹿乃].mp3
心拍数#0822-[鹿乃].mp3
桜のような恋でした-[鹿乃].mp3
个人感觉好看多了。
用Shell写代码:
(怕是人家shell自己写的代码都比你规范)
moe-container里有这样一段头文件:
#define DROP_CAP_SYS_ADMIN 1
#define DROP_CAP_SYS_MODULE 1
#define DROP_CAP_SYS_RAWIO 1
#define DROP_CAP_SYS_PACCT 1
#define DROP_CAP_SYS_NICE 1
#define DROP_CAP_SYS_RESOURCE 1
#define DROP_CAP_SYS_TTY_CONFIG 1
………………
可以看到#define DROP_和后面的1都是重复的
于是我们可以单独写一个caplist文件来记录那些不同的部分:
CAP_SYS_ADMIN
CAP_SYS_MODULE
CAP_SYS_RAWIO
CAP_SYS_PACCT
CAP_SYS_NICE
CAP_SYS_RESOURCE
CAP_SYS_TTY_CONFIG
然后:
cat caplist|while read cap
do
echo "#define DROP_${cap} 1"
done
事实上这一段:
if(DROP_CAP_SYS_ADMIN == 1){
cap_drop_bound(CAP_SYS_ADMIN);
}
if(DROP_CAP_SYS_MODULE == 1){
cap_drop_bound(CAP_SYS_MODULE);
}
if(DROP_CAP_SYS_RAWIO == 1){
cap_drop_bound(CAP_SYS_RAWIO);
}
………………
是这么生成的:
cat caplist|while read cap
do
echo " if(DROP_$cap==1){\n cap_drop_bound($cap);\n }"
done
非常规范,非常工整。
C语言实现了shell,shell可以生成简单重复的C语言代码,双向奔赴,非常美好。
生草部分:
变量当函数/命令名执行:
test(){
$1
}
test ls
不做类型检查你就可以为所欲为了是吧。
忽略Ctrl+C:
用户别想用Ctrl+C杀死你的进程(大草)。
trap "" SIGINT
本文著作权归Moe-hacker所有
copyright (©) 2022 Moe-hacker
标签:Shell,技巧,CAP,SYS,WIDTH,mp3,DROP,cap From: https://www.cnblogs.com/Moe-hacker/p/16953865.html