전체 표준 입력을 문자 그대로 명령줄 인수로 변환하려면 어떻게 해야 합니까?

전체 표준 입력을 문자 그대로 명령줄 인수로 변환하려면 어떻게 해야 합니까?

1번 시도

xargs -I '{}' -0 -n 1 myprogram --arg '{}' --other-options

그러나 이것은 0바이트를 보존하지 않습니다. 프로그램은 여러 번 실행될 수도 있습니다. 그러나 표준 입력에 0바이트가 입력되어 실패하는 대신 프로그램을 여러 번 실행합니다.

2번 시도

myprogram --arg "`cat`" --other-options

그러나 이것은 후행 공백을 유지하지 않습니다.

3번 시도

bash -c 'read -r -d "" INPUT ; myprogram --arg "$INPUT" --other-options'

터미널을 엉망으로 만들고 후행 공백을 유지하지 못하는 것 같습니다.


이를 정확하고 안정적이며 읽기 쉽고 호환 가능하게 수행하는 방법은 무엇입니까?

답변1

명령줄 인수에서는 NUL 바이트를 사용할 수 없습니다., 그래서 질문은 이런 일이 발생하면 어떻게 되기를 원하는가입니다.표준 입력의 NUL 바이트입니다.

지적한 대로 이 경우 후보 솔루션 #1은 명령을 여러 번 실행하는 것입니다. 이는 이상적이지 않습니다. 그러나 실제 바이너리 입력을 처리할 수 있는 이상적인 솔루션은 없습니다. 다른 합리적인 옵션은 다음과 같습니다.

  • NUL 바이트를 제거하고 계속
    • 삽입하기 tr -d '\0' |전에xargs
  • NUL 바이트를 다른 바이트로 변환하고 계속
    • 삽입 tr '\0' something-else |xargs( something-else싱글 바이트인 경우)
  • NUL 바이트가 있으면 중단하고 보석합니다.

    • bash 또는 ksh93 사용(입력의 끝에 단일 null 바이트가 포함되어 있지 않은 경우 자동으로 삭제됨):

      { read -r -d '' input;
        if [ "$(wc -c)" = 0 ]; then
          printf %s "$input" | xargs …;
        else
          echo 1>&2 "Null bytes detected, bailing out"
          exit 2
        fi
      }
      
    • zsh 사용(bash, ksh 또는 dash와 같은 다른 셸을 사용하는 대신):

      input=$(<&0)
        if [[ $input != *$'\0'* ]]; then
          printf %s "$input" | xargs …;
        else
          echo 1>&2 "Null bytes detected, bailing out"
          exit 2
        fi
      
    • 아니면 임시 파일을 사용하세요.
  • 첫 번째 NUL 바이트 이후의 입력을 자릅니다.

    • 삽입하기 tr '\0\n' '\n\0' | head -n 1 | tr '\0\n' '\n\0'xargs( head널 안전하다고 가정)

관련 정보