Как разделить файл «/ proc / * / environment» на отдельные строки?

19

Я пытаюсь получить содержимое любого /proc/*PID*/environфайла в более удобочитаемом формате. Я могу сделать это способом, показанным ниже, но я уверен, что это не правильный путь.

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

Может быть, я должен назначить конкретное значение $IFS, но что это? Как правильно достичь вышеуказанного результата?

pa4080
источник

Ответы:

25

Записи разделены нулевым символом, см . 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.

Таким образом, простой способ применить 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 - читать строки, разделенные нулем,
  • -L1 - читать одну строку за выполнение команды
  • -a file читать строки из file
  • и если команда не указана, xargsпросто печатает строку.

Различные команды GNU имеют опции для работы с данными нуля-разграничено: -zдля sed, sort, uniq, и grepт.д., и для имен файлов, -print0с findи -Zс Grep.

В качестве альтернативы вы можете использовать обычный старый bash:

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

-d ''говорит readчитать до нулевого байта IFS=и -rпредотвращает расщепление полей и обратную косую черту, так что данные читаются как есть, %qбудут заключать в кавычки специальные символы.

Так как вы использовали sed, вы могли бы сделать:

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

который просто указывает на новую строку в конце каждой строки, разделенной нулем.

Мур
источник
1
+1 по умолчанию xargsдля печати, я не знал об этом
Винсент Фурмонд
2
Имейте в виду, однако, что записи заканчиваются нулем именно потому, что это единственный символ, который не может быть частью значения. Если вы замените их символами новой строки, вы можете ввести двусмысленность того, представляют ли две последовательные строки две переменные, или одну переменную, значение которой содержит символ новой строки, за которым следует то, что выглядит как присваивание.
chepner
13
  • Вы можете использовать cut:

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

    используя null в качестве разделителя и выводя разделитель новой строки, опционально выбирая только определенные поля / строки.

  • Или отфильтруйте tr, переводя нули в новые строки:

    tr '\0' '\n' </proc/$pid/environ
  • Или просто придерживайтесь своей sedверсии ...

Xen2050
источник
4
Я использую с tr '\0' '\n'тех пор, как я могу вспомнить. Для меня это самый интуитивный способ выразить «заменить все NUL символами новой строки», и, следовательно, мое личное предпочтительное решение.
egmont
10

Вы можете использовать stringsследующим образом:

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

Пример вывода:

$ 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

мужские струны

ИМЯ

   strings - print the strings of printable characters in files.

ОПИСАНИЕ

   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
это красиво.
Заключенный
1

Основываясь на ответе @ muru, вы можете экспортировать эти переменные следующим образом:

`cat /proc/1/environ | xargs -0 -L1 -I{} echo export {}`
Marcin
источник
1
На самом деле я использую команду:, export $(xargs -0 -a "/proc/$(pgrep gnome-session -n -U $UID)/environ")ссылка: Как я могу показать сообщения уведомления-отправки, инициированные crontab?
pa4080
1
@ pa4080 Ах, хорошо
Марчин