相关疑难解决方法(0)

如何以优雅的方式永远什么都不做?

我有一个程序可以生成有用的信息,stdout但也可以从stdin. 我想将其标准输出重定向到一个文件,而不在标准输入上提供任何内容。到目前为止,很好:我可以做到:

program > output
Run Code Online (Sandbox Code Playgroud)

并且不要在 tty 中做任何事情。

但是,问题是我想在后台执行此操作。如果我做:

program > output &
Run Code Online (Sandbox Code Playgroud)

程序将被挂起(“挂起(tty 输入)”)。

如果我做:

program < /dev/null > output &
Run Code Online (Sandbox Code Playgroud)

程序立即终止,因为它到达 EOF。

似乎我需要的是将program某些内容导入到无限期不执行任何操作且不读取的内容中stdin。以下方法有效:

while true; do sleep 100; done | program > output &
mkfifo fifo && cat fifo | program > output &
tail -f /dev/null | program > output &
Run Code Online (Sandbox Code Playgroud)

然而,这一切都非常难看。有是一种优雅的方式,使用标准的Unix工具,以“什么都不做,无限期”(意译man true)。我怎么能做到这一点?(我这里优雅的主要标准:没有临时文件;没有忙碌等待或定期唤醒;没有异国情调的实用程序;尽可能短。)

bash shell-script background-process stdout stdin

95
推荐指数
6
解决办法
5万
查看次数

如何捕获有序的 STDOUT/STDERR 并添加时间戳/前缀?

我已经探索了几乎所有 可用的 类似 问题,但无济于事。

让我详细描述一下这个问题:

我运行一些无人值守的脚本,这些脚本可以生成标准输出和标准错误行,我想按照终端模拟器显示的精确顺序捕获它们,然后向它们添加前缀,如“STDERR:”和“STDOUT:”。

我曾尝试对它们使用管道甚至基于 epoll 的方法,但无济于事。我认为解决方案是在 pty 使用中,尽管我不是这方面的高手。我还查看了Gnome 的 VTE的源代码,但这并没有多大成效。

理想情况下,我会使用Go而不是 Bash 来完成此操作,但我无法做到。由于缓冲,管道似乎自动禁止保持正确的行顺序。

有人能做类似的事情吗?或者这是不可能的?我认为,如果终端模拟器可以做到,那么它就不是——也许通过创建一个以不同方式处理 PTY 的小型 C 程序?

理想情况下,我会使用异步输入来读取这 2 个流(STDOUT 和 STDERR),然后根据我的需要重新打印它们,但输入顺序至关重要!

注意:我知道stderred但它不适用于 Bash 脚本,并且无法轻松编辑以添加前缀(因为它基本上包含了大量系统调用)。

更新:在两个要点下面添加

(可以在我提供的示例脚本中添加亚秒随机延迟,以证明结果一致)

更新:正如@Gilles 指出的那样,这个问题的解决方案也将解决另一个问题。但是,我得出的结论是,不可能在这里和那里做所要求的事情。当使用2>&1两个流在 pty/pipe 级别正确合并时,但要单独使用流并以正确的顺序使用,确实应该使用涉及系统调用挂钩的stderred方法,并且可以在许多方面被视为

如果有人可以反驳上述内容,我将渴望更新这个问题。

shell bash pipe io-redirection

28
推荐指数
2
解决办法
7933
查看次数

tee + cat:多次使用输出,然后连接结果

如果我调用某个命令,例如,echo我可以在其他几个命令中使用该命令的结果tee。例子:

echo "Hello world!" | tee >(command1) >(command2) >(command3)
Run Code Online (Sandbox Code Playgroud)

使用 cat 我可以收集几个命令的结果。例子:

cat <(command1) <(command2) <(command3)
Run Code Online (Sandbox Code Playgroud)

我希望能够同时做这两件事,这样我就可以tee在其他东西的输出上调用这些命令(例如echo我写的),然后在一个输出上收集所有结果cat.

保持结果为了这一点很重要,这意味着输出的线路command1command2并且command3不应该纠缠在一起,但订购的命令是(因为它与发生cat)。

可能有比cat和更好的选择,tee但这些是我目前所知道的。

我想避免使用临时文件,因为输入和输出的大小可能很大。

我怎么能这样做?

PD:另一个问题是这种情况发生在循环中,这使得处理临时文件变得更加困难。这是我拥有的当前代码,它适用于小型测试用例,但是在以某种我不理解的方式从 auxfile 读取和写入时,它会创建无限循环。

