我打开了几个应用程序。运行wmctrl并将输出通过管道传输到awk会列出窗口 ID(不包括“粘性”窗口),如下所示:
$ wmctrl -l | awk ' !/-1/ { print $1 } '
0x00a00018
0x04800005
0x04e00005
0x04400003
0x05000003
0x0540002b
0x05a00012
0x05800002
0x05c00003
$
我可以将此输出发送到wmctrl以关闭所有这些窗口:
没有需要保存内容的窗口和不需要响应的窗口将在不询问我的情况下关闭,但是
诸如具有未保存内容的编辑器或运行进程的终端之类的窗口将“优雅地”关闭:相应的应用程序将显示一个窗口,允许我保存更改或放弃更改或通知我仍在运行的进程。
分配给合适快捷方式的以下脚本有效:
#!/bin/bash
list=$(wmctrl -l | awk ' !/-1/ { print $1 } ')
for i in ${list[@]}
do
wmctrl -i -a $i
wmctrl -i -c $i
done
我发现更简单的(对我来说)for i in $list
也有效。
有什么理由更喜欢其中一个吗?
“粘”和“优雅”是来自 的术语man wmctrl
。
在您的脚本
$list
中与${list[@]}
.后者是数组语法,但在您的脚本中它是一个普通变量。
由于您的
wmctl
输出项中没有空格,因此您不需要数组,并且使用$list
非常好。如果它是一个数组,则
$list
只会是数组的第一项 (=>item1
)${list[@]}
并将扩展到所有项 (=>item1 item2 item3
)。但是,如果它实际上是一个数组,那么您真正想要的是
"${list[@]}"
(带引号)延伸到"item1" "item2" "item3"
,因此它不会因空白而窒息。(阅读)
循环通常
while
比for
循环更适合处理命令输出,允许您直接处理行而不是将它们存储在列表或数组中。在这种情况下,它允许您完全避免该
awk
命令:echo
一旦你对它做正确的事情感到高兴,就删除s。如评论中所述,
xargs
是另一种选择-但是当您想对每个arg
.回复原标题
原标题问“什么类型的for循环比较好”。
对我自己来说,最好的方法是最快的。要找出将
time
命令添加到您的脚本或函数。一些例子:但是,在测试之间刷新缓存缓冲区很重要:
如果两个循环的速度大致相同,我会选择可读性最好的一个。
这个问题的范围是使速度无关紧要,因为大部分时间都花在等待用户输入上,而且大多数人最多只能打开 10 个窗口。
对问题主体的回答
其他答案集中在重写脚本上,所以我也会付出我的两分钱。
该行:
list
是通用的而不是描述性的所以我会使用:
该行:
-i
并且-a
可以组合成-ia
.$i
是非描述性的,我会$Window
改用。有两种方法可以编写更短且更易读的脚本,第一种是使用数组:
第二个没有数组:
我更喜欢数组方法,因为我正在尝试更多地了解它们并希望尽可能多地使用它们。然而,选择是你的。
您可以在没有阵列的情况下进行管理。将IFS设置为换行符将允许
for
循环行,然后您可以unset
在循环内的 IFS 而不会影响循环本身。(重置位置参数是将一行拆分为字段的巧妙技巧)。
如果您需要使用数组,您可以使用mapfile并利用回调函数创建类似于循环的内容。对于一小组迭代,使用更简单的函数调用可能是一个优势。
(长版):