Moh*_*ani 6 command-line evince
我已经使用 GUI 中的文档查看器打开了一个 PDF 文件。有没有办法在终端/脚本中获取此文件的路径?
c0r*_*0rp 12
域名注册地址:
for ip in $(pgrep -x evince); do lsof -F +p $ip|grep -i '^n.*\.pdf$'|sed s/^n//g; done
Run Code Online (Sandbox Code Playgroud)
解释:
Document Viewer是程序的友好名称/usr/bin/evince。所以首先我们需要找到以下的进程 ID (PID) evince:
$ pgrep -x evince
22291
Run Code Online (Sandbox Code Playgroud)
要列出此 PID 打开的所有文件,我们将使用该lsof命令(请注意,我们需要对每个 PID 重复此操作,以防我们有多个 evince 运行实例)
$ lsof -F +p 22291
some other files opened
.
.
.
n/home/c0rp/File.pdf
Run Code Online (Sandbox Code Playgroud)
接下来,我们将仅对 pdf 进行 grep 并在行首丢弃不相关的 n:
$ lsof -Fn +p 22291 | grep -i '^n.*\.pdf$' | sed s/^n//g
/home/c0rp/File.pdf
Run Code Online (Sandbox Code Playgroud)
最后将所有内容组合在一个 bash 行中:
for ip in $(pgrep -x evince); do lsof -F +p $ip|grep -i '^n.*\.pdf$'|sed s/^n//g; done
Run Code Online (Sandbox Code Playgroud)
这个 one-liner 的灵感来自 terdon 的答案,它在解决同一问题的方式上也非常有趣。
如果您对n inlsof -Fn的用途感兴趣,这里是man lsof关于该-F选项的引用:
OUTPUT FOR OTHER PROGRAMS
When the -F option is specified, lsof produces output that is suitable
for processing by another program - e.g, an awk or Perl script, or a C
program.
...
...
These are the fields that lsof will produce. The single character
listed first is the field identifier.
...
...
n file name, comment, Internet address
...
...
Run Code Online (Sandbox Code Playgroud)
所以-Fn,是说给我看file name, comment, Internet address
另一种方法是这样的
$ for ip in $(pgrep -x evince); do lsof -F +p $ip | grep -oP '^n\K.*\.pdf$'; done
/home/terdon/file1.pdf
/home/terdon/file2.pdf
Run Code Online (Sandbox Code Playgroud)
一般来说,无论何时你想搜索一个进程,pgrep都比ps -ef | grep process后者更好,因为后者也会匹配grep进程本身。例如:
$ ps -ef | grep emacs
terdon 6647 6424 23 16:26 pts/14 00:00:02 emacs
terdon 6813 6424 0 16:26 pts/14 00:00:00 grep --color emacs
$ pgrep emacs
6647
Run Code Online (Sandbox Code Playgroud)
该-x选项仅返回整个名称与传递的字符串匹配的进程。这是必需的,因为evince还启动了一个守护进程 ( evinced) 并且它也将在不匹配的情况下进行匹配-x(-l打印名称和 PID):
$ pgrep -l evince
4606 evince
4611 evinced
4613 evince
$ pgrep -lx evince
4606 evince
4613 evince
Run Code Online (Sandbox Code Playgroud)
因此,for 循环将lsof在由 返回的每个 PID 上运行pgrep。然后通过这些grep。该-o选项的意思是“仅打印该行的匹配部分”并-P激活 Perl 兼容正则表达式,让我们使用\K. 在 PCRE 中,\K表示“丢弃\K ". In other words, since I am using-o , it will match lines beginning withn and ending with.pdf but it will not print the matchedn`之前匹配的所有内容。结果是只打印文件名。