web-dev-qa-db-fra.com

Comment puis-je déterminer par programme quels fichiers sont actuellement ouverts dans evince?

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?

6

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

12
c0rp

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

Explication

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 withnand ending with. Pdfbut it will not print the matchedn`. Le résultat est que seul le nom du fichier est imprimé.

5
terdon

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 .

2
Avinash Raj