Comment diviser un fichier «/ proc / * / environ» en lignes distinctes?

19

J'essaie d'obtenir le contenu de n'importe quel /proc/*PID*/environfichier dans un format plus lisible. Je peux le faire de la manière indiquée ci-dessous, mais je suis sûr que ce n'est pas la bonne façon.

$ cat "/proc/$(pgrep gnome-session -n -U $UID)/environ"
USER=spasTEXTDOMAIN=im-configXDG_SEAT=seat0XDG_SESSION_TYPE=waylandSHLVL=1QT4_IM_MODULE=ximHOME=/home/spasDESKTOP_SESSION=ubuntuGNOME_SHELL_SESSION_MODE=ubuntuDBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/busIM_CONFIG_PHASE=2LOGNAME=spasGTK_IM_MODULE=ibusJOURNAL_STREAM=9:147845_=/usr/bin/gnome-sessionUSERNAME=spasXDG_SESSION_ID=70PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/binXDG_RUNTIME_DIR=/run/user/1000LANG=en_US.UTF-8XDG_CURRENT_DESKTOP=ubuntu:GNOMEXDG_SESSION_DESKTOP=ubuntuXMODIFIERS=@im=ibusSHELL=/bin/bashGDMSESSION=ubuntuTEXTDOMAINDIR=/usr/share/locale/XDG_VTNR=2QT_IM_MODULE=ximPWD=/home/spasCLUTTER_IM_MODULE=ximXDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share:/usr/share:/var/lib/snapd/desktopXDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg
$ cat -e "/proc/$(pgrep gnome-session -n -U $UID)/environ"
USER=spas^@TEXTDOMAIN=im-config^@XDG_SEAT=seat0^@XDG_SESSION_TYPE=wayland^@SHLVL=1^@QT4_IM_MODULE=xim^@HOME=/home/spas^@DESKTOP_SESSION=ubuntu^@GNOME_SHELL_SESSION_MODE=ubuntu^@DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/1000/bus^@IM_CONFIG_PHASE=2^@LOGNAME=spas^@GTK_IM_MODULE=ibus^@JOURNAL_STREAM=9:147845^@_=/usr/bin/gnome-session^@USERNAME=spas^@XDG_SESSION_ID=70^@PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin^@XDG_RUNTIME_DIR=/run/user/1000^@LANG=en_US.UTF-8^@XDG_CURRENT_DESKTOP=ubuntu:GNOME^@XDG_SESSION_DESKTOP=ubuntu^@XMODIFIERS=@im=ibus^@SHELL=/bin/bash^@GDMSESSION=ubuntu^@TEXTDOMAINDIR=/usr/share/locale/^@XDG_VTNR=2^@QT_IM_MODULE=xim^@PWD=/home/spas^@CLUTTER_IM_MODULE=xim^@XDG_DATA_DIRS=/usr/share/ubuntu:/usr/local/share:/usr/share:/var/lib/snapd/desktop^@XDG_CONFIG_DIRS=/etc/xdg/xdg-ubuntu:/etc/xdg^@
$ cat -e "/proc/$(pgrep gnome-session -n -U $UID)/environ" | sed 's/\^@/\n/g'
USER=spas
TEXTDOMAIN=im-config
XDG_SEAT=seat0
XDG_SESSION_TYPE=wayland
...

Peut-être que je dois attribuer une valeur spécifique à $IFS, mais qu'est-ce que c'est? Quelle est la bonne façon d'atteindre le résultat ci-dessus?

pa4080
la source

Réponses:

25

Les entrées sont séparées par le caractère nul, voir man 5 proc:

/proc/[pid]/environ
      This file contains the environment for the process.  The entries
      are separated by null bytes ('\0'), and there may be a null byte
      at  the  end.

Donc, un moyen simple est de l'appliquer xargs -0 -L1:

