无法使用脚本将交互式shell的输出重定向到文件

时间:2016-09-14 16:44:48

标签: linux bash shell

我尝试编写简单的输出记录器。它只是拒绝工作。我可以发誓,它曾经工作过一次,很漂亮。

这是练习,所以我不想使用预构建的bash工具。 (如script

代码:

#!/bin/bash
# create_log.sh

exec 6>&1

exec &> log

s

a=0

while true
do    
    sleep 1

    echo love

    ((a++))
    if  [ "$a" -eq 1000 ]
    then 
        break
    fi

done

exec 1>&6 6>&-

echo "Stopped doing love"

我在控制台. /create_log.sh &

中运行此脚本

只要循环开始,stdoutstderr就应该重定向到日志文件。但他们根本就没有。

日志文件中包含 love ,但我根本无法获取日期。 (或控制台的任何其他输出)

P.S。如果我只是在控制台中键入exec > log,它就能完美运行。

1 个答案:

答案 0 :(得分:0)

需要在要为其重定向输出的shell中本机运行方法,而不是在该shell的任何子进程中。运行&作为将命令与下一个命令分开的命令将其放入子进程中,而不是在shell本身中运行。

考虑这对函数(对于bash 4.1或更新版本):

# for this example, consider this content to belong to file-with-functions.bash

start_redir() {
    exec {orig_stdout}>&1
    exec > >(tee log >&$orig_stdout)
}

end_redir() {
    [[ $orig_stdout ]] || {
      echo "Not redirected with start_redir previously" >&2
      return 1
    }
    exec 1>&$orig_stdout
    exec {orig_stdout}>&-
}

...这可以使用如下:

. ./file-with-functions.bash # source these functions into the current shell; no &

start_redir
ls
end_redir

您可以将这些功能放在您提供的文件中,但是需要在前景中完成,因为在后台放置任何内容都会使其在子进程中发生,而不是在您的& #39;重新使用自己。