如何重定向子进程的输出?

the*_*fog 2 io-redirection shell-script

我正在运行以下git clone命令sudobash并且我想将 STDOUT 重定向到日志文件:

% sudo -u test_user bash -c "git clone https://github.com/scrooloose/nerdtree.git
/home/test_user/.vim/bundle/nerdtree >> /var/log/build_scripts.log"
Run Code Online (Sandbox Code Playgroud)

发生的事情是 STDOUT 继续发送到终端。IE

Cloning into 'nerdtree'...
remote: Counting objects: 3689, done.
[...]
Checking connectivity... done.
Run Code Online (Sandbox Code Playgroud)

我猜这个问题与sudo分叉一个新进程然后bash分叉另一个进程的事实有关,如下所示:

% sudo -u test_user bash -c "{ git clone https://github.com/scrooloose/nerdtree.git
/home/test_user/.vim/bundle/nerdtree >> /var/log/build_scripts.log; ps f -g$$; }"  

  PID TTY      STAT   TIME COMMAND
 6556 pts/25   Ss     0:02 /usr/bin/zsh
 3005 pts/25   S+     0:00  \_ sudo -u test_user bash -c { git clone https://github.com/scrooloo
 3006 pts/25   S+     0:00      \_ bash -c { git clone https://github.com/scrooloose/nerdtree.
 3009 pts/25   R+     0:00          \_ ps f -g6556
Run Code Online (Sandbox Code Playgroud)

我试过了

  • 在脚本中运行它并exec >> /var/log/build_script.log在命令之前使用
  • 将命令包装在一个函数中,然后调用和重定向函数输出

但我认为这些重定向仅适用于父进程,子进程默认将 STDOUT 发送到/dev/tty/25其父进程,导致输出继续到终端。
如何重定向此命令的 STDOUT?

ter*_*don 9

您提到的消息不会打印到标准输出,而是打印到标准错误。因此,要捕获它们,您需要重定向标准错误而不是标准输出:

sudo -u user bash -c "git clone https://github.com/foo.git ~/foo 2>> log"
Run Code Online (Sandbox Code Playgroud)

或者同时使用 STDERR 和 STDOUT:

sudo -u user bash -c "git clone https://github.com/foo.git ~/foo >> log 2>&1"
Run Code Online (Sandbox Code Playgroud)

使用bash,您还可以&>>为此使用:

sudo -u user bash -c "git clone https://github.com/foo.git ~/foo &>> log"
Run Code Online (Sandbox Code Playgroud)

cshtcshzsh相当于存在>>&(t)csh不支持2>&1所以它的唯一办法):

sudo -u user csh -c "git clone https://github.com/foo.git ~/foo >>& log"
Run Code Online (Sandbox Code Playgroud)

fish

sudo -u user fish -c "git clone https://github.com/foo.git ~/foo >> log ^&1"
Run Code Online (Sandbox Code Playgroud)

有关不同类型重定向运算符的更多信息,请参阅外壳程序的控制和重定向运算符是什么?

现在,在 的特定情况下git,还有另一个问题。像其他一些程序一样,git可以检测到它的输出正在被重定向并停止打印进度报告。这可能是因为这些报告旨在实时查看并包含\r保存在文件中时可能出现的问题。要解决此问题,请使用:

       --progress
       Progress status is reported on the standard error stream by default
       when it is attached to a terminal, unless -q is specified. This
       flag forces progress status even if the standard error stream is
       not directed to a terminal.
Run Code Online (Sandbox Code Playgroud)

和:

sudo -u user bash -c "git clone --progress https://github.com/foo.git ~/foo >> log 2>&1"
Run Code Online (Sandbox Code Playgroud)

如果您想同时查看输出保存到文件,请使用tee

sudo -u user bash -c "git clone --progress https://github.com/foo.git ~/foo 2>&1 | 
    tee -a log
Run Code Online (Sandbox Code Playgroud)