나는 이것으로 빙글 빙글 갔다. null 바이트의 이식성에 좌절했습니다. 쉘에서 처리 할 수있는 확실한 방법이 없다는 것은 나와 함께 잘 앉아 있지 않았습니다. 그래서 나는 계속 찾고 있었다. 진실은 내가 이것을 할 수있는 몇 가지 방법을 찾았다는 것인데, 그중 두 가지만이 내 대답에 나와 있습니다. 그러나 결과는 다음과 같이 작동하는 적어도 두 개의 쉘 함수였습니다.
_pidenv ${psrc=$$} ; _zedlmt <$near_any_type_of_file
먼저 \0
구분 에 대해 이야기하겠습니다 . 실제로는 매우 쉽습니다. 기능은 다음과 같습니다.
_zedlmt() { od -t x1 -w1 -v | sed -n '
/.* \(..\)$/s//\1/
/00/!{H;b};s///
x;s/\n/\\x/gp;x;h'
}
기본적 od
얻어 stdin
그 쓰는 stdout
각 바이트가 라인 당 진수 한 수신한다.
printf 'This\0is\0a\0lot\0\of\0\nulls.' |
od -t x1 -w1 -v
#output
0000000 54
0000001 68
0000002 69
0000003 73
0000004 00
0000005 69
0000006 73
#and so on
나는 당신이 어느 것을 추측 할 수 있습니다 내기 \0null
? 이 취급이 용이하다는처럼 서면 어느 sed
. sed
중간 줄 바꿈을 printf
친숙한 형식 코드로 바꾸고 문자열을 인쇄 하는 null이 발생할 때까지 각 줄의 마지막 두 문자를 저장 합니다. 결과는 \0null
구분 된 16 진 바이트 문자열 배열입니다. 보기:
printf %b\\n $(printf 'Fewer\0nulls\0here\0.' |
_zedlmt | tee /dev/stderr)
#output
\x46\x65\x77\x65\x72
\x6e\x75\x6c\x6c\x73
\x68\x65\x72\x65
\x2e
Fewer
nulls
here
.
위의 내용을 파이프하여 tee
명령 susbstitution의 출력과 printf
의 처리 결과를 모두 볼 수 있습니다 . 서브 쉘이 실제로 인용되지 않았지만 printf
여전히 \0null
구분 기호 로만 분할 되었음을 알 수 있기를 바랍니다 . 보기:
printf %b\\n $(printf \
"Fe\n\"w\"er\0'nu\t'll\\'s\0h ere\0." |
_zedlmt | tee /dev/stderr)
#output
\x46\x65\x0a\x22\x77\x22\x65\x72
\x27\x6e\x75\x09\x27\x6c\x6c\x27\x73
\x68\x20\x20\x20\x20\x65\x72\x65
\x2e
Fe
"w"er
'nu 'll's
h ere
.
해당 확장에 대한 인용문도 없습니다-인용 여부는 중요하지 않습니다. 문자열을 인쇄 할 \n
때마다 생성 된 하나의 ewline을 제외하고는 바이트 값이 분리되지 않기 때문 sed
입니다. 단어 분리는 적용되지 않습니다. 그리고 이것이 가능해집니다.
_pidenv() { ps -p $1 >/dev/null 2>&1 &&
[ -z "${1#"$psrc"}" ] && . /dev/fd/3 ||
cat <&3 ; unset psrc pcat
} 3<<STATE
$( [ -z "${1#${pcat=$psrc}}" ] &&
pcat='$(printf %%b "%s")' || pcat="%b"
xeq="$(printf '\\x%x' "'=")"
for x in $( _zedlmt </proc/$1/environ ) ; do
printf "%b=$pcat\n" "${x%%"$xeq"*}" "${x#*"$xeq"}"
done)
#END
STATE
상기 기능을 사용하는 _zedlmt
하나에 ${pcat}
발견 될 수있는 임의의 프로세스 환경 소싱 바이트 코드의 준비된 스트림 /proc
, 또는 직접 .dot
${psrc}
전류 셸 동일하거나 파라미터없이 같은 단말에 동일의 처리 결과를 표시하도록 set
또는 printenv
의지. 모두 당신이 필요하다 $pid
- 어떤 읽을 수있는 /proc/$pid/environ
파일을 할 것입니다.
다음과 같이 사용하십시오.
#output like printenv for any running process
_pidenv $pid
#save human friendly env file
_pidenv $pid >/preparsed/env/file
#save unparsed file for sourcing at any time
_pidenv ${pcat=$pid} >/sourcable/env.save
#.dot source any pid's $env from any file stream
_pidenv ${pcat=$pid} | sh -c '. /dev/stdin'
#feed any pid's env in on a heredoc filedescriptor
su -c '. /dev/fd/4' 4<<ENV
$( _pidenv ${pcat=$pid} )
ENV
#.dot sources any $pid's $env in the current shell
_pidenv ${psrc=$pid}
그러나 인간 친화적 이고 소싱 가능한 것의 차이점은 무엇 입니까? 글쎄, 차이점은이 답변을 여기의 다른 답변과 다르게 만드는 것입니다. 다른 모든 답변은 어떤 방식 으로든 쉘 인용에 의존하여 모든 엣지 케이스를 처리합니다. 그것은 단순히 잘 작동하지 않습니다. 믿어주세요-시험 을 보았습니다. 보기:
_pidenv ${pcat=$$}
#output
LC_COLLATE=$(printf %b "\x43")
GREP_COLOR=$(printf %b "\x33\x37\x3b\x34\x35")
GREP_OPTIONS=$(printf %b "\x2d\x2d\x63\x6f\x6c\x6f\x72\x3d\x61\x75\x74\x6f")
LESS_TERMCAP_mb=$(printf %b "\x1b\x5b\x30\x31\x3b\x33\x31\x6d")
LESS_TERMCAP_md=$(printf %b "\x1b\x5b\x30\x31\x3b\x33\x31\x6d")
LESS_TERMCAP_me=$(printf %b "\x1b\x5b\x30\x6d")
LESS_TERMCAP_se=$(printf %b "\x1b\x5b\x30\x6d")
LESS_TERMCAP_so=$(printf %b "\x1b\x5b\x30\x30\x3b\x34\x37\x3b\x33\x30\x6d")
LESS_TERMCAP_ue=$(printf %b "\x1b\x5b\x30\x6d")
NO 펑키 문자의 양 또는 각 값에 대한 바이트 내용이 소스로 매우 순간까지 평가되지 않기 때문에이 손상 될 수 있습니다 인용하지 포함되어 있습니다. 그리고 우리는 이미 적어도 한 번은 값으로 작동한다는 것을 알고 있습니다. 이것은 원래 값의 바이트 단위 복사본이므로 구문 분석 또는 인용 보호가 필요하지 않습니다.
이 함수는 먼저 $var
이름을 평가하고 .dot
파일 설명자 3에 공급 된 here-doc을 소싱 하기 전에 검사가 완료 될 때까지 기다립니다 . 바보입니다. 그리고 POSIX 휴대용. 적어도 \ 0null 처리는 POSIX 이식 가능합니다. / process 파일 시스템은 분명히 Linux에 따라 다릅니다. 이것이 두 가지 기능이있는 이유입니다.
. <(xargs -0 bash -c 'printf "export %q\n" "$@"' -- < /proc/nnn/environ)
따옴표가있는 변수도 올바르게 처리하는 것이 좋습니다 .