是否有一种简单而可靠的方法来创建“;“单身人士”;Bash中的进程?

是否有一种简单而可靠的方法来创建“;“单身人士”;Bash中的进程?,bash,Bash,环境:最近的Ubuntu,非标准的软件包是可以的,只要它们不是太异国情调 我有一个数据处理器bash脚本,它处理来自stdin的数据: $ cat data | process_stdin.sh 我可以更改脚本 我有一个遗留的数据生成系统(我不能更改),它通过SSH登录到一台机器并调用脚本,通过管道传输数据。伪代码: foo@producer $ cat data | ssh foo@processor ./process_stdin.sh 传统系统每天启动无数次 我希望保持/process

环境:最近的Ubuntu,非标准的软件包是可以的,只要它们不是太异国情调

我有一个数据处理器bash脚本,它处理来自stdin的数据:

$ cat data | process_stdin.sh
我可以更改脚本

我有一个遗留的数据生成系统(我不能更改),它通过SSH登录到一台机器并调用脚本,通过管道传输数据。伪代码:

foo@producer $ cat data | ssh foo@processor ./process_stdin.sh
传统系统每天启动无数次

我希望保持
/process\stdin.sh
处理器
机器上无限期运行,以消除进程启动开销。Legacy producer将调用某种包装器,以某种方式将数据传输到实际的处理器进程

是否有一种健壮的unix方法可以用最少的代码实现我想要的功能?我不想更改
/process\u stdin.sh
(太多)-完全重写已经安排好了,但是,唉,还不够快-我无法更改数据生成器。

一个(不太)肮脏的黑客可能是:

作为
处理器上的
foo
,创建fifo并运行
tail-f
重定向到
进程的stdin\u stdin.sh
,可能在无限循环中:

foo@processor:~$ mkfifo process_fifo
foo@processor:~$ while true; do tail -f process_fifo | process_stdin.sh; done
别担心,在这一点上,
process\u stdin.sh
正在等待一些东西到达fifo
process\u fifo
。无限循环就在这里,以防发生错误,因此它被重新启动

然后,您可以通过以下方式发送数据:

foo@producer:~$ cat data | ssh foo@processor "cat > process_fifo"
希望这能给你一些想法

做这项工作

同一命令很快发出了3次请求,但等待锁释放

# flock /var/run/mylock -c 'sleep 5 && date' &
[1] 21623
# flock /var/run/mylock -c 'sleep 5 && date' &
[2] 21626
# flock /var/run/mylock -c 'sleep 5 && date' &
[3] 21627
# Fri Jan  6 12:09:14 UTC 2017
Fri Jan  6 12:09:19 UTC 2017
Fri Jan  6 12:09:24 UTC 2017

关于这一点,我的第一个想法是,您可能很难确保脚本在每次循环某些输入时都有一个“干净”的环境。您试图避免的流程启动会做很多这方面的工作,并且编写的脚本可能会假定一个干净的启动。我并不是说在您的情况下,开销可能过大,但我会在考虑包装它和管道数据的方法之前考虑。不确定这是否有可能,如果您可以在管道输入上创建脚本块,并在无限循环中运行,那么这是个好消息,每次获取数据、初始化应用程序并运行脚本体时,您都需要将文件发送到与脚本关联的管道中。要退出,您可以发送一个关键字让scrip离开主循环。unix的方法是编写一个init脚本,并可能将其添加到某个运行级别。顺便说一句。@bitfiddler Clean environment在这里没什么大不了的-脚本相当愚蠢。@n.m.这是伪代码,而不是cat,还有更复杂的东西。这将序列化所有处理。最初的版本至少允许并行性…也就是说,可以通过重复这些指令乘以CPU的数量(当然有单独的路径)来实现并行性。这样会减少混乱,顺便说一句,应该更有效。注意这个解决方案!如果你真的在fifo中写“每天无数次”,你可能会偶尔发现你的写是交错的。(即使低级写(2)调用是原子的,缓冲标准库版本也不是原子的,并且不能保证
ssh
将在一个块中传输数据。)