Come faccio a dividere un file "/ proc / * / environment" in righe separate?


19

Sto cercando di ottenere il contenuto di qualsiasi /proc/*PID*/environfile in un formato più leggibile. Sono in grado di farlo nel modo mostrato di seguito, ma sono sicuro che questo non è il modo corretto.

$ 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
...

Forse devo assegnare un valore specifico a $IFS, ma che cos'è? Qual è il modo corretto per ottenere il risultato sopra?

Risposte:


25

Le voci sono separate dal carattere null, vedere 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.

Quindi un modo semplice è applicare xargs -0 -L1su di esso:

$ 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 - leggere righe delimitate da null,
  • -L1 - leggere una riga per l'esecuzione del comando
  • -a file leggere le righe da file
  • e se non viene specificato alcun comando, xargsstampa semplicemente la riga.

Vari comandi GNU hanno opzioni per lavorare con dati nulli delimitati: -zper sed, sort, uniq, grepecc, e di nomi di file, -print0con finde -Zcon grep.

In alternativa, puoi usare semplicemente il vecchio bash:

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

-d ''dice readdi leggere fino a un byte nullo IFS=e di -rimpedire la divisione dei campi e la backslash-escape, in modo che i dati vengano letti così come sono, %qciterà caratteri speciali nell'output.

Da quando hai usato sed, avresti potuto fare:

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

che si adatta a una nuova riga alla fine di ogni riga delimitata da null.


1
+1 per impostazione predefinita di xargsstampa, non ne ero a conoscenza
Vincent Fourmond,

2
Tieni presente, tuttavia, che le voci sono nulle proprio perché è l'unico carattere che non può far parte di un valore. Se li sostituisci con le nuove righe, potresti introdurre un'ambiguità sul fatto che due righe consecutive rappresentino due variabili o una variabile il cui valore contiene una nuova riga seguita da quello che sembra un incarico.
Chepner,

13
  • Puoi usare cut:

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

    usando null come delimitatore e producendo un delimitatore newline, opzionalmente selezionando solo determinati campi / linee.

  • O filtrare tr, traducendo i null in newline:

    tr '\0' '\n' </proc/$pid/environ
  • O semplicemente rispetta la tua sedversione ...


4
Lo uso tr '\0' '\n'da quando ricordo. Questo è il modo più intuitivo per me di esprimere "sostituisci tutte le NUL con newline", e quindi la mia soluzione personale preferita.
egmont,

10

Puoi usare stringscome segue:

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

Esempio di output:

$ 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

stringhe uomo

NOME

   strings - print the strings of printable characters in files.

DESCRIZIONE

   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.

1
Questo è bello.
Prigioniero

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.