이 문서에서 null 문자를 어떻게 이스케이프할 수 있나요? (배시 및/또는 대시)

이 문서에서 null 문자를 어떻게 이스케이프할 수 있나요? (배시 및/또는 대시)

shuf --zero-terminated여기 문서를 사용하여 여러 줄 문자열에 대한 작업을 수행 하고 싶습니다 .

답변1

Bash 및 dash의 여기 문서는 이를 지원하지 않습니다. 널은 변수에 저장할 수 없고, 명령 대체에서 제거되며, 널을 문자 그대로 쓸 수 없으며, 이 문서에서는 ANSI-C 인용문을 사용할 수 없습니다. 두 쉘 모두 널 친화적이지 않으며 입력되면 일반적으로 (C 스타일) 문자열 종결자로 처리됩니다.

여러 가지 옵션이 있습니다:실제 파일 사용, zsh 사용, 프로세스 대체 사용 또는 표준 입력 사용.


할 수 있는null 친화적인 zsh에서 원하는 작업을 정확하게 수행하세요.

zsh% null=$(printf '\x00')
zsh% hexdump -C <<EOT
heredoc> a${null}b${null}
heredoc> EOT
00000000  61 00 62 00 0a                                    |a.b..|
00000005

shufheredocs에는 암시적으로 종료되는 개행 문자가 있지만 이는 이상적이지 않을 수 있습니다( 최종 null 값 뒤에 추가 필드가 됩니다 ).


Bash의 경우 다음을 사용할 수 있습니다.프로세스 교체null 값을 인라인으로 결합 printf하거나 생성하는 heredoc과 거의 동일합니다 .echo -e

bash$ hexdump -C < <(
printf 'item 1\x00item\n2\x00'
)
00000000  69 74 65 6d 20 31 00 69  74 65 6d 0a 32 00        |item 1.item.2.|
0000000e

이러한 파일은 종종 쉘에 의해 실제 파일에 비밀리에 저장되기 때문에 이것이 반드시 여기에 있는 문서와 정확히 동일하지는 않습니다(검색 가능성 등에 중요함).

종료되는 개행 문자를 억제하고 싶을 수도 있으므로 명령 내에서 heredoc을 사용할 수도 없습니다. printf/ echo -ne출력을 세밀하게 제어하는 ​​것이 안전해야 합니다.


대시에서는 프로세스 대체를 수행할 수 없지만 모든 셸에서는 하위 셸에서 표준 입력을 파이프할 수 있습니다.

dash$ (
printf 'item 1\x00'
printf 'item\n2\x00'
) | hexdump -C
00000000  69 74 65 6d 20 31 00 69  74 65 6d 0a 32 00        |item 1.item.2.|
0000000e

shuf기본값은 표준 입력에서 읽는 것이 좋습니다. 따라서 제가 이해한 바로는 이것이 귀하의 특정 사용 사례에 적합할 것입니다. 더 복잡한 명령이 있는 경우 파이프 오른쪽에 있으면 범위 지정과 관련하여 혼란스러운 요소가 발생할 수 있습니다.


printf마지막으로, 이 파일을 사용하여 여기에 설명된 내용 대신 실제 파일에 데이터를 쓸 수 있습니다 . 이 옵션은 다음에 포함되어 있습니다.또 다른 대답. 나중에 파일을 정리하고 싶을 수도 있습니다.mktemp또는 이와 유사한 것(실시간 보안 문제가 있는 경우)을 사용하여 안전한 파일 이름을 만들 수 있습니다.

답변2

다들 감사 해요. 여러분 모두가 가지고 있는 것을 바탕으로 답변을 게시하겠습니다. 아마도 그것이 나에게 가장 좋을 것입니다.

스크립트는 bash 및 dash에서 잘 실행되며 실제 파일이나 파일이 필요하지 않습니다.Bash에서 프로세스 교체%s, 추가로 느린 외부 프로그램 호출이 필요하지 않으며 다음과 같은 엔터티의 이스케이프 문제에 대해 걱정할 필요도 없습니다.인쇄물,하지만 여전히 셸 자체에서 문자열 이스케이프에 주의를 기울여야 합니다..

#!/bin/sh
printf '%s\0' "[tag1]
key1=value1
key2=value2
[/tag1]
" "[tag2]
key3=value3
key4=value4
[/tag2]
" | shuf --zero-terminated
#also see man printf(1)

~을 위한shuf만(여기의 일반 문서를 대체할 의도는 없음):

shuf --echo "[tag1]
key1=value1
key2=value2
[/tag1]" "[tag2]
key3=value3
key4=value4
[/tag2]"

답변3

나는 heredoc에서 당신이 원하는 것을 할 수 없다고 생각합니다. 그러나 echo다음 예와 같이 사용이 간단합니다 .

$ cat demo
#!/bin/bash

echo -ne "one\0" > outfile
echo -ne "two\0" >> outfile
echo -ne "three\0" >> outfile

$ ./demo
$ od -a outfile
0000000   o   n   e nul   t   w   o nul   t   h   r   e   e nul
0000016
$ 

답변4

나는 결국 "트릭"을 사용하게 되었다

cat <<EOS | cat - <(echo -e "\0") | most
{
  "version":"1.1",
  "gelf-toekn":"SOMETHIN",
  "host": "api.ivsdev.net",
  "short_message": "foo",
   "full_message": "bar",
   "level": 1
}
EOS

첫 번째 구분 기호 cat은 두 번째 구분 기호 cat으로 파이프되어 null 바이트와 연결됩니다.

관련 정보