子プロセスの出力をリダイレクトする方法は?

子プロセスの出力をリダイレクトする方法は?

git clone次のコマンドを実行しており、sudoSTDOUTbashをログファイルにリダイレクトしたいと思います。

% 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"

何が起こるかは、STDOUTが端末に送信され続けることです。つまり

Cloning into 'nerdtree'...
remote: Counting objects: 3689, done.
[...]
Checking connectivity... done.

sudobash問題は、次のように新しいプロセスをフォークしてから別のプロセスをフォークすることに関連しているようです。

% 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

頑張った

  • スクリプトで実行し、exec >> /var/log/build_script.logコマンドの前に使用します。
  • コマンドを関数にラップし、関数出力を呼び出してリダイレクトします。

しかし、これらのリダイレクトは親プロセスにのみ適用されると思います。子プロセスは/dev/tty/25デフォルトでSTDOUTを親プロセスに送信し、出力が端末に進むようにします。
このコマンドのSTDOUTをどのようにリダイレクトできますか?

ベストアンサー1

上記のメッセージは標準出力として印刷されず、標準エラーとして印刷されます。したがって、これを取得するには、標準出力の代わりに標準エラーをリダイレクトする必要があります。

sudo -u user bash -c "git clone https://github.com/foo.git ~/foo 2>> log"

またはSTDERRとSTDOUT:

sudo -u user bash -c "git clone https://github.com/foo.git ~/foo >> log 2>&1"

Passを使用すると、次の方法もbash使用できます。&>>

sudo -u user bash -c "git clone https://github.com/foo.git ~/foo &>> log"

csh、、等価(サポートされていないためtcsh、これが唯一の方法です):zsh>>&(t)csh2>&1

sudo -u user csh -c "git clone https://github.com/foo.git ~/foo >>& log"

存在するfish

sudo -u user fish -c "git clone https://github.com/foo.git ~/foo >> log ^&1"

さまざまな種類のリダイレクト演算子の詳細については、次を参照してください。シェルの制御およびリダイレクト演算子は何ですか?

今、特定のケースでは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.

そして:

sudo -u user bash -c "git clone --progress https://github.com/foo.git ~/foo >> log 2>&1"

出力を同時に見たい場合そしてファイルに保存するには、以下を使用しますtee

sudo -u user bash -c "git clone --progress https://github.com/foo.git ~/foo 2>&1 | 
    tee -a log

おすすめ記事