我是 Unix 新手,试图了解管道的工作原理。我以为我明白了,所以我尝试了以下示例,但没有成功:
(base) MacBook-Pro:Code usr$ echo "file.txt ~/.Trash" | mv
usage: mv [-f | -i | -n] [-v] source target
mv [-f | -i | -n] [-v] source ... directory
我想知道出了什么问题。
谢谢,丹尼尔
答案1
A管道连接标准输出左侧进程的标准输入到右侧进程的标准输入。echo "file.txt ~/.Trash"
写入file.txt ~/.Trash
其标准输出,管道使该字符串可供mv
读取。
然而,mv
此时不从标准输入读取:正如您引用的错误消息所暗示的那样,它相反期望接收至少两个命令行参数(一个source
和一个target
或一个或多个source
s 和一个)directory
。它抱怨看不到任何和
(请注意,即使mv
您按照要求的方式调用它,也不会读取其标准输入,例如运行echo foo | mv source dest
。它仅在需要与用户交互时使用标准输入,例如提示确认时)。
事实上,并非每个程序都从标准输入读取。部分程序中标准流的使用在其man
实际页面中进行了解释。那些POSIX 实用程序有专门的“STDIN”、“STDOUT”和“STDERR”部分,而其他版本的组织不太正式,可能需要完整阅读。
没有规则规定程序应如何使用标准流。正如对问题的回答中所述提议的重复目标,主要和程序的语义有关。简化一点,处理数据流的程序倾向于使用其标准输入/输出,而处理操作系统对象(文件、目录、进程、用户...)的程序则倾向于仅采用命令行参数。
最后谈到您的问题似乎提出的具体问题:只有从标准输入读取的 *nix 实用程序的一个子集使用它来读取命令。从广义上讲,只有那些解释器:主要是 shell(标准sh
, bash
, zsh
...)和面向文本处理的实用程序(尽管不限于文本处理;例如awk
, grep
, sed
...),但也有计算器(bc
)当然还有其他一些我现在无法想到的。
由于大多数旨在管理 *nix 系统的工具,mv
并不是为了将字符串解析为不同的元素而设计的。在通常的任务划分中,这个角色是 shell 的角色,它反过来调用工具来根据参数mv
执行特定的操作(基于),这些参数的单独含义已明确定义(并且通常由文档明确说明,如 中)。mv [-f | -i | -n] [-v] source target
为了说明这一点:虽然您无法mv
通过标准输入告诉要做什么,并且需要键入mv foo bar
,但您能做echo "mv foo bar" | sh
。如果解释器没有接收到文件参数,它sh
就会从标准输入读取命令,负责解析它并mv
使用两个参数foo
和进行调用bar
。