许多人使用 oneliners 和包含沿线代码的脚本
cat "$MYFILE" | command1 | command2 > "$OUTPUT"
Run Code Online (Sandbox Code Playgroud)
第一个cat通常被称为“对 cat 的无用使用”,因为从技术上讲,它需要启动一个新进程(通常/usr/bin/cat),如果命令已被执行,则可以避免这种情况。
< "$MYFILE" command1 | command2 > "$OUTPUT"
Run Code Online (Sandbox Code Playgroud)
因为然后 shell 只需要启动command1并简单地将其stdin指向给定的文件。
为什么 shell 不自动进行这种转换?我觉得“useless use of cat”语法更容易阅读,shell 应该有足够的信息来自动摆脱无用的 cat。的cat是在POSIX标准定义,因此壳应该允许执行它在内部,而不是在路径使用二进制的。shell 甚至可以只包含一个参数版本的实现,并回退到路径中的二进制文件。
有人知道为什么 bash 仍然默认启用历史替换吗?我的.bashrc已经包含set +H很多年了,但其他一些人仍然被这个功能所吸引。
鉴于几乎每个人都使用具有复制粘贴功能的终端,并且使用readline库编译的 bash和历史替换在默认情况下仅在交互式 shell 中启用,真的有任何理由拥有该功能吗?即使默认情况下为所有 shell 禁用此功能,也不会破坏现有脚本。
如果你不知道为什么历史替换被破坏,试试这个:
$ set +H # disable feature history substitution
$ echo "WTF???!?!!?"
WTF???!?!!?
$ set -H # enable feature history substitution
$ echo "WTF???!?!!?"
echo WTF???echo WTF???!?!!?
WTF???echo WTF???!?!!?
Run Code Online (Sandbox Code Playgroud)
(显然,如果默认情况下所有脚本都禁用该功能,并且存在一个功能可以在执行之前验证结果,则该功能存在重大问题:shopt -s histverify。)
也可以看看:
输入:
$ cat a.txt
1FOO2FOO3
4FOO5FOO5
2FOO1FOO9
$
Run Code Online (Sandbox Code Playgroud)
输出:
$ cat a.txt | sort SOMEMAGIC
2FOO1FOO9
1FOO2FOO3
4FOO5FOO5
$
Run Code Online (Sandbox Code Playgroud)
问题:如果我有几个字符长的分隔符,我该如何排序?(“FOO”)?
在示例a.txt中按第二列排序。
问题是一般来说,数字a.txt可以是任何东西。
假设一个繁忙的系统安装了一个非常快的块设备(高端 NVMe RAID,2 GB/s 写入,4 GB/s 读取)/data和一个非常慢的设备(USB HDD 与旋转 8 TB 磁盘,50 MB/s 写入, 60 MB/s 读取)安装在 上/backup,如何在/backup不牺牲 I/O 的情况下限制进程读取和写入/data?
据我所知,问题是 linux 只有全局旋钮dirty_background_bytes和dirty_bytes. 如果我将这些限制设置为 NVMe 的合理值(实际上大约为 2 GB 和 4 GB),则吞吐量很好,直到进程(例如rsync)开始向 USB 写入大量数据。在这种情况下dirty_background,填充了数据到 USB 设备并rsync停止污染更多页面。但是,这会导致写入快速设备的进程大幅减慢,因为这dirty_background是全局限制并在快速和慢速设备之间共享。我知道我可以根据连接到系统的最慢设备来限制脏字节,这将避免巨大的停顿,但会牺牲更快设备的一些吞吐量。
是否有等效dirty_background_bytes于单个块设备?减慢所有写入的进程真的是零意义的/data,以防/backup它很慢并且被其他进程访问。
我知道cgroup可以用来手动执行此操作(如何将每个进程 I/O 限制到最大限制?)。但是,我想对每个块设备进行调整,并且在降低整个系统的速度之前,应该限制访问所述设备的所有进程。如果进程同时写入快速和慢速设备,则只有在向慢速设备写入过多内容时,它才会变慢。