somefunction()
{
  if [ $1 -eq 1 ]
  then
    echo "Hello world!"
  else
    somefunction $(( $1 - 1 )) > auxfile
    cat <(command1 < auxfile) \
        <(command2 < auxfile) \
        <(command3 < auxfile)
  fi …
Run Code Online (Sandbox Code Playgroud)

pipe concurrency cat tee

19
推荐指数
1
解决办法
8850
查看次数

如何实现像 $RANDOM 这样的“生成器”?

$RANDOM每次访问特殊变量时都会有一个新值。在这方面,它让人想起某些语言中的“生成器”对象。

有没有办法在中实现这样的东西zsh

我试图用命名管道来做到这一点,但我没有找到一种以受控方式从 fifo 中提取项目而不终止“生成器”进程的方法。例如:

% mkfifo /tmp/ints
% (index=0
   while ( true )
   do
       echo $index
       index=$(( index + 1 ))
   done) > /tmp/ints &
[1] 16309
% head -1 /tmp/ints
0
[1]  + broken pipe  ( index=0 ; while ( true; ); do; echo $index; index=$(( ...
Run Code Online (Sandbox Code Playgroud)

有没有其他方法可以在 zsh 中实现这种生成器类型的对象?


编辑:这不起作用:

#!/usr/bin/env zsh

FIFO=/tmp/fifo-$$
mkfifo $FIFO
INDEX=0
while true; do echo $(( ++INDEX )) > $FIFO; done &
cat $FIFO
Run Code Online (Sandbox Code Playgroud)

如果我将上述内容放在脚本中并运行它,则输出很少是预期的单行

1
Run Code Online (Sandbox Code Playgroud)

相反,它通常由几个整数组成;例如

1
2 …
Run Code Online (Sandbox Code Playgroud)

zsh ipc fifo

11
推荐指数
1
解决办法
861
查看次数

捕获没有子shell的shell函数的输出

rbenv在机器上安装了(ruby 版本管理器),它的工作原理是这样的:

$ rbenv local
2.3.1
Run Code Online (Sandbox Code Playgroud)

写入标准输出我的 ruby​​ 的本地版本。我想拯救这个版本并在一个变量中声明它以在另一个场合重用。

$ declare -r RUBY_DEFINED_VERSION=$(rbenv local)
$ echo Using ruby version $RUBY_DEFINED_VERSION
Using ruby version 2.3.1
Run Code Online (Sandbox Code Playgroud)

有用!

但我不想使用子外壳来完成工作(使用$()``)。我想使用相同的外壳,我不想创建一个tmp文件来完成这项工作。

有没有办法做到这一点?

注意: declare -r不是强制性的,它可以是一个简单的var=FOOBAR.

shell command-substitution subshell variable

10
推荐指数
3
解决办法
5682
查看次数

coproc &lt;命令&gt; 与 &lt;命令&gt; &amp; 相同吗?

我读过的内容$coproc < command >不同于$< command > &与在子 shell 进程中coproc执行的command

但当我测试它时,它的工作原理就像$< command > &. 测试如下:

第一:测试行为$< command > &

  1. 跑步$nano &在tty1
  2. 在另一个 tty 上,输出来自$ps -t tty1 --forest表明 nano 进程是 -bash 进程的子进程(登录 bash shell 进程 -> 未创建子 shell 进程)

第二:测试行为$coproc < command >

  1. 跑步$coproc nano在tty1
  2. 在另一个 tty 上,输出来自$ps -t tty1 --forest上面相同(没有创建子 shell 进程)

也是如此$coproc < command >和一样吗$< …

bash coprocesses

5
推荐指数
1
解决办法
2305
查看次数

在 Bash 脚本中,“cmd1 [newline] cmd2”是否与“cmd1 &amp; cmd2”一样并发?

执行以下脚本

#!/usr/bin/bash

while true
do
  ab -c 700 -n 100000000000 -r http://crimea-post.ru/ >>crimea-post & ab -c 700 -n 100000000000 -r http://nalog.gov.ru/ >>nalog
done
Run Code Online (Sandbox Code Playgroud)

做的完全一样

#!/usr/bin/bash

while true
do
  ab -c 700 -n 100000000000 -r http://crimea-post.ru/ >>crimea-post 
  ab -c 700 -n 100000000000 -r http://nalog.gov.ru/ >>nalog
done
Run Code Online (Sandbox Code Playgroud)

根据我的经验,第一个脚本创建nalog文件的速度比第二个脚本(10 多分钟后)更快(几秒钟内),这表明后者需要等待ab -c 700 -n 100000000000 -r http://nalog.gov.ru/ >>nalog完成。情况不应该是这样,因为从我到目前为止的研究来看,第二个脚本应该ab -c 700 -n 100000000000 -r http://nalog.gov.ru/ >>nalog在不等待ab -c 700 -n 100000000000 -r http://crimea-post.ru/ >>crimea-post完成的情况下开始。我希望这两个ab命令同时执行,我如何在 …

bash background-process parallelism

1
推荐指数
1
解决办法
144
查看次数