Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/bash/16.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Bash 从长时间运行的流程到xargs的管道传输没有任何效果_Bash_Xargs_Gollum Wiki - Fatal编程技术网

Bash 从长时间运行的流程到xargs的管道传输没有任何效果

Bash 从长时间运行的流程到xargs的管道传输没有任何效果,bash,xargs,gollum-wiki,Bash,Xargs,Gollum Wiki,在bash中,我想启动我的程序(gollum),并使用stderr的一部分(端口号)作为另一个程序的参数。我将stderr重定向到stdout,并使用grep和sed过滤输出。我在stdout中得到结果: gollum -p0 2>&1| sed -n -e "s/.*port=//p" 它返回'56343'并继续运行,因为咕噜是一台服务器 但是,如果我想将其用作另一个带有xargs的程序的参数(即echo,但我想稍后使用它来启动具有端口号的internet navigato

在bash中,我想启动我的程序(gollum),并使用stderr的一部分(端口号)作为另一个程序的参数。我将stderr重定向到stdout,并使用grep和sed过滤输出。我在stdout中得到结果:

gollum -p0 2>&1|  sed  -n -e "s/.*port=//p"
它返回'56343'并继续运行,因为咕噜是一台服务器

但是,如果我想将其用作另一个带有xargs的程序的参数(即echo,但我想稍后使用它来启动具有端口号的internet navigator),它将不起作用

gollum -p0 2>&1|  sed  -n -e "s/.*port=//p" | xargs -n1  echo  
什么也没发生。你知道为什么吗,或者你有没有其他想法来做同样的事情


谢谢您的帮助。

如果您不想让服务器在后台继续运行,这很容易做到。如果需要,一种方法是使用流程替换:

#!/bin/bash
#      ^^^^- not /bin/sh; needed for >(...) syntax

gollum -p0 > >(
  while IFS= read -r line; do
    # start a web browser here, etc.
    [[ $line = *"port="* ]] && echo "${line##*port=}"
    # ...for instance, could also be:
    # open "http://localhost:${line##*port=}/"
  done
) 2>&1 &

…如果您只想读取包含
端口=
的第一行,那么
从处理程序的循环中断开,并在stdin退出之前处理其余的stdin(这与使用
cat>/dev/null
一样简单)。

问题在于Bash等待管道中的所有子级死亡,而
golum
不会死亡(一个戒指让他活下来)?事实上这是因为咕噜没有死。我从其他地方杀人,它就工作了。我怎样才能让我的第二个程序在端口号返回后立即工作?如果
咕噜
没有选择在“守护进程”模式下运行,那么
(咕噜-p02>&1&)|sed…| xargs…
假设您必须使用
xargs
(…)
的子shell不会等待
golum
死亡。但是,您可能仍然对
sed
不死亡有问题;也许您会使用
sed-n-e'/port=/{s/*port=//p;q;}“
在第一条端口线之后停止。我认为您需要两种诡计:运行
gollum
的过程和分析输出的
sed
。太好了。请查看可用的选项-您不可能是唯一需要端口号的人,因此可能有办法找到我注意到有一个
--port=4567
选项(这是默认的端口号);如果指定
-p4567
而不是
-p0
,它可能会在该端口上启动。这样,您就可以绕过所有问题;您可以告诉它该做什么,而不是试图让它告诉您它在做什么。顺便说一句,如果这是Linux,您可以使用更多的选项来检测实例正在使用的端口,而不是读取其输出——例如,您可以直接在procfs中查看它的文件描述符列表(或者使用一个工具,例如
lsof
),这样您就不会取消错误,也不会依赖于为人类消费而构建的日志格式(这可能会随新版本而改变,或者取决于当前的语言/本地化/语言环境设置!)。谢谢,它可能会起作用,但我希望更简单一些。就易读性而言,“简单”与“简单”之间的区别在于具有非常明确的行为。通常,在bash中,可以有一种形式的简单,也可以有另一种形式的简单,但不能两者兼而有之。