我一直认为使用 dash 而不是 bash 的唯一好处是 dash 更小,因此许多 dash 实例在启动时启动得更快。
但是我做了一些研究,发现有些人将他们所有的脚本迁移到 dash 中,希望他们能跑得更快,我也在Ubuntu Wiki 的DashAsBinSh文章中发现了这一点:
切换默认 shell 的主要原因是效率。bash 是一个优秀的全功能 shell,适合交互式使用;事实上,它仍然是默认的登录 shell。但是,与dash相比,它的启动和操作相当大且缓慢。
现在,我一直在系统上使用大量 bash 脚本来处理许多事情,我的问题是我有一个特定的脚本,我 24/7 连续运行,产生大约 200 个孩子,它们一起加热我的计算机 10° C多于正常使用。
这是一个相当大的脚本,有很多 bashism,因此将它们移植到 POSIX 或其他一些 shell 将非常耗时(而且 POSIX 对个人使用并不重要),但如果我能减少其中的一些,那将是值得的CPU使用率。我知道还有其他事情需要考虑,比如调用一个外部二进制文件,比如sed一个简单的 bashism ${foo/bar},或者grep代替=~.
TL;DR与 dash 相比,bash 的启动和运行速度真的更慢吗?是否有其他 Unix shell比 bash更有效?
今天,我的时钟自动调整为夏令时,来自 crontab 的脚本开始失败。我查看了发生了什么,并显示了以下错误LC_ALL=C:
日期:无效日期“2016-10-16”
我认为最好只是重新启动系统,但现在我已经重新启动,错误仍然出现:
$ date -d '2016-10-15'
Sat Oct 15 00:00:00 BRT 2016
$ date -d '2016-10-16'
date: data inválida “2016-10-16”
$ date -d '2016-10-17'
Mon Oct 17 00:00:00 BRST 2016
Run Code Online (Sandbox Code Playgroud)
什么可能导致这种情况?
我有以下代码将删除带有该模式的banana行和其后的 2 行:
sed '/banana/I,+2 d' file
Run Code Online (Sandbox Code Playgroud)
到现在为止还挺好!但是我需要它在之前 删除 2 行banana,但是我无法使用“减号”或其他任何东西(类似于grep -v -B2 banana file应该做什么但不做什么):
teresaejunior@localhost ~ > LC_ALL=C sed '-2,/banana/I d' file
sed: invalid option -- '2'
teresaejunior@localhost ~ > LC_ALL=C sed '/banana/I,-2 d' file
sed: -e expression #1, char 16: unexpected `,'
teresaejunior@localhost ~ > LC_ALL=C sed '/banana/I,2- d' file
sed: -e expression #1, char 17: unknown command: `-'
Run Code Online (Sandbox Code Playgroud) 我已经使用 PEM 证书设置了带有 SSL 的代理服务器。现在,我的几台机器我想自动信任这个证书(没有网络浏览器抱怨)。如何在每台机器上安装 PEM 证书?
另外,更推荐的是:生成自签名证书还是连接蛇油证书?
我有一个每天增长大约 200,000 行的文件,它都是由三行块组成的:
1358726575123 # key
Joseph Muller # name
carpenter # job
9973834728345
Andres Smith
student
7836472098652
Mariah Anthony
dentist
Run Code Online (Sandbox Code Playgroud)
现在,我有另一个文件,我从中提取了大约 10,000 个关键模式,例如1358726575123. 然后我for用这些模式运行一个循环,并且必须根据第一个文件检查它们。如果文件不包含此类模式,我会将模式保存在第三个文件中以供进一步处理:
for number in $(grep -o '[0-9]\{12\}' file2); do # finds about 10.000 keys
if ! grep -q ^$number$ file1; then # file1 is a huge file
printf "$number\n" >>file3 # we'll process file3 later
fi
done
Run Code Online (Sandbox Code Playgroud)
示例代码 grep 一个巨大的文件 10,000 次,我在一整天内大约每分钟运行一次这个循环。
由于巨大的文件不断增长,我该怎么做才能使这一切更快并节省一些 CPU?我想知道以某种方式通过其键(如果是,如何?)或使用 db 而不是纯文本对文件进行排序会有所帮助...
过去我做过很多晦涩的系统优化,但在我powertop告诉我应该将 USB 端口设置为autosuspend后,我摆脱了其中的大部分,这迫使它们永久休眠,并且在我意识到更高swappiness的好处之后.
但是今天,在查看 时/etc/fstab,我注意到我已经commit=60为/和/home设置了选项。我记得这是对笔记本电脑的优化,以减少对磁盘的写入量,从而节省电池。但后来我开始担心这可能会导致数据丢失(有时我的电池断开连接,然后在启动时fsck告诉我几个孤立的 inode)。
在寻找这个选项的解释时,我得出了以下解释(第二个似乎与我之前的理解相矛盾):
$ man mount | awk '/commit=/,/^$/'
commit=nrsec
Sync all data and metadata every nrsec seconds. The default value is 5 seconds.
Zero means default.
Run Code Online (Sandbox Code Playgroud)
https://forums.gentoo.org/viewtopic-p-4088752.html
commit=60 停止“立即”(默认为 5 秒)写入优先级,在几秒钟后缓存写入。这在重读和写混合在一起的情况下是很好的,在这种情况下,用户希望读取优先,以便处理器可以保持忙碌而不是在等待写入完成之前暂停,然后才能继续读取。
我见过的一个真实世界的例子是等待几秒钟 Gnome 下拉菜单出现,似乎没有任何原因。原因是磁盘忙于写入,因此CPU必须等待写入完成才能从磁盘中获取所有数据才能显示菜单。
提交到底有什么作用?增加它真的有好处吗(比如响应能力和节能)?它真的会导致数据丢失吗?
我最近在使用 bash 时遇到了一些奇怪的问题。在尝试简化我的脚本时,我想出了一小段代码:
$ o(){ echo | while read -r; do return 0; done; echo $?;}; o
0
$ o(){ echo | while read -r; do return 1; done; echo $?;}; o
1
Run Code Online (Sandbox Code Playgroud)
return应该退出函数而不打印$?,不是吗?好吧,然后我检查了我是否可以单独从管道返回:
$ echo | while read -r; do return 1; done
bash: return: can only `return' from a function or sourced script
Run Code Online (Sandbox Code Playgroud)
没有while循环也会发生同样的情况:
$ foo(){ : | return 1; echo "This should not be printed.";}
$ foo
This should not be printed. …Run Code Online (Sandbox Code Playgroud) 我在 bash 中编写了一个小“守护进程”,如果检测到它们,它将切换到耳机,如果没有,则切换到带有 PulseAudio 的外部 USB 扬声器。
我正在寻找的是某种方式来获取文件更改的通知/proc/asound/card0/codec#0,就像inotifywait在真实文件上一样(将 /proc 下的文件视为“伪文件”)。
我找到我的代码有点疯狂,因为它运行sleep 1与awk整个一天,也就是86400次,每天:)
while sleep 1; do
_1=${_2:-}
_2=$(awk '/Pin-ctls/{n++;if(n==4)print}' '/proc/asound/card0/codec#0')
[[ ${_1:-} = $_2 ]] ||
if [[ $_2 =~ OUT ]]; then
use_speakers
else
use_internal
fi
done
Run Code Online (Sandbox Code Playgroud)
我正在寻找的是类似的东西(这个例子不起作用):
codec=/proc/asound/card0/codec#0
while inotifywait $codec; do
if [[ $(awk '/Pin-ctls/{n++;if(n==4)print}' $codec) =~ OUT ]]; then
use_speakers
else
use_internal
fi
done
Run Code Online (Sandbox Code Playgroud)
这样,只有在$codec文件发生实际更改时,才会运行循环内的命令。
在 shell 脚本中,我需要等待一个标题上带有字符串的窗口出现,执行一些操作,然后等待它消失,然后执行一些其他操作。
直到昨天,我才有了这个简单的代码。它的问题是在脚本运行时磁盘无法进入省电状态,并且可能会持续好几个小时:
while :; do
until wmctrl -l | grep -q "$string"; do # until
sleep 0.5
done
: do action 1
while wmctrl -l | grep -q "$string"; do # while
sleep 0.5
done
: do action 2
done
Run Code Online (Sandbox Code Playgroud)
由于我认为上述代码疯狂地唤醒了磁盘,因此我查看了一些命令行工具的文档,并决定xdotool等待窗口出现,并xprop确定窗口何时消失:
while :; do
# we use `until' because sometimes xdotool just crashes
until xdotool search -sync -all -onlyvisible -pid $pid -name "$string"; do
:
done
# xdotool isn't trustworthy either, so check again …Run Code Online (Sandbox Code Playgroud) 我有一个庞大的音乐播放列表,虽然有些艺术家有很多专辑,但其他人只有一首歌。我想对播放列表进行排序,这样同一位艺术家就不会连续播放两次,或者他的歌曲不会大部分出现在播放列表的开头或结尾。
示例播放列表:
$ cat /tmp/playlist.m3u
Anna A. - Song 1
Anna A. - Song 2
I--Rock - Song 1
John B. - Song 1
John B. - Song 2
John B. - Song 3
John B. - Song 4
John B. - Song 5
Kyle C. - Song 1
U--Rock - Song 1
Run Code Online (Sandbox Code Playgroud)
来自sort -R或 的输出shuf:
$ sort -R /tmp/playlist.m3u
Anna A. - Song 1 #
U--Rock - Song 1
Anna A. - Song 2 # …Run Code Online (Sandbox Code Playgroud)