"orienv" 및 "currenv" 명령을 사용하여 두 파일을 비교하고 싶습니다 diff
.
이 두 파일을 만드는 방법은 다음과 같습니다.
"currenv" 파일 생성
$cat /proc/1/environ >> currenv $cat /pcoc/279/environ >> currenv $cat /proc/295/environ >> currenv //295 is the pid of the current console
orienv 파일 생성
$printenv > orienv
diff
그런 다음 다음과 같이 호출합니다 .
diff -u orienv currenv
다음과 같은 결과를 얻었습니다.
바이너리 orienv와 currenv가 다릅니다.
diff
플래그가 있는 정상적인 출력을 기대합니다 -u
(예: 차이점을 보여주는 출력).잘 생긴 남자, 다른 파일에는 없는 정보가 있는 파일을 나타냅니다.
무엇이 잘못되었나요?
답변1
환경 변수의 값에는 개행 문자가 포함될 수 있습니다. 에서 변수는 환경 변수의 값이나 이름에 나타날 수 없는 null 바이트로 구분됩니다. (이것은 우연이 아닙니다. 환경이 메모리에 표현되는 방식입니다.) diff가 널 바이트를 발견하면 파일이 바이너리라고 판단하고(정의에 따르면 텍스트 파일은 널 바이트를 포함하지 않음) 표시를 포기합니다. 차이점은 대부분의 바이너리 형식의 경우 diff 인쇄가 쓸모가 없기 때문입니다./proc/PID/environ
diff에게 계속해서 파일을 텍스트로 처리하라고 지시할 수 있지만 diff --text
, 두 파일 사이에서 이 작업을 수행하면 환경에 실제로 많은 개행 문자가 포함되어 있지 않기 때문에 크게 변경된 한두 줄만 표시될 수 있습니다. Diff는 개행으로 구분된 줄에서만 작동합니다. 의 내용과 출력 사이에 이 작업을 수행하면 줄 바꿈이 구분 기호로 사용되므로 모든 것이 변경되었음을 의미합니다./proc/PID/environ
/proc/PID/environ
printenv
printenv
유용한 출력을 얻으려면 널 바이트를 줄 바꿈으로 변환하십시오. 이렇게 하면 각 환경 변수가 줄의 시작 부분에서 시작됩니다.
diff -u orienv --label=currenv <(tr '\0' '\n' <currenv)
유용하고 명확한 출력을 위해 개행 문자도 널 바이트로 변환되어 각 환경 변수가 자체 단일 행에 표시됩니다. 그런 다음 diff 출력에 널 바이트가 있으면 원본 파일의 해당 위치에 개행 문자가 포함되어 있음을 나타냅니다.
diff -u --text --label=currenv <(tr '\0\n' '\n\0' <currenv1) --label=currenv <(tr '\0\n' '\n\0' <currenv2)
답변2
/proc/*/environ은 텍스트 파일이 아닙니다. 문자열을 사용하세요:
strings /proc/{1,279,295}/environ >> currenv
env > orienv
diff -u orienv currenv
답변3
문제는 /proc/<pid>/environ
널 바이트가 포함되어 있기 때문입니다. 로 텍스트로 표시되는 인쇄할 수 없는 바이트를 볼 수 있습니다 cat -v
. 예를 들어 ^@
아래 출력에서 null 바이트가 표시되는 것을 볼 수 있습니다.
$ cat -v /proc/20148/environ
CLUTTER_IM_MODULE=xim^@COLORFGBG=15;0^@COLORTERM=truecolor^@ ...cont.
그러나 환경 변수를 인쇄할 때 고려해야 할 세 가지 일반적인 문제가 있습니다.
- 이것ANSI 색상 이스케이프 코드 값텍스트 대신 "색상"으로 터미널에 인쇄됩니다(예
export p_red=$(tput setaf 1)
: . 이로 인해 diff가 원치 않는 색상을 출력하고 색상 코드 값도 손실됩니다.diff --color=always
또한 색상 중단으로 인해 예상대로 작동하지 않습니다. 함수 정의에는 종종 여러 줄이 포함됩니다.. 그리고 변수 값에는 여러 줄이 포함될 수도 있습니다. 예를 들어:
$ cat /etc/environment love=" 1st line 2nd line"
sort
먼저 비교하지 않으면 혼란스러운 결과가 나올 수 있습니다.
다음을 통해 이러한 모든 문제를 해결할 수 있습니다.
$ sudo cat /proc/1/environ | tr '\n\0' ' \n' | cat -v > currenv
$ sudo cat /proc/279/environ | tr '\n\0' ' \n' | cat -v >> currenv
$ sudo cat /proc/295/environ | tr '\n\0' ' \n' | cat -v >> currenv
$ sort -u currenv -o currenv
$ printenv -0 | tr '\n\0' ' \n' | cat -v | sort -u > orienv
$ diff --unified="$(cat currenv orienv | wc -l)" orienv currenv --color=always
출력은 다음과 같습니다:
...
LOGNAME=xiaobai
love= 1st line 2nd line
..
PKG_CONFIG_PATH=:/usr/lib/pkgconfig:/usr/local/lib/pkgconfig
p_lblue=^[[38;5;50m
p_lgreen=^[[38;5;118m
p_lred=^[[38;5;196m
p_orig=^[(B^[[m
p_red=^[[31m
PROFILEHOME=
...
QT_IM_MODULE=ibus
+recovery=
+rootmnt=/root
S_COLORS=auto
설명하다:
tr '\n\0' ' \n'
약어 형식을 나타냅니다tr '\n' ' ' | tr '\0' '\n'
. 먼저 개행 문자(예: 여러 줄 값)를\n
null로 바꾼' '
다음 null 바이트를\0
개행 문자로 바꿉니다'\n'
. 여러 줄 값을 먼저 공백으로 바꾸기 때문에 여러 줄 값이나 null 바이트의 모호성에 대해 걱정할 필요가 없습니다.printenv
-0
선택 할수있다각 출력 줄은 개행 문자가 아닌 NUL로 끝납니다.. 의 출력은printenv -0
와 동일하게 동작합니다/proc/<pid>/environ
. 그래서 우리도 같은 일을 할 수 있습니다tr '\n\0' ' \n'
.sort -u
>> currenv
동일한 변수를 반복해서 추가하여 차이를 확인하기 어렵게 만드는 것을 방지하려면 중복 행을 정렬하고 제거하세요 .cat currenv orienv | wc -l
가능한 모든 균일 값을 보려면 균일 값을 value로 설정합니다 .diff
이 도구는 실제로strtoumax()
값을 변환하기 위해 호출되므로 음수 값을 전달하면 쓰레기 값을 얻게 됩니다.cat -v
색상 코드를 인쇄 가능한 텍스트로 변환합니다. 이미 모든 null 바이트를 먼저 교체cat -v
했으므로 별도의 null 바이트 및 색상 코드가 필요한 것에 대해 걱정할 필요가 없습니다 .tr '\n\0' ' \n'
- 마지막으로
diff --color=always
색상 블록(녹색/빨간색/흰색)으로 차이점을 인쇄합니다.cat -v
색상 코드가 이미 변환되었으므로 색상 코드가 차등 색상을 깨뜨리는 것에 대해 걱정할 필요가 없습니다 .