非常新手的问题,我三天前开始使用 Linux,所以请耐心等待 :)
我不太理解许多 shell 命令返回的数据的结构。让我更好地解释一下:
每当我运行诸如 之类的命令时ls
,究竟返回了什么?我所说的返回,不是指屏幕上打印的内容,而是指内存中的内容。ls
例如,我可以使用从 返回的输出吗?或者这个命令是否返回null
并仅在屏幕上打印内容?我如何检查返回的数据?
更一般地说,我可以在哪里检查每个命令返回什么?
谢谢你!
答案1
所见即所得,确实如此。运行后打印的所有内容ls
都是由“ls”命令本身打印的——不必须重新格式化的中间返回值。
Shell 命令与编程语言中的函数并不完全相同 - 它们只能返回一个整数:“退出状态”。大多数 Shell 允许通过变量检查此值$?
。(惯例是成功时返回 0;失败时返回 1 或更大。)
因此,您看到的所有输出都不是通过返回值产生的,而是通过将普通文本写入名为“stdout”和“stderr”的特殊文件产生的。期间命令的执行(前者用于常规输出,后者用于通知和错误消息)。
当然,里面在 ls 程序中,你会发现对 libc 函数的调用,例如 readdir() 返回struct dirent
,或 stat() 返回struct stat
。然而,这些都不会返回到外部世界。
那么,您可以使用 ls 的输出吗?从某种意义上说,是的,事实上,许多传统的“Unix”用户界面都是建立在将一个程序的输出用作另一个程序的输入这一理念之上的——这就是管道运算符|
的用途。但是,请记住,ls 的输出是专门为人类使用而格式化的,并且不是很容易被机器解析。换句话说,你不应该即使可以,也在脚本中使用“ls”的输出。
(当初始程序实际上是为了产生某种结构化的输出而编写时,管道工作效果最好。因此,许多工具实际上可以运行,并带有输出漂亮格式的文本的选项或者机器可解析的文本。比较lsblk
vs lsblk --raw
vs lsblk --json
。)
也有例外——有些 shell 尝试支持灵活的返回类型,但 PowerShell 是唯一广为人知的例子。PowerShell cmdlet 可以返回任意 .NET 运行时类型。