duangsuse::Echo
712 subscribers
4.24K photos
127 videos
583 files
6.45K links
import this:
美而不丑、明而不暗、短而不凡、长而不乱,扁平不宽,读而后码,行之天下,勿托地上天国。
异常勿吞,难过勿过,叹一真理。效率是很重要,盲目最是低效。
简明是可靠的先验,不是可靠的祭品。
知其变,守其恒,为天下式;穷其变,知不穷,得地上势。知变守恒却穷变知新,我认真理,我不认真。

技术相干订阅~
另外有 throws 闲杂频道 @dsuset
转载频道 @dsusep
极小可能会有批评zf的消息 如有不适可退出
suse小站(面向运气编程): https://WOJS.org/#/
Download Telegram
duangsuse::Echo
#js #code #low 🌚 本来想到FT可视化算法里一个流程技巧,想去看看这个是不是已有了,发现人家用的是FFT — 为什么和正常人写的不一样? 非常无语的抑制住了血压升高,因为我的文还在「设计」中 真的是逗死我了,Xe 大佬的代码居然是最优雅的,因为居然有人蠢(请允许我这次用这个词)到动画状态机(st++的那种?)都 case? JSer 都没学过编程吗?! 我tm a[i/N >>0] (floor)已经很过分了,这还 >>>1 ?还x:y:x:yx... this, context(graphic)…
请各位订户千万不要被原文的趣味性带偏! 无论你在写什么领域的代码,这是绝对不可取的!
他的文章很好,但代码很烂! 我会逐图解释为何「烂」 🌚 虽然正常人都看得出

从迷糊程度开始。
2.这其实是一个展开命名(SSA单赋值...)了的Vec3计算。hpmd 是+s 的乘积(range map计算..),后面许多是 n[v],n[v+1] 和2D旋转公式 ax-by,ay+bx ,只是没有任何数据封装 只有变量名(汇编时代都有约定俗成struct的),千万不要手动内联表达式!不要以这种人为榜样!

我相信一定是作者手写的,因为没有魔怔编译器会如此优化文本代码 🤪🙏

3.到这时想起来[{key,value}] 和[{x,y}]的滥用datatype了,那刚才写那么多var是 🙅‍♂️
从性能上也没比[x,y]优雅到哪去,都是 number pair ,何苦内联手写js里🤦🏻 稍微有点常识也懂JSON.parse
有你从 MouseEvent.xy 拿这些的功夫。早找到 SVG Path 了

