STDOUT + STDERR 输出...将输出视为空字符串与 NULL 之间有什么区别

STDOUT + STDERR 输出...将输出视为空字符串与 NULL 之间有什么区别

我正在编写一些用于执行 Linux shell 命令的应用程序代码,然后它将命令详细信息记录到 SQL 数据库中。这包括 STDOUT + STDERR 的输出(单独)。

执行命令后,假设进程没有输出任何内容...是否有任何理由将 STDOUT/STDERR 字段保留为 NULL -vs- 将它们设置为空字符串?

换句话说:这两件事在技术上有什么区别吗?

  • 不向 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(1 表示 stdout,2 表示 stderr)。例如,在echo test, echo(或 shell,如果echo是内置的)中执行write(1, "test\n", 5).

不过,这有点傻,你可以用write()长度为 0 来调用系统调用。

和:

write(1, address, 0)

至少在Linux上,系统调用仍然检查文件描述符是否已以写或读+写模式打开,并且该地址是否是有效地址(尽管它不必是可读的)。如果 stdout 是一个损坏的管道,我认为它不会导致 SIGPIPE 信号传递。

因此,执行大小为零并不严格等同于根本不执行任何写入,因为它可能会导致错误。

在实践中,我发现大多数命令都会避免使用“write()如果可以”。

我发现这一点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

相关内容