STDOUT + STDERR出力...出力を空の文字列として扱うこととNULLとして扱うことの違いは何ですか?

STDOUT + STDERR出力...出力を空の文字列として扱うこととNULLとして扱うことの違いは何ですか?

私はLinuxシェルコマンドを実行し、コマンドの詳細をSQLデータベースに書き込むいくつかのアプリケーションコードを書いています。これには、STDOUT + STDERR(別途)の出力が含まれます。

コマンドの実行後にプロセスが何も出力しないと仮定すると、STDOUT / STDERRフィールドをNULLにして空の文字列に設定する理由はありますか?

つまり、これら2つの間に技術的な違いはありますか?

  • 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 testechoまたはecho組み込みの場合はシェルを実行します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

関連情報