我写了这段代码:
(require
'[org.httpkit.client :as http]
'[org.httpkit.fake :refer :all]
)
(with-fake-http ["localhost?q=hello" "hello param"]
(println @(http/get "localhost" :query-params {:q "hello"})))
出乎意料的是,命令echo在读取之前执行,在这种情况下,它显示一个空行,然后等待我输入文本。如果我想首先执行读取,有谁知道该怎么办?
答案 0 :(得分:2)
管道是两个进程(作者和读者)之间的通信通道。作者和读者可以同时执行,只需要相互依赖于写/读关系。
对于管道做任何有用的事情,编写器(左边的命令)需要输出一些东西到它的标准输出(stdout),而阅读器(右边的命令)需要从它的标准输入读取(标准输入)。如果读者实际上没有尝试从stdin读取,它将不会阻塞并且将在不等待作者做任何事情的情况下执行。
管道是一种操作系统机制,它将编写器的标准输出与读取器的标准输入连接起来,程序员不得不打扰任何有关文件描述符,同步和其他无聊和棘手的细节。细节。这很棒,但是如果你不明白场景背后会发生什么,它可能会产生你会认为令人惊讶的结果(但不是)。
在您的情况下,read
命令不向stdout输出任何内容(它指定变量NAME
),echo
命令不会从stdin读取任何内容。由于echo
没有读取任何内容,因此无需等待任何内容即可执行,因此您可以立即看到echo
的输出。但是,read
命令需要等待来自其自己的stdin的输入(与管道无关,因为管道只关注来自read
的stdout); read
将stdin连接到终端,因此它等待键盘输入。
换句话说,你的命令是并行执行的,根本不相互通信。
请记住,管道中的两个命令都会尽可能同时执行。一个实际上没有读过的读者不会为其作者而烦恼,反之亦然。
答案 1 :(得分:0)
|
的方式,你告诉bash发送' read'的输出。成为回声'的输入。因为'阅读'没有输出,echo没有输入,bash执行以下操作:
根据您的描述,我认为您可能需要更多类似的内容:
read NAME ; echo "$NAME"
;
就像是说第一个命令"然后" 第二个命令。 $ read foo ; echo $foo
与以下内容相同:
$ read foo
$ echo $foo
同样,正如Hunter McMillen和iamauser所指出的,&&
基本上会得到相同的结果。但是,&&
告诉bash只有在前面的命令成功后执行命令,而;
是无条件的 - 它将执行,无论前面的命令是否成功。另一种有条件的方法是使用||
,它类似于"或"声明意味着只有在前面的命令是UN-successful的情况下才会执行以下命令。