代码空间管理大师:
4.起名大师,和那个 Pizzicato 一样,重复前缀丝毫不会意识到 DOMTree 为何是嵌套的
5.重复.前缀大师, doc.docElement 无数遍,我的天哪 Kotlin 的 o.let{it.aa+it.bb} 真的是太现实了
6.DOM注册转发大师,空话复制一大堆,您还是看看JQuery吧,虽然格局较小但简写也是有用的🙅‍♂️
用这个"可拓展",没人帮你写插件!(Kotlin 的 class by(o: interface) 真好😂

7.数据类型函数名化,from/into 这个应该是全工业界没抽提。 我现在对数据已经完全无实感了,一会整 res.amplitude 一会全变量名,他到底是不是程序员,知不知道变量和 data 上的变量对复用是不同

1.您把 drawCircles 的 opacity 参数抽提啥都用 anim(1,0,v=> 补间绘制末帧来淡出不就可以了,是对动画队列没概念吗?起一大堆状态号
您把「画圈、手移开、FT出这个手、圈淡出」,这些变成带参回调function 不就可以了,您知道状态机的意义是转移表吗?🤦🏻 讲数学,函数的[]都不会用

最重要的是,状态机都写了,animCount 帧号还是手动判断区间的?! setInterval重绘里这是二选一好不好……(<)号就能判断状态和时轴%了,您还是讲数学呢!还3D螺旋呢!

我是从没写过臆症到 && 内含多个,赋值的 (注意break前的“语句”哪里来尾括号? animCount>48&&(state=) ...) 🤪
思想稍微善良的程序员也该明白 && || 取代if 要适可而止吧,能把JS写成 #bash

世界上只有两种程序员:一种习得技巧发现用不到后微笑着接受 ,一种学到后立刻与this这些画风不搭的组成缝合怪🤮,还自以为更快更黑科技

用手想都知道 ok=(i==n)
switch(st){case 0:draw(i); if(ok)st=1,n=50 } i++ ;if(ok)i=0
比重复5遍「高性能」

“聪明”到知道 !0&&(a=1,b=2)1==t&&2==t 是有效的,笨到不知道有 if()break; 可以外包for(;;st++) 和switch就是过时写法的事情。当代码必须重复,就要把函数当参数,存[]了,这不是编程基础吗?
不会写您可以不写,可以用社区轮子,写这么一大堆是何苦呢; 怕是得花个星期写一篇博文吧,竟然需要几万行代码,我死了
恶心的是JQ内部也没优雅到哪去,但它居然还算好的……

我们应该为对自己代码的自信没有魔怔到此种程度而骄傲🤦🏻 价值观稍微正常的人看到20行的算式都知道是错的离谱
不仅不应为自己能“理解”并编写此类代码而自豪,反而要将写过这种谭式mian条代码当自嘲的笑话,警示自己编程是解决而非制造问题的

优秀的代码绝对不该能区别开 >>>1 和 /2 这些的,请大家以此为镜,尽管是在写有用的代码,也千万不要用奇奇怪怪的语法,尤其是同前缀"" 或同前缀.号链,如果出现太多,就要注意设计是否变成堆砌了
#DontKnow #linux #tool
有没有那种能存档linux 进程的调试工具啊,就像GBA里的存档键
涉及 vmem,fd, linker 等问题.linux ptrace没有
Linux 太硬了,都不给这种简单的进程级hibernate工具?

预装了,叫CRIU。感觉Linux和win32 里也有好的成分,比如 ld hook , overlayfs, qemu-user, D-Bus, rundll32和C#COM , WSL, CRIU, https://github.com/rami3l/pacaptr 包管理

垃圾 docker pause 居然不给进程 snapshot 的机会,是把cgroup CPU轮转给停掉

我想用进程快照玩游戏,这样就能复活,也不容易存死档
但是貌似只有VMware UI 最方便

(import multiprocess 挺好玩,最近封装AI库就用到了进程池。二进制数据封送直接传参就能过去
进程池的全局变量是复用的, 不会浪费时间
(补: Docker 2014 就支持了进程冷恢复,但fork需要 -dir 参数导出,新容器加载
#code #bash
echo "{\"experimental\": true}" >> /etc/docker/daemon.json
sudo dockerd
docker run -d --name looper busybox /bin/sh -c 'i=0; while true; do echo $i; i=$(expr $i + 1); sleep 1; done'
docker checkpoint create looper c1

docker start -i --checkpoint c1 looper
#linux #bing USB共享网络的SOCKS代理?
#bash #tool
cat>/etc/udev/rules.d/99-usb.rules <<OK
ACTION=="add", SUBSYSTEM=="usb", RUN+="/bin/su duangsuse bash -c 'export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus; (sleep 2;eval `base64 -d <<<ZGNvbmYgd3JpdGUgL3N5c3RlbS9wcm94eS9zb2Nrcy9ob3N0ICInYGlwIHJ8aGVhZCAtbjF8cGNyZWdyZXAgLW8xICdkZWZhdWx0IHZpYSAoXFMqKSdgJyI=`')&"
OK


开始打算用
printf 'ACTION=="add", SUBSYSTEM=="usb", RUN+=env K=V %q' cmd , 但果然内联base64 更能解决引号地狱..
duangsuse::Echo
#linux #hack VSCode Alt-S 同行数多光标可以列粘贴,但在 #telegram desktop 里编辑、导入导出长的富文本,就完蛋了 😅 Bot还被限制了2个链接截断 web.telegram.org 是用 $('[tabindex]:read-write').innerHTML 表示消息的,bot markdown 所支持的格式勉强能F12粘贴 不知为何Qt与Chrome,Wx的剪贴板不兼容 xclip -selection c -o -t TARGETS xclip -selection…
#tool tty canvas #ai 编程失败
>用py实现 sudo hexdump /dev/input/mice -ve'3/1 "%d " "\n"'| for X,Y in lines: 叠加x=0,y=0 并移动终端光标
(很烂而且没有避print换行的坑)
gpmm() { #鼠标光标
stdbuf -o0 hexdump /dev/input/mice -e '3/1 "%d ""\n"'|awk -v kx=$((COLUMNS / LINES)) -e '!/*/{x+=$2/k*kx; y+=$3/k; printf "\x1b[%d;%dH", -y,x} BEGIN{x=y=0; kx*=.5;k=9.3}'; }

>用py struct("bbb") 读取 /dev/input/mice, for btn,X,Y in evt: 叠加x=0,y=0 并将其以 "\x1b[y;xH" 显示
(它没用ANSI escape

#code #bash GPM 字符画板 sudo cat /dev/input/mice | python a.py $COLUMNS $LINES
import sys, numpy as np #array('b', )

P = np.array([0,0]); dk = np.array([.6 ,-.4])
L = np.array(sys.argv[1:]).astype(float)

while True:
btn,*dP = np.frombuffer(sys.stdin.buffer.read(3), np.byte)
P=np.clip(0,(P+dP*dk),L); x,y=P.astype(int)
print('\x1b[',flush=True, end=f'{y};{x}H')
duangsuse::Echo
https://t.me/seedless_channel/1655 #statement #PLT #dev #reaction “我有一个每天都要运行的Python程序,每次运行需要1.5秒。我花了六个小时用rust重写了这个程序,现在这个程序运行一次只需要0.06秒了。41年零24天以后,效率提升节约下来的时间补偿了我重写程序的六个小时。:) 这条没错啊,这个作者,根本没搞清楚「大型软件」和demo里,开销都花在哪里 所有软件都巨巨巨巨大无比,这也是和性能无关的 “整个网页/SQL 数据库的架构…
对「日用软件工程」的讽刺文章 内容更新了
真知灼见,字字珠玑啊 #design 😨❤️

> 你会买百公里耗油100升,甚至1000升的汽车吗?在软件行业,我们一直这么做。
> “你需要拼命地奔跑,才能保持呆在原地”。从iOS 11开始,系统将不再支持32位的应用,Chrome的一次更新,就能够让某个JS插件失灵
> 小白用户换上新设备,只是为了运行变得越来越慢的Apps吗?

现代汽车工作效率可以达到当前引擎设计的98%的水准
现代建筑使用刚好的材料来搭建并且在确定条件下保持安全
现代软件行业,大厂普遍接受程序存储和运行在1%甚至0.1%的算法效率上。
当大多数开源还不可靠的时候,机器学习和“人工智能(AI)”又将软件推向了靠猜测的阶段。

> Jonathan Blow 自己开发给自己游戏开发用的编程语言,在笔记本上每秒可以编译50万行代码。而且是全新编译,没有中间缓存,没有增量编译。
> 编写高效的程序不需要你是天才。这并不需要什么魔法。只是不要在现在的臃肿不堪的工具链上去构建就行。

最新的顶级Macbook Pro上,谷歌邮箱,在谷歌自己开发的Chrome浏览器上,需要花费13秒的时间打开邮件
Windows 10大小是4GB,是Windows 95的133倍大。但是Windows 10比Windows 95高级133倍吗?难道整个安卓比这4GB还复杂1.5倍
Windows 10需要花费30分钟来更新系统,什么流程需要这么长的时间呢?30分钟都够我彻底格式化我的SSD硬盘
你有没有想过为什么你的智能手机需要30到60秒的时间来启动。为什么它不能在1秒内启动?这里并没有硬件限制^

10年前一张光盘就能存储操作系统,系统应用和你所有的数据内容。
3年前,16GB手机能良好运行使用,但是到了今天,16GB和膨胀两倍的安卓8.1的手机,已经没有选择游戏和"微"信的余地
然而安卓8.1,并没有带来性能的变化和功能提升,它就这么膨胀了?

一个没有安装任何其他APP的Android8占用6GB的存储空间。请比10年前的软件想一下,程序员们该有多么巨大的进步。
这里面有高清电影吗?我猜大部分应该是代码:系统内核,驱动,翻译字符串,这些资源都不应该很大!
谷歌App,基本上就是谷歌网页搜索,需要350MB空间!谷歌Play服务,我基本不用,需要300MB空间

——
现代editor的输入延迟远输于42年前开发的Emacs。还有比编辑器更简单的功能吗?每敲击一次键盘,你所需要做的仅仅是更新一个小小的方形区域
一个3D游戏可以在这个时间内刷新整个屏幕,渲染成千上万的多边形。同时还处理用户输入,重新计算环境世界

Web应用都会报出大量的“随机”JS错误。
如果网页出现什么问题,只会提示你F5。谁有时间去研究到底什么地方改变了?
整个网页/SQL数据库的架构都建立在当用户浏览渲染出来的网页时,不会去操作任何数据的假设 🔥
原始讽刺:https://motherfuckingwebsite.com/
进阶讽刺:https://thebestmotherfucking.website/
反向讽刺:
https://thebestmotherfuckingwebsite.co/

你桌面的todo应用可能是基于Electron写的,所以它包含了一个Xbox 360控制器的用户态驱动在里面(QQ虚幻引擎警告 😅),这个驱动能渲染3D图像,播放音频,用你的网络摄像头拍照。
你应该将Slack划分为极其耗电型应用。聊天室和简单的文本编辑工具,这些应该都不是资源消耗型的应用才对。欢迎来到2018。
开发Node.js/Javscript项目,rm -rf node_modules 一直是码农工作过程不可或缺的部分。
在虚拟机上构建Docker容器,ONNX,就因为没人可以理清楚程序,编程语言和运行环境的混乱状况。

^注 #bash
systemd-analyze blame|tac|sed '/lightdm/q'

1.986s lightdm.service
2.1GHz 8G 的x86_64 Linux上启动只需2s 🥰 安卓慢不是Linux的锅
另外,pacman 的安装速度比apt;rpm几乎是快一倍的

不同的CPU指令集有体积差异,arm64几乎是32的二倍,这就显得Android的字节性价比奇低了-堪比JavaEE。 不知是不是系统apk的冗余res/文件太多
每次你 ./configure ,gcc都会重新计算一个完全能被缓存的CPU info,即使不换语言用cmake也能避免这点。 C指针语法的繁琐和预处理也会极大拖慢parse的时间
(for A in armv7 aarch64 x86 x86_64; do wget --spider 2>&1 https://mirrors.ustc.edu.cn/alpine/v3.19/releases/$A/alpine-standard-3.19.0-$A.iso; done)|grep 长度

长度:107423744 (102M) [application/octet-stream]
长度:220485632 (210M) [application/octet-stream]
长度:167772160 (160M) [application/octet-stream]
长度:217055232 (207M) [application/octet-stream]
💭
一些人可能觉得W95时没有 .NET 这样的框架,各种UI也很简陋,但这也是扯淡
要知道 7zip.org 可以用1M实现文件管理器的功能
qemu.org,ffmpeg.org,msys2.org 加起来也只250M, 难道内核驱动会包含更多算法吗?
而自带驱动的 pacman -Qi linux 6.7 x64是130M,原文作者 #rust 吹并非空穴来风

功能类似的PS和 gimp.org 居然差0.7G https://helpx.adobe.com/creative-cloud/kb/file-size-creative-cloud-installers.html#:~:text=Photoshop%20CS6
功能和代码量似乎根本没有对应性

难道框架接口不是为服务于apps存在的吗? 随着技术进步,过分冗余的功能组件太多了

我觉得编程界的市场也是挺有趣的,明明速度在下降, 工资却依然涨
这又可以说成资本对劳动和技术的异化 又可以说成资本故意淘汰老设备

但其实编程界好像就是这样…… 无法多快好省地换代,有得有失
我觉得可以搞个绝对化,一切有局部类型标注,或者为val/var数据类型做区分的语法都是噪音(

一个编译期黑盒assert 当成金科律玉,说明根本没有做自顶向下复用 就开始敲键盘,根本是过度工程
文档写成测试,测试写成汇编,类型写成代码……
弱类型还简单些,module导入,interface多态和扩展,data和临时对象 创建个闭包,查个dict就行了
type能和函数字典很好地对应,序列化和集合类型都字面, 完全不需要keywords

这点许多新创建的静态语言都做不到,kt现在的listOf() 也没法好好实现

more: https://news.ycombinator.com/item?id=34936729
https://pointersgonewild.com/2018/02/18/minimalism-in-programming/ #dalao
#py #tool 浏览器缓存 图片 爬虫
python a.py 'x\.com' 200 ~/.cache/chromium/Default/Cache/Cache_Data/*
python imgdump.py 'www' 100 `ls  --sort time --reverse ~/.cache/chromium/Default/Cache/Cache_Data/*`


#code
import re,struct, os

def ls_cache(urlRegex, kbSizeMin, *cache_files):
key_marker = struct.pack('Q', 0xf4fa6f45970d41d8)
def deco(b):
# header is 8+4+4:keylen+4+ bytes[keylen]
key_len = struct.unpack('I', b[12:16])[0]+4
key = b[20:20+key_len].decode()
body = b[20+key_len:b.find(key_marker)]
if len(body)>kbSizeMin*1024 and re.search(urlRegex,key):
return mstrip(100,re.sub('[\x00/]','', key)),body
mapFiles(cache_files,deco)

mstrip=lambda n,s: s if len(s)<n else f"{s[:n//2-2 -2]}..{s[n//2:]}"
def mapFiles(a, fOut):
os.system('rm -rf png;mkdir png')
for i,file in enumerate(a):
with open(file, 'rb') as f:
if f1:=fOut(f.read()):
k,v=f1
with open(f'png/{i}-{k}', 'wb+') as out_f:out_f.write(v)

if __name__ == '__main__':
import fire
fire.Fire(ls_cache)


你可以逐文件夹拼图: #bash 各种相对路径真的吐了
vcat() { cd $1;a=`find *|sort -n|xargs printf "-i %s\n"`
ffmpeg $a -filter_complex vstack=inputs=`wc -l <<<$a` ../$1.png ;cd -;}
for f in `ls`;do vcat $f;done

for f in find * -type d; do thunar -B $f/*; done #按文件夹 批量重命名
cp-id() { i=1; for x in "$@"; do X=$(basename "$x"); cp "$x" "${i}-${X%.*}.${X##*.}"; i=$((i+1)); done; }

最开始考虑了 https://t.me/dsuses/5305 和binwalk但太慢

mkdir a tar
cp `grep 'x.com' -FRl ~/.cache/chromium/Default/Cache/|find -size +200k` tar
binwalk -C a -D image:png tar/*
find a/ -name '*.png'|nl
duangsuse::Echo
#linux #bing USB共享网络的SOCKS代理? #bash #tool cat>/etc/udev/rules.d/99-usb.rules <<OK ACTION=="add", SUBSYSTEM=="usb", RUN+="/bin/su duangsuse bash -c 'export DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus; (sleep 2;eval `base64 -d <<<ZGNvbmYgd3JpdGUg…
#bash #tool USB 5V pwm/pcm 以及stdio.file命令行科普
https://wiki.archlinux.org/title/Fan_speed_control 使用$ sensors; pwmcontrol 控制风扇

lsusb的基于udev,不适用于sysctlfs 所以查看:
usbdev(){ usb-devices |node -p 'fs.readFileSync(0,"utf8").replace(/T:  Bus=(\d*).*Port=(\d*).*MxCh= 0[\s\S]*?Product=(.*?)\n/g, (_,i,j,k)=>`# ${k} /sys/bus/usb/devices/${+i}-${+j+1}\n`)';}

可以用powertop调
发现2.6内核已经不能调,而且电源也是软关闭,如同 usbguard-qt
不过,如果驱动(rndis..)不对可以 usbreset

无论使用 usbguard list-devices; dmesg|grep udev; sysfs都无法diff到USB LED头的差别

唯一的可能是 rtcwake -m mem -s 60; 需要BIOS支持睡眠断电
以及购买集线器 uhubctl -a off -p 1
https://github.com/mvp/uhubctl?tab=readme-ov-file#notable-projects-using-uhubctl
DEB http://launchpadlibrarian.net/448511434/uhubctl_2.1.0-1_amd64.deb

xurls(){ eval $(node -p 'process.argv.slice(1).map(s=>{try{s=`$(wget -c -nv --show-progress ${new URL(s)};ls -rt|head -n1)`}catch{}return s}).join(" ")' $*);}
alias DEB='xurls sudo dpkg -i --force-depends'
alias RPM='xurls sudo rpm -ivh --nodeps' #应支持 rpm://$(dnf download)

diff <(echo hello world) <(echo foo bar)
pushd $(mktemp -d); $0; cd; rm -rf `dirs +1` #进入临时目录
xdg-mime query default application/x-deb #dbus注册表
#learn #bash with #tool 入门+优质冷知识 😋
图为 asciinema.org/explore 。没有 #linux 的极客可打开 WebVM.io
Linux Deploy; (Mac)Git Bash; winetricks; screenfetch 甚至 bashttpd; pacman/OpenRC init 基于bash

shell 是类似 Windows.ps1 但使用纯文本或行IO的脚本编程语言。 每当你看见awk|sed|grep ,那就是在 #sql select访问属性、文本替换、where过滤了
Dijkstra说,用BASIC编程的人“脑子已经坏了”,作为运维你要尽力避免这一点。用AI写命令思路也是要正确! 😨

因此在思考时,你应当用pwsh的API模型: Get-Date|select Year; dir|?{$_.CreationTime.Year -lt 2024} ,而不止是 date '+%Y' ; find . -maxdepth 1 -type f -not -newerct 2023.12.31
更不是 网关=ip r|awk '{print $3}' 这样的糟粕

— 快捷键 (bind -p|grep '"\\C')
⬆️⬇️滚动历史, Alt/Fn⬅️➡️ 跳词/跳行,Tab补齐, ls \ mydir 或fc:多行命令
nl $HISTFILE|tac|less 默认保留500条可清空
^=Ctrl, M=Alt e=ESC
^M T 打开cmd窗口 ^L清屏 ^D退出
!cd 执行最近1次cd开头的命令, sudo !! 补齐为上一条命令
touch a; ls $_
#操作同一个文件
^a^b 改参数重执行

^U ^Y 剪切和粘贴行,nano同款
*.mp4 ^xg #查看符合正择的文件,免ls|grep
^A# ^E# 意为正则/^$/。script录制时(例如 history 3) 添加注释

^M F1~F6 一般含几个tty串口,通过 echo>/dev/tty2 即w;write,您可以装得像电脑有第二个人在用一样 还需要协作 😅
duangsuse::Echo
#learn #bash with #tool 入门+优质冷知识 😋 图为 asciinema.org/explore 。没有 #linux 的极客可打开 WebVM.io Linux Deploy; (Mac)Git Bash; winetricks; screenfetch 甚至 bashttpd; pacman/OpenRC init 基于bash shell 是类似 Windows.ps1 但使用纯文本或行IO的脚本编程语言。 每当你看见awk|sed|grep ,那就是在 #sql sele…
#Linux 与命令行 #bash
"外壳"提供了调用软件的人机接口。在 kernel.org 已对内存cpu分时分址复用、解码/dev/sdXY 分区, /sys/内设外设+网 ls {/proc,/sys/class}/net 的基础上。这是DOS.COM 所不具有的
.bashrc 和 etc/XXX.d/ 以run-command而非json注册表的方式配置设置,这既先进又落后。 rc的灵活性远优于yml,但bash的无类型,单全局表 将其化神奇😅为腐朽了(毕竟1971年老古董)
pacaur -S xonsh elvish pwsh
拥有更合理的弱类型API

您的终端通过 ANSI 清屏=printf '\e[2J\e[14t' 来控制显示效果,但对于TUI应用..有少数stdio管道不能实现的接口, https://docs.python.org/zh-cn/2/library/termios.html .iospeed.O_NONBLOCK
->py termios 如何进入非阻塞(游戏按键)模式?编写 key echo demo
->表格出所有ANSI escape,然后函数化为 clear=lambda: CSI('2J'); ...
bash连接到的tty服务器=$(fuser -s $(readlink /proc/$$/fd/0)) ,如 xfce4-terminal;ssh;tmux

— 进程管理
^C终止 ^Z挂起到jobs
htop; powertop TUI监视器
yes sir|tee just-like.dd
nohup zenity --entry --text="请输入您的姓名:" &
tail -f nohup.out
time sleep 1

#记录3态时间的后2Sum是CPU占用率 ,sys时间较高=IO密集型
jobs -l 查看pid; fg bg 继续任务$!, kill -9 $(pidof bash) 杀死

— 命令的组合 &; >< 与括号展开
{cat,echo}|grep #不要这样做! 使用'<'或arg1输入文件常量,'>>', &>/dev/null 赋值文件。尽量不要使用 >

&>fp 即 1>fp 2>&1; freopen了两个换行流文件(stdbuf -oL),就像 import subprocess.Popen(stdin=-1) 它可被读写
less -f /dev/stdin &sleep 1 &&echo>>/proc/$(pidof less)/fd/0 hi
lsof /tmp/; ss; strace -etrace=openat,getdents64,connect ls

您使用lsof即可知道进程打开了什么(网络)文件

表达式if\else
zenity --question --text="确认要执行吗?" && echo "您已确认执行。" || echo "您取消了执行。"
test -f nohup.out &&wc $_

for,case在文尾。 罕见于urls|xargs cat
a=hih;echo ${a:0:2} ${#a} ${a//h/H} $((10/3)) {01..9..2} {good,bad}boy {z..a}

hi 3 HiH 3 01 03 05 07 09 goodboy badboy..
{} 允许并列,嵌套和正择 🥰
使用可嵌套的 $() 取代`` 除了可以调用文字替换API, 还能提升组合力
diff <(echo hello world) <(echo hello bar)
less <<<Good #配合 ruby -p; node -e 胶水使用
JS=$(cat <<OK
heredoc,就像""仍能内插${} ''
OK
)

不过sh系都支持多行字符串
可以手动 tmp=$(mktemp); trap 'rm -f "$tmp"' EXIT

— 目录管理
文件夹名/拖放 转到。不要用cd那个太古板了
mkdir -p 目录/树
ls -lh; tree; du -h 读目录,计算df大小
echo>>a.txt 记录
rm -rf * 清空$(dirs)
^xg #查看符合正择的文件
cp;mv 复制和移动到arg-1即 $_
chmod {+x,755} 设置可执行

set -s noglob 以禁用*正择
可深度遍历
,匹配多个斜杠。正则[0-9]仍有效,但'?' 变成了(.), [^\d]* 成了 *[![:digit:]] ,从find和sed的使用来看😅bash的RegExp是🤡
ls !(*.mp4)
echo **/*.mp4

替换文件扩展名(thunar -B ,不得不说单字符很脑残,何况bash连对象键值都停留在get/set函数名) https://wangdoc.com/bash/string#搜索和替换
fp=a.x.mp4; echo ${fp%.*} ${fp##*.}
echo ${fp/.*/} ${fp/*./}

a.x mp4
a mp4
for fp in *; do [[ $fp =~ \.png$ ]]&&ls "$fp"; done

自至剪贴板
a=$(xclip -selection clipboard -o); base64 <<<$a|xclip -selection clipboard

练习:封装这些功能为函数或basename式CLI工具,加什么参数你看着办,这幼儿园Perl我看着就难受

— sh变量
不支持str和float算式,支持?:
pargs() { echo "$@"; }
pargs x y #x y. 不像argv它不含$0
echo $PS{1,2} #为什么大佬教你要 "$var"呢?试试在文件名里加空格或 echo $(cal) ?牛逼啊,还能SQL注入了!默认语意这么脑残
IFS=":" # read分隔符为冒号, 遍历可执行注册表
for dir in $PATH; do
echo "$dir"; done
export PATH #bash连字符串变量也不默认传给子进程
#有无屏幕, 其实 .bash_login 就是tty-only
(xdotool sleep .1 search --name tty windowsize 100% 100%)& alacritty
[ -z $DISPLAY ]&&startx /bin/sh atty.sh

read id; ${id:=Peter}
read id; ${id:?Oh no Peter}
#不建议用 declare -i c; c=1+2 或let=运算,可以
((a=1,b=2)); array=([2]=c [0]=a [1]=b) #读取 "${array[0或@]}"



— 权限
您的系统通过chown和setcap来管理特权,所有文件通过 umask: ugo(user grp other)三权分立,一般为 644, 755(=rwxrxrx 对于目录x允许进入)
6(rw-)即是位旗 0b100+0b10+0; echo $[2#100+2#10],644以此类推
特别地,wheel 用户组(类似win/droid的SYSTEM) 可使用/bin/sudo 来鉴权到sudo的所有者root。为了防止 LD_PRELOAD注入应使用 visudo 修改配置
find / -perm /4000

列举所有自鉴权模块如su
sudo setcap cap_net_bind_service=+ep $(command -v python)

#允许bind 80端口
# cat /etc/{,g}shadow /etc/{passwd,fstab,sudoers,ssh/sshd_config} 只有root能查看。权力越大责任越小,rm -rf /* 😱享受特权吧!

— 古怪的语法
先前学过java的大佬,会觉得 if-fi case-esac for-done 比Lua和Matlab还啰嗦,这是因为bash采取了shlex 而且和TeX一样不懂变通
if [ ]; then, for in ; do 更像是2条命令(do eval字符串 done) 而不是“块”, forkBomb() { sleep; } 尾分号同理
bash 区分命令和计算的$()也很含糊,但在pwsh上都是 ()
#bash #tool 测一测您的笔电电池,还有多少容量? 🔋
eval `cat /sys/class/power_supply/BAT0/* |grep -o POW.*`
echo $POWER_SUPPLY_ENERGY_FULL{,_DESIGN} 1000/ /p|dc


科普:Li-ion 电池都有百次以上的循环寿命,且其电压U与剩余容量C成反比,要提升寿命,需要在闲置时把电量保持在70%左右

'L16M2PB2' Battery by SMP#14845 ⚡️
IU=16720000 mW
C0=.76C=24160000 mWh
C=.90design=31640000 mWh
U=8373000 mV > 7500000 mV
Lm=100% 💡
nCyc=205🔋
CpW=1.444h

BAT -h
IU=16.749 W
C0=.82C=26.15 Wh
C=.90design=31.64 Wh
U=8.481 V > 7.5 V

😅我对AI的代码复用率和准确性醉了, 大家复制粘贴切勿模仿,1个排版模板浪费了我个把小时
😅 echo */ 可以显示文件夹,但 !(*/) 不能显示非*.* 格式的文件名, 我想对bash作者说你设计glob设了个 🐓……自己都玩不明白还要 find -depth1 😅

另外, /sys/class/power_supply/BAT$i/ 是个完全能 i=select 的主,类如章节选择完全可以绑定为 select '-no' ls [0-9].mp4 ,既能read还能Tab。
有glob匹配您还要做select语句,您也真是 极大方便了应用层啊!?
只能评价为连pwsh都不如, 就像DBus之于COM,完全没有为API user 服务的意识

BAT() {
i=0;eval `cat /sys/class/power_supply/BAT$i/!(*/) 2>/dev/null|grep POW`
st=$([[ "$POWER_SUPPLY_STATUS" == C* ]] &&echo ⚡️)
tput setaf 6 bold;
echo "$(quote $POWER_SUPPLY_MODEL_NAME) $POWER_SUPPLY_TYPE by $POWER_SUPPLY_MANUFACTURER#$POWER_SUPPLY_SERIAL_NUMBER $st"
echo "IU=${POWER_SUPPLY_POWER_NOW} mW"
echo "C0=.${POWER_SUPPLY_CAPACITY}C=${POWER_SUPPLY_ENERGY_NOW} mWh"
tput setaf 1;echo "C=$(echo "scale=2;(${POWER_SUPPLY_ENERGY_FULL}/${POWER_SUPPLY_ENERGY_FULL_DESIGN})" | bc)design=${POWER_SUPPLY_ENERGY_FULL} mWh"
echo "U=${POWER_SUPPLY_VOLTAGE_NOW} mV > ${POWER_SUPPLY_VOLTAGE_MIN_DESIGN} mV"
tput sgr0;
echo Lm=$(echo `cat /sys/class/backlight/*/{,max_}brightness` 10/ /p|dc)0% 💡
echo "nCyc=${POWER_SUPPLY_CYCLE_COUNT}🔋"
echo "CpW=$(echo "scale=3;(${POWER_SUPPLY_ENERGY_NOW}/${POWER_SUPPLY_POWER_NOW})" | bc)h"
}
unit() { node -p 'process.argv[1].replace(/(\d+) m(Wh?|Ah?|V)/g, (m,n,k)=>n/1e6+" "+k)' "`cat`" ;}