我打开了几个应用程序。运行wmctrl并将输出通过管道传送到awk列出窗口 ID(不包括“粘性”窗口),如下所示:
$ wmctrl -l | awk ' !/-1/ { print $1 } '
0x00a00018
0x04800005
0x04e00005
0x04400003
0x05000003
0x0540002b
0x05a00012
0x05800002
0x05c00003
$
Run Code Online (Sandbox Code Playgroud)
我可以将此输出发送到wmctrl以关闭所有这些窗口:
没有需要保存内容的窗口和不需要响应的窗口将在不询问我的情况下关闭,但是
诸如具有未保存内容的编辑器或运行进程的终端的窗口将“正常”关闭:相应的应用程序将显示一个窗口,允许我保存更改或放弃更改或通知我仍在运行的进程。
分配给合适的快捷方式的以下脚本有效:
#!/bin/bash
list=$(wmctrl -l | awk ' !/-1/ { print $1 } ')
for i in ${list[@]}
do
wmctrl -i -a $i
wmctrl -i -c $i
done
Run Code Online (Sandbox Code Playgroud)
我发现更简单的(对我来说)for i in $list
也有效。
有什么理由更喜欢一个吗?
“粘性”和“优雅”是来自man wmctrl
.
甲while
环常常是更适合比for
用于处理命令输出,允许你处理线,而不是直接将它们存储在一个列表中循环或数组。
在这种情况下,它允许您awk
完全避免该命令:
wmctrl -l | while read -r id dt stuff; do
case $dt in
-1) continue
;;
*) echo wmctrl -i -a "$id"
echo wmctrl -i -c "$id"
;;
esac
done
Run Code Online (Sandbox Code Playgroud)
echo
一旦您对它做正确的事情感到高兴,请删除s。
正如评论中所述,xargs
是另一种选择 - 但是当您想对每个arg
.
原标题问“什么类型的for循环更好”。
对我自己来说,最好的方法是最快的。要找出将time
命令添加到脚本或函数中的方法。一些例子:
$ time du -s
real 0m0.002s
user 0m0.003s
sys 0m0.000s
$ time ls
real 0m0.004s
user 0m0.000s
sys 0m0.004s
Run Code Online (Sandbox Code Playgroud)
但是,在测试之间刷新缓存的缓冲区很重要:
如果两个循环的速度大致相同,我会选择可读性最好的循环。
这个问题的范围是使速度无关紧要,因为大部分时间都花在等待用户输入上,而且大多数人最多只能打开 10 个窗口。
其他答案侧重于重写脚本,所以我也会给我的两美分。
线路:
list=$(wmctrl -l | awk ' !/-1/ { print $1 } ')
Run Code Online (Sandbox Code Playgroud)
list
是通用的而不是描述性的所以我会使用:
Windows=( $(wmctrl -l | awk ' !/-1/ { print $1 } ') )
Run Code Online (Sandbox Code Playgroud)
线路:
wmctrl -i -a $i
Run Code Online (Sandbox Code Playgroud)
-i
并且-a
可以组合成-ia
.$i
是非描述性的,我会$Window
改用。有两种方法可以编写更短、更易读的脚本,第一种是使用数组:
#!/bin/bash
Windows=( $(wmctrl -l | awk ' !/-1/ { print $1 } ' ) )
for Window in "${Windows[@]}" ; do wmctrl -ia $Window -c $Window ; done
Run Code Online (Sandbox Code Playgroud)
第二个没有数组:
#!/bin/bash
Windows=$(wmctrl -l | awk ' !/-1/ { print $1 } ' )
for Window in $Windows ; do wmctrl -ia $Window -c $Window ; done
Run Code Online (Sandbox Code Playgroud)
我更喜欢数组方法,因为我正在尝试更多地了解它们并希望尽可能多地使用它们。然而,选择权在你。
您可以在没有阵列的情况下进行管理。将IFS设置为换行符将允许for
循环行,然后您可以unset
在循环内使用 IFS 而不会影响循环本身。
#!/bin/bash
IFS=$'\n'
for i in $(wmctrl -l); do
unset IFS
set -- $i
(($2 > -1)) && wmctrl -i -a $1 -c $1
done
Run Code Online (Sandbox Code Playgroud)
(重置位置参数是将一行拆分为字段的巧妙技巧)。
如果您需要使用数组,您可以使用mapfile并利用回调函数来创建类似于循环的内容。对于一小组迭代,使用更简单的函数调用可能是一个优势。
mapfile -c 1 -C 'f(){ set -- $@; (($3 >= 0)) && wmctrl -i -a $2 -c $2; }; f' -t < <(wmctrl -l)
Run Code Online (Sandbox Code Playgroud)
(长版):
#!/bin/bash
f(){
set -- $@
if (($3 > -1)); then
wmctrl -i -a $2 -c $2
fi
}
mapfile -c 1 -C f -t < <(wmctrl -l)
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1720 次 |
最近记录: |