Jak podzielić plik „/ proc / * / Environment” na osobne linie?

19

Próbuję uzyskać zawartość dowolnego /proc/*PID*/environpliku w bardziej czytelnym formacie. Jestem w stanie to zrobić w sposób pokazany poniżej, ale jestem pewien, że to nie jest właściwy sposób.

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

Może muszę przypisać określoną wartość $IFS, ale co to jest? Jaki jest właściwy sposób na osiągnięcie powyższego wyniku?

pa4080
źródło

Odpowiedzi:

25

Wpisy są oddzielone znakiem null, patrz 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.

Tak więc prosty sposób to zastosować 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 - czytaj linie rozdzielane zerami,
  • -L1 - odczytać jeden wiersz na wykonanie polecenia
  • -a file czytaj wiersze z file
  • a jeśli nie podano żadnego polecenia, xargspo prostu drukuje linię.

Różne polecenia GNU mają opcje do pracy z danymi NUL ograniczona: -zna sed, sort, uniq, grepitp, oraz nazw, -print0z findoraz -Zz grep.

Alternatywnie możesz użyć zwykłego starego basha:

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

-d ''każe readczytać do bajtu zerowego, IFS=a także -rzapobiegać dzieleniu pól i odwrotnemu ukośnikowi, aby dane były odczytywane w niezmienionej postaci, %qpoda w wynikach znaki specjalne.

Od kiedy używałeś sed, mogłeś:

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

który po prostu wstawia nową linię na końcu każdej linii rozdzielanej znakiem zerowym.

muru
źródło
1
+1 za domyślne xargsdrukowanie, nie wiedziałem o tym
Vincent Fourmond
2
Pamiętaj jednak, że wpisy są zakończone zerem właśnie dlatego, że jest to jedyny znak, który nie może być częścią wartości. Jeśli zastąpisz je nowymi liniami, potencjalnie wprowadzisz dwuznaczność, czy dwie kolejne linie reprezentują dwie zmienne, czy też jedną zmienną, której wartość zawiera nową linię, a po niej coś, co wygląda jak przypisanie.
chepner
13
  • Możesz użyć cut:

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

    użycie null jako separatora i generowanie separatora nowej linii, opcjonalnie wybranie tylko niektórych pól / linii.

  • Lub filtruj tr, tłumacząc wartości zerowe na nowe linie:

    tr '\0' '\n' </proc/$pid/environ
  • Lub po prostu trzymaj się swojej sedwersji ...

Xen2050
źródło
4
Używam tr '\0' '\n'odkąd pamiętam. To dla mnie najbardziej intuicyjny sposób wyrażenia „zamień wszystkie wartości NUL na nowe wiersze”, a zatem moje osobiste preferowane rozwiązanie.
egmont
10

Możesz użyć stringsw następujący sposób:

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

Próbka wyjścia:

$ 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

struny człowieka

NAZWA

   strings - print the strings of printable characters in files.

OPIS

   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
źródło
1
to jest piękne.
Więzień
1

Opierając się na odpowiedzi @ muru, możesz następnie wyeksportować te zmienne w następujący sposób:

`cat /proc/1/environ | xargs -0 -L1 -I{} echo export {}`
Marcin
źródło
1
Właściwie używam polecenia:, export $(xargs -0 -a "/proc/$(pgrep gnome-session -n -U $UID)/environ")referencja: Jak mogę wyświetlać powiadomienia wysyłane przez crontab?
pa4080,
1
@ pa4080 Ah nice
Marcin,