Como dividir um arquivo “/ proc / * / environ” em linhas separadas?

9

Estou tentando obter o conteúdo de qualquer arquivo /proc/*PID*/environ em um formato mais legível. Eu sou capaz de fazer isso da maneira mostrada abaixo, mas tenho certeza que esse não é o jeito certo.

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

Talvez eu deva atribuir um valor específico para $IFS , mas o que é? Qual é a maneira correta de alcançar o resultado acima?

    
por pa4080 21.11.2017 / 10:35

4 respostas

15

As entradas são separadas pelo caractere nulo, consulte man 5 proc :

/proc/[pid]/environ
      This file contains the environment for the process.  The entries
      are separated by null bytes ('
$ 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
...
'), and there may be a null byte at the end.

Portanto, uma maneira simples é aplicar xargs -0 -L1 :

while IFS= read -d '' -r line
do
    printf "%q\n" "$line"
done < /proc/.../environ
  • -0 - ler linhas delimitadas por nulo,
  • -L1 - leia uma linha por execução de comando
  • -a file leu linhas de file
  • e se nenhum comando for especificado, xargs simplesmente imprime a linha.

Vários comandos GNU têm opções para trabalhar com dados delimitados por nulo: -z para sed , sort , uniq , grep etc e para nomes de arquivos, -print0 com find e -Z com grep.

Como alternativa, você pode usar o bash antigo:

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

-d '' informa read para leitura até um byte nulo, IFS= e -r previnem a divisão de campos e a contrabarra, para que os dados sejam lidos como são, %q citará caracteres especiais na saída.

Como você usou sed , você poderia ter feito:

/proc/[pid]/environ
      This file contains the environment for the process.  The entries
      are separated by null bytes ('
$ 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
...
'), and there may be a null byte at the end.

que apenas cria uma nova linha no final de cada linha delimitada por nulo.

    
por muru 21.11.2017 / 10:40
11
  • Você pode usar cut :

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

    usando nulo como um delimitador e gerando um delimitador de nova linha, opcionalmente escolhendo apenas certos campos / linhas.

  • Ou filtre por tr , traduzindo nulos para novas linhas:

    tr '
    cut -d '' -f1- --output-delimiter=$'\n' /proc/$pid/environ
    
    ' '\n' </proc/$pid/environ
  • Ou fique só com a sua sed versão ...

por Xen2050 21.11.2017 / 11:02
6

Você pode usar strings da seguinte forma:

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

Exemplo da saída:

$ 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 de homem

NAME

   strings - print the strings of printable characters in files.

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.
    
por Yaron 21.11.2017 / 10:41
1

Com base na resposta do @ muru, você pode exportar essas variáveis com o seguinte:

'cat /proc/1/environ | xargs -0 -L1 -I{} echo export {}'
    
por 12.10.2018 / 02:45