$ xargs -0 -L1 -a /proc/self/environ
LC_CTYPE=UTF-8
USER=muru
LOGNAME=muru
HOME=/home/muru
MAIL=/var/mail/muru
SHELL=/bin/zsh
...
  • -0 - lire des lignes délimitées par des nuls,
  • -L1 - lire une ligne par exécution de commande
  • -a file lire les lignes de file
  • et si aucune commande n'est spécifiée, xargsimprime simplement la ligne.

Diverses commandes GNU ont des options de travail avec des données délimitées par null: -zpour sed, sort, uniq, grepetc, et des noms de fichiers, -print0avec findet -Zavec grep.

Alternativement, vous pouvez utiliser un ancien bash simple:

while IFS= read -d '' -r line
do
    printf "%q\n" "$line"
done < /proc/.../environ

-d ''indique readde lire jusqu'à un octet nul IFS=et d' -rempêcher le fractionnement de champ et l'échappement de barre oblique inverse, de sorte que les données soient lues telles quelles, %qcite des caractères spéciaux en sortie.

Depuis que vous l'avez utilisé sed, vous auriez pu faire:

sed -z 's/$/\n/' /proc/.../environ

qui pointe simplement sur une nouvelle ligne à la fin de chaque ligne délimitée par des valeurs nulles.

muru
la source
1
+1 pour le défaut d' xargsimprimer, je ne savais pas cela
Vincent Fourmond
2
Gardez à l'esprit, cependant, que les entrées se terminent par un caractère nul précisément parce que c'est le seul caractère qui ne peut pas faire partie d'une valeur. Si vous les remplacez par des sauts de ligne, vous introduisez potentiellement une ambiguïté sur le fait que deux lignes consécutives représentent deux variables ou une variable dont la valeur contient un retour à la ligne suivi de ce qui ressemble à une affectation.
chepner
13
  • Vous pouvez utiliser cut:

    cut -d '' -f1- --output-delimiter=$'\n' /proc/$pid/environ

    utiliser null comme délimiteur et produire un délimiteur de nouvelle ligne, en sélectionnant éventuellement certains champs / lignes uniquement.

  • Ou filtrez tr, en convertissant les valeurs nulles en nouvelles lignes:

    tr '\0' '\n' </proc/$pid/environ
  • Ou restez simplement avec votre sedversion ...

Xen2050
la source
4
J'utilise tr '\0' '\n'depuis que je me souvienne. C'est le moyen le plus intuitif pour moi d'exprimer "remplacer tous les NUL par des nouvelles lignes", et donc ma solution personnelle préférée.
egmont
10

Vous pouvez utiliser stringscomme suit:

strings /proc/$(pgrep gnome-session -n -U $UID)/environ

Exemple de sortie:

$ strings /proc/$(pgrep gnome-session -n -U $UID)/environ
GNOME_KEYRING_PID=
LANGUAGE=en_US
J2SDKDIR=/usr/lib/jvm/java-8-oracle
LC_TIME=en_US.UTF-8
XDG_SEAT=seat0
XDG_SESSION_TYPE=x11
COMPIZ_CONFIG_PROFILE=ubuntu
SESSION=ubuntu

cordes homme

NOM

   strings - print the strings of printable characters in files.

LA DESCRIPTION

   For each file given, GNU strings prints the printable character
   sequences that are at least 4 characters long (or the number given with
   the options below) and are followed by an unprintable character.  By
   default, it only prints the strings from the initialized and loaded
   sections of object files; for other types of files, it prints the
   strings from the whole file.

   strings is mainly useful for determining the contents of non-text
   files.
Yaron
la source
1
c'est beau.
Prisonnier
1

En s'appuyant sur la réponse de @ muru, vous pouvez ensuite exporter ces variables avec les éléments suivants:

`cat /proc/1/environ | xargs -0 -L1 -I{} echo export {}`
Marcin
la source
1
En fait, j'utilise la commande:, export $(xargs -0 -a "/proc/$(pgrep gnome-session -n -U $UID)/environ")référence: Comment puis-je afficher les messages de notification-envoi déclenchés par crontab?
pa4080
1
@ pa4080 Ah nice
Marcin