以下是Bash进程替换的示例:
zjhui@ubuntu:~/Desktop$ echo >(ls)
/dev/fd/63
zjhui@ubuntu:~/Desktop$ abs-guide.pdf
Run Code Online (Sandbox Code Playgroud)
然后我得到一个光标等待命令.
/dev/fd/63不存在.我想会发生的是:
/dev/fdlsin>(ls)这是正确的吗?为什么有光标等待输入?
我正在努力理解过程替换。据我所知,
echo abcd | tr -d 'b'
tr -d 'b' <(echo abcd)
Run Code Online (Sandbox Code Playgroud)
应该都给出相同的输出。但是第一个有效(输出为“acd”)但第二个说
tr: extra operand '/dev/fd/63'
Run Code Online (Sandbox Code Playgroud)
为什么是这样?tr 不只是通过管道接收 'abcd' 而不是 '/dev/fd/63' 吗?
我试图在while循环中使用进程替换的stdout,如下所示:
#!/bin/bash
FILE_1=f1.txt
FILE_2=f2.txt
while read LINE; do
echo "$LINE"
done < <(paste <(tail -f "$FILE_1") <(tail -f "$FILE_2"))
Run Code Online (Sandbox Code Playgroud)
它应该做的是每当将新数据添加到文件时合并FILE_1和FILE_2的最后几行.显然,我想做的不仅仅是在while循环中打印行,但这是一个很好的例子.
不幸的是,当我运行这个脚本时,它只是位于终端并且什么都不做.
只运行这一行:
paste <(tail -f "$FILE_1") <(tail -f "$FILE_2")
Run Code Online (Sandbox Code Playgroud)
工作得很好,我可以看到终端上的输出,因为我将数据添加到文件中.
我需要使用一些特殊的语法来将stdout传递给另一个进程吗?
我试过了
paste <(tail -f "$FILE_1") <(tail -f "$FILE_2") | while read LINE; do...
Run Code Online (Sandbox Code Playgroud)
但它仍然只是坐在终端.
我tee在tee信息页面中找到了一个使用实用程序的示例:
wget -O - http://example.com/dvd.iso | tee >(sha1sum > dvd.sha1) > dvd.iso
Run Code Online (Sandbox Code Playgroud)
我查了一下>(...)语法,找到了一个叫做"进程替换"的东西.根据我的理解,它使一个进程看起来像另一个进程可以写入/附加其输出的文件.(如果我在这一点上错了,请纠正我.)
这与管道有什么不同?(|)我看到上面的例子中正在使用管道 - 它只是一个优先问题吗?或者还有其他一些区别吗?
我正在编写一个屏障来阻止脚本的执行,直到记录某个关键字为止。该脚本非常简单:
tail -F -n0 logfile.log | while read LINE; do
[[ "$LINE" == *'STOP'* ]] && echo ${LINE} && break;
done
Run Code Online (Sandbox Code Playgroud)
或者
tail -F -n0 logfile.log | grep -m1 STOP
Run Code Online (Sandbox Code Playgroud)
问题是它不会在检测到关键字后立即退出,而是仅在写入下一行后才退出。IE:
printf "foo\n" >> logfile.log # keeps reading
printf "foo\n" >> logfile.log # keeps reading
printf "STOP\n" >> logfile.log # STOP printed
printf "foo\n" >> logfile.log # code exits at last
Run Code Online (Sandbox Code Playgroud)
不幸的是,我不能依赖这样一个事实:在“STOP”之后将记录另一行(至少不在对我的目的有用的间隔内)。
到目前为止找到的解决方法是tail另一个我确信会经常更新的文件,但是“干净”的解决方案是什么,以便代码在记录STOP后立即退出?
我在 Bash 脚本中偶然发现了一些奇怪的 heredoc 用法。一个简化的例子是这样的:
do_stuff() {
notify @<(cat <<- EOF
{
"key": "value",
<more JSON data>
}
EOF
)
}
Run Code Online (Sandbox Code Playgroud)
什么是@<(cat <<- EOF部分呢?它与常规的heredoc有什么不同?
在阅读了关于exec builtin如何在bash中工作的解释之后,我理解它的基本功能是在不分叉的情况下替换当前进程.它似乎也用于在当前进程中重定向I/O和关闭文件描述符,这让我感到困惑.这是一些无关的额外的事情exec吗?能否在"取代现有流程"的背景下理解?如果与流程替换相结合,它是如何工作的,例如exec 3< <(my program)?
bash 如何等待进程替换中使用的子 shell 在以下构造中完成?(这当然是从我正在使用的真实 for 循环和子 shell 简化而来的,但它很好地说明了意图。)
for i in {1..3}; do
echo "$i"
done > >(xargs -n1 bash -c 'sleep 1; echo "Subshell: $0"')
echo "Finished"
Run Code Online (Sandbox Code Playgroud)
印刷:
Finished
Subshell: 1
Subshell: 2
Subshell: 3
Run Code Online (Sandbox Code Playgroud)
代替:
Subshell: 1
Subshell: 2
Subshell: 3
Finished
Run Code Online (Sandbox Code Playgroud)
如何让 bash 等待这些子 shell 完成?
更新
使用进程替换的原因是我想使用文件描述符来控制打印到屏幕的内容以及发送到进程的内容。这是我正在做的事情的完整版本:
for myFile in file1 file2 file3; do
echo "Downloading $myFile" # Should print to terminal
scp -q $user@$host:$myFile ./ # Might take a long time
echo "$myFile" >&3 # …Run Code Online (Sandbox Code Playgroud) 我想运行这个脚本:
#!/bin/bash
echo <(true)
Run Code Online (Sandbox Code Playgroud)
我把它当作:
sh file.sh
Run Code Online (Sandbox Code Playgroud)
我得到了" Syntax error: "(" unexpected".我发现了一些类似的情况,但仍然无法解决这个问题.我是shell脚本的初学者,但据我了解:
echo $0一下它给了我" bash",那么在命令行和调用同一个shell的脚本中运行命令有什么不同?也许这很简单,但我找不到解释或解决方案.
我想知道如何在此站点https://shapeshed.com/unix-join/ 的示例中使用重定向
这是输入
$ cat wine.txt
White Reisling Germany
Red Riocha Spain
Red Beaunes France
$ cat reviews.txt
Riocha Meh
Beaunes Great!
Reisling Terrible!
Run Code Online (Sandbox Code Playgroud)
这是命令和结果
$ join -1 2 -2 1 <(sort -k 2 wine.txt) <(sort reviews.txt)
Beaunes Red France Great!
Reisling White Germany Terrible!
Riocha Red Spain Meh
Run Code Online (Sandbox Code Playgroud)
但在这种情况下,双重使用 < 不起作用
$ cat file 1
Hello
$ cat file 2
World
Run Code Online (Sandbox Code Playgroud)
我预计
$ cat <file1 <file2
Hello World
Run Code Online (Sandbox Code Playgroud)
但结果是
World
Run Code Online (Sandbox Code Playgroud)
你们有什么想法吗?
我想从vim使用bash进程替换,我该怎么做?我需要输入类似的东西:
:tabe `<(git show mybranch:mydir/myfile.txt)`
Run Code Online (Sandbox Code Playgroud)
该特定形式无效.如何让vim git show mybranch:mydir/myfile.txt在新选项卡中打开命令输出.
我有以下命令...
/bin/bash -c 'diff <(sort text2) <(sort text1)'
Run Code Online (Sandbox Code Playgroud)
它对每个文件进行排序并将它们通过管道传输到 diff 函数中。如果/bin/bash存在,这很有效。但是,我使用的系统只有/bin/sh. 我正在努力为此找到等效的命令。
如果我跑...
/bin/sh -c 'diff <(sort text2) <(sort text1)'
Run Code Online (Sandbox Code Playgroud)
我会得到...
/bin/sh: 语法错误:意外的“(”