web-dev-qa-db-fra.com

Comment diviser un fichier "/ proc / * / environ" en plusieurs lignes?

J'essaie d'obtenir le contenu de n'importe quel fichier /proc/*PID*/environ 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 de quoi s'agit-il? Quelle est la bonne façon d'atteindre le résultat ci-dessus?

16
pa4080

Les entrées sont séparées par le caractère NULL, 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 d'appliquer xargs -0 -L1 dessus:

$ 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 - lit les lignes délimitées par un caractère nul,
  • -L1 - lit une ligne par exécution de la commande
  • -a file lire les lignes de file
  • et si aucune commande n'est spécifiée, xargs affiche simplement la ligne.

Diverses commandes GNU ont des options permettant de travailler avec des données délimitées par des caractères nuls: -z pour sed, sort, uniq, grep etc., et pour les noms de fichiers, -print0 avec find et -Z avec __pod.

Alternativement, vous pouvez utiliser un vieux bash simple:

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

-d '' indique à read de lire jusqu'à l'octet nul, IFS= et -r empêchent la division de champ et l'échappement de barre oblique inverse, de sorte que les données soient lues telles quelles, %q citera des caractères spéciaux dans la sortie.

Puisque vous avez utilisé sed, vous auriez pu:

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

qui pointe juste sur une nouvelle ligne à la fin de chaque ligne délimitée par un zéro.

22
muru
  • Vous pouvez utiliser cut:

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

    utiliser null en tant que délimiteur et générer un délimiteur de nouvelle ligne, en sélectionnant éventuellement certains champs/lignes uniquement.

  • Ou filtrez tr, en traduisant les nulls en nouvelles lignes:

    tr '\0' '\n' </proc/$pid/environ
    
  • Ou tout simplement coller avec votre version sed ...

12
Xen2050

Vous pouvez utiliser strings comme 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 man

PRÉ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.
9
Yaron

En vous 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 {}`
1
Marcin