Làm cách nào để tôi tách một tập tin / Proc / * / môi trường thành các dòng riêng biệt?


19

Tôi đang cố gắng để có được nội dung của bất kỳ /proc/*PID*/environtệp nào ở định dạng dễ đọc hơn. Tôi có thể làm điều đó theo cách hiển thị bên dưới, nhưng tôi chắc chắn đây không phải là cách thích hợp.

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

Có lẽ tôi phải gán một giá trị cụ thể $IFS, nhưng nó là gì? Cách thích hợp để đạt được kết quả trên là gì?

Câu trả lời:


25

Các mục được phân tách bằng ký tự null, xem 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.

Vì vậy, một cách đơn giản là áp dụng xargs -0 -L1trên nó:

$ 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 - đọc các dòng phân cách null
  • -L1 - đọc một dòng trên mỗi lần thực hiện lệnh
  • -a file đọc các dòng từ file
  • và nếu không có lệnh nào được chỉ định, xargschỉ cần in dòng.

Lệnh GNU khác nhau có các tùy chọn để làm việc với dữ liệu null được phân định: -zcho sed, sort, uniq, grepvv, và cho tên tập tin, -print0với find-Zvới grep.

Ngoài ra, bạn có thể sử dụng bash cũ đơn giản:

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

-d ''yêu readcầu đọc cho đến khi một byte rỗng IFS=-rngăn chặn phân tách trường và thoát dấu gạch chéo ngược, để dữ liệu được đọc nguyên trạng, %qsẽ trích dẫn các ký tự đặc biệt trong đầu ra.

Vì bạn đã sử dụng sed, bạn có thể đã thực hiện:

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

mà chỉ xử lý một dòng mới ở cuối mỗi dòng phân cách null.


1
+1 cho mặc định xargsđể in, tôi không biết điều đó
Vincent Fourmond

2
Tuy nhiên, hãy nhớ rằng các mục nhập bị chấm dứt chính xác bởi vì đó là ký tự duy nhất không thể là một phần của giá trị. Nếu bạn thay thế chúng bằng các dòng mới, bạn có khả năng đưa ra một sự mơ hồ về việc hai dòng liên tiếp đại diện cho hai biến hay một biến có giá trị chứa một dòng mới theo sau là một phép gán.
chepner

13
  • Bạn có thể sử dụng cut:

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

    sử dụng null làm dấu phân cách và xuất ra một dấu phân cách dòng mới, tùy chọn chỉ chọn một số trường / dòng nhất định.

  • Hoặc lọc qua tr, dịch null sang dòng mới:

    tr '\0' '\n' </proc/$pid/environ
  • Hoặc chỉ cần gắn bó với sedphiên bản của bạn ...


4
Tôi đã sử dụng tr '\0' '\n'bao giờ kể từ khi tôi có thể nhớ lại. Đó là cách trực quan nhất để tôi thể hiện "thay thế tất cả NUL bằng dòng mới", và do đó là giải pháp ưa thích cá nhân của tôi.
egmont

10

Bạn có thể sử dụng stringsnhư sau:

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

Mẫu đầu ra:

$ 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

người đàn ông

TÊN

   strings - print the strings of printable characters in files.

SỰ MIÊU TẢ

   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
thật đẹp
Tù nhân

Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.