Как разделить файл "/proc/*/environment" на отдельные строки?
Я пытаюсь получить содержание любого /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
а что это? Как правильно достичь вышеуказанного результата?
6 ответов
Записи разделены нулевым символом, см. 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
который просто указывает на новую строку в конце каждой строки, разделенной нулем.
Вы могли бы использовать
cut
:cut -d '' -f1- --output-delimiter=$'\n' /proc/$pid/environ
используя null в качестве разделителя и выводя разделитель новой строки, опционально выбирая только определенные поля / строки.
Или отфильтровать
tr
переводим нули в переводы строк:tr '\0' '\n' </proc/$pid/environ
Или просто придерживайтесь своего
sed
версия...
Ты можешь использовать 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.
"man proc", поиск "environment", текст справки говорит:
Таким образом, чтобы распечатать среду процесса 1, вы должны сделать: $ strings /proc/1/environmental
Основываясь на ответе @muru, вы можете экспортировать эти переменные следующим образом:
`cat /proc/1/environ | xargs -0 -L1 -I{} echo export {}`
hexdump -v -e '/1 "%02X "' /proc/PID/environ |sed -e 's/00/0a/g' | xxd -r -p
как это работает сначала
hexdump -v -e '/1 "%02X "' /proc/PID/environ
будет (если вы замените PID на pid программы или самого себя) распечатает весь файл в шестнадцатеричном формате с укусом, разделенным пробелом. затем я передаю это в
sed -e 's/00/0a/g'
который берет все 00 или нули, которые используются в качестве разделителей для каждой записи, и преобразует их в новые строки. чтобы я не использовал
xxd -r -p
чтобы преобразовать шестнадцатеричный код в двоичный читабельный текст.