J'ai ouvert un fichier PDF avec la visionneuse de documents à partir de l'interface graphique. Est-il possible d’obtenir le chemin de ce fichier dans un terminal/script?
TLDR:
for ip in $(pgrep -x evince); do lsof -F +p $ip|grep -i '^n.*\.pdf$'|sed s/^n//g; done
Explication:
Document Viewer
est le nom convivial du programme /usr/bin/evince
. Nous devons donc d’abord trouver l’ID de processus (PID) de evince
:
$ pgrep -x evince
22291
Pour répertorier tous les fichiers ouverts par ce PID, nous utiliserons la commande lsof
(notez que nous devrons répéter cette opération pour chaque PID au cas où nous aurions plusieurs instances de evince en cours d'exécution).
$ lsof -F +p 22291
some other files opened
.
.
.
n/home/c0rp/File.pdf
Ensuite, nous allons grep uniquement pour les fichiers PDF et supprimer le n non pertinent au début de la ligne:
$ lsof -Fn +p 22291 | grep -i '^n.*\.pdf$' | sed s/^n//g
/home/c0rp/File.pdf
Enfin, pour tout combiner dans une ligne bash:
for ip in $(pgrep -x evince); do lsof -F +p $ip|grep -i '^n.*\.pdf$'|sed s/^n//g; done
Ce one-liner s’inspire de la réponse de terdon, qui est également très intéressante car elle résout le même problème.
Si vous êtes intéressé par ce n dans lsof -Fn
, voici une citation de man lsof
à propos de -F
option:
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
...
...
alors -Fn
, dit me montrer file name, comment, Internet address
Une autre approche serait quelque chose comme
$ 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
En général, chaque fois que vous voulez effectuer une recherche dans un processus, pgrep
est meilleur que ps -ef | grep process
car ce dernier correspondra également au processus grep
lui-même. Par exemple:
$ 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
L'option -x
ne renvoie que les processus dont le nom complet correspond à la chaîne transmise. Cela est nécessaire car evince
démarre également un démon (evinced
) et sera également associé sans le -x
(le -l
est d'imprimer le nom ainsi que le PID. ):
$ pgrep -l evince
4606 evince
4611 evinced
4613 evince
$ pgrep -lx evince
4606 evince
4613 evince
Ainsi, la boucle for exécutera lsof
sur chacun des PID renvoyés par pgrep
. Celles-ci sont ensuite passées à travers grep
. L'option -o
signifie "imprimer uniquement la partie correspondante de la ligne" et le -P
active les expressions régulières compatibles Perl, ce qui nous permet d'utiliser \K
. Dans les PCRE, \K
signifie "tout ce qui correspond avant le \K ". In other words, since I am using
- o, it will match lines beginning with
nand ending with
. Pdfbut it will not print the matched
n`. Le résultat est que seul le nom du fichier est imprimé.
Vous n'avez même pas besoin de spécifier le nom de fichier du fichier pdf ouvert via Document Viewer. Cette commande ci-dessous affiche les chemins de tous les fichiers pdf ouverts via Document Viewer .evince
est la commande actuelle pour ouvrir Document Viewer via un terminal.
ps -ef | grep evince | sed -n '/.*\.pdf/p' | sed 's/.*evince \(.*\)$/\1/g'
Exemple:
$ ps -ef | grep evince | sed -n '/.*\.pdf/p' | sed 's/.*evince \(.*\)$/\1/g'
/media/avinash/C68C57908C5779BF/pdf/PHP/PHP-Manual.pdf
/media/avinash/C68C57908C5779BF/pdf/python.pdf
Mais tout le mérite revient à @ Corp .