STDOUT + STDERR 출력... 출력을 빈 문자열로 처리하는 것과 NULL로 처리하는 것의 차이점은 무엇입니까?

STDOUT + STDERR 출력... 출력을 빈 문자열로 처리하는 것과 NULL로 처리하는 것의 차이점은 무엇입니까?

저는 Linux 셸 명령을 실행한 다음 명령 세부 정보를 SQL 데이터베이스에 기록하는 일부 애플리케이션 코드를 작성 중입니다. 여기에는 STDOUT + STDERR(별도)의 출력이 포함됩니다.

명령을 실행한 후 프로세스가 아무것도 출력하지 않는다고 가정하면... STDOUT/STDERR 필드를 NULL로 남겨두고 빈 문자열로 설정하는 이유가 있습니까?

즉, 이 두 가지 사이에 기술적 차이가 있습니까?

  • STDOUT에 아무것도 출력하지 않는 프로세스
  • STDOUT에 빈 문자열(그 이상은 없음)을 출력하는 프로세스

다시 다른 방법으로 질문해 보겠습니다. SQL에서 이러한 열을 NOT NULL로 만드는 것이 합리적입니까?

답변1

파이프(std-err/out)에는 빈 문자열이라는 개념이 없으며 단지 "출력 없음"일 뿐입니다.

> printf '' 
> printf '' | xxd

null은 무엇입니까?

> printf '\0'
> printf '\0' | xxd
00000000: 00

데이터베이스에서는 그 반대가 사실이고, 적을수록 많으므로 스크립트를 자동으로 만들고(빈 문자열) 데이터베이스를 빈(비어 있음)로 설정하십시오.

답변2

질문을 이해했는지 잘 모르겠지만:

표준 출력에 쓰기가 실행 중입니다.

write(1, memory_address, length)

메모리 주소에 저장된 길이 바이트를 파일 설명자 1(stdout의 경우 1, stderr의 경우 2)에 씁니다. 예를 들어, in echo test, echo(또는 echo내장된 경우 shell) 을 실행합니다 write(1, "test\n", 5).

그러나 이것은 약간 어리석은 일입니다. write()길이가 0인 시스템 호출을 호출할 수 있습니다.

그리고:

write(1, address, 0)

적어도 Linux에서는 시스템 호출이 파일 설명자가 쓰기 또는 읽기+쓰기 모드로 열렸는지, 주소가 유효한 주소인지(읽을 수 있을 필요는 없지만) 확인합니다. stdout이 손상된 파이프인 경우 SIGPIPE 신호가 전달되지 않을 것이라고 생각합니다.

따라서 크기 0을 수행하는 것은 쓰기를 전혀 수행하지 않는 것과 엄격하게 동일하지 않습니다. 오류가 발생할 수 있기 때문입니다.

실제로 대부분의 명령은 " write()if can"을 사용하지 않는 것으로 나타났습니다.

나는 이것을 발견했고 echo -n내가 시도한 어떤 구현에서도 printf ''시스템 호출을 하지 않습니다 . write()stdio 함수( fputs()// ... printf()빈 문자열을 쓰도록 요청하면 fwrite()아무 작업도 수행하지 않습니다 .)write()

0 길이 쓰기를 수행하려면 다음을 시도해 보십시오.

perl -e 'syswrite(STDOUT, "")'

또는

python -c 'import os; os.write(1, "")'

이러한 인터프리터의 원래 인터페이스는 write().

예:

$ strace -e write /bin/echo -n
$ strace -e write python -c 'import os; os.write(1, "")'
write(1, "", 0)                         = 0
$ python -c 'import os; os.write(1, "")' >&-
Traceback (most recent call last):
  File "<string>", line 1, in <module>
OSError: [Errno 9] Bad file descriptor
$ python -c 'import os; os.write(1, "")' 1< /dev/null
Traceback (most recent call last):
  File "<string>", line 1, in <module>
OSError: [Errno 9] Bad file descriptor
$ printf '%s\n' '#include <unistd.h>' 'main(){write(1,(char*)-1,0);}' | strace -e write tcc -run -
write(1, "", 0)                         = -1 EFAULT (Bad address)
$ printf '%s\n' '#include <unistd.h>' 'main(){write(1,(char*)0,1);}' | strace -e write tcc -run -
write(1, NULL, 1)                       = -1 EFAULT (Bad address)
$ printf '%s\n' '#include <unistd.h>' 'main(){write(1,(char*)0,0);}' | strace -e write tcc -run -
write(1, NULL, 0)                       = 0

관련 정보