git clone not working if bash script is tee'd

68 Views Asked by At

I have this bash script:

#!/bin/bash -xe
set -xe

function build() {
  git clone --mirror https://github.com/digi-embedded/u-boot.git
}

time build $@ |& tee /tmp/build.log

When I run it:

./build.sh

it hangs. Adding verbose/trace like this:

GIT_CURL_VERBOSE=1 GIT_TRACE=1 \
git clone --mirror https://github.com/digi-embedded/u-boot.git

shows that it is stuck in the fetch part.

But, running the git clone on its own works fine:

git clone --mirror https://github.com/digi-embedded/u-boot.git

Then I changed my script to remove the tee, and everything just worked!

#!/bin/bash -xe
set -xe

function build() {
  git clone --mirror https://github.com/digi-embedded/u-boot.git
}

time build $@ # |& tee /tmp/build.log

Why does the tee cause git clone to fail?

2

There are 2 best solutions below

0
LeGEC On

Like many other commands (ls will toggle between multi column display while ls | cat will show 1 item per line, grep will color its matches while grep | cat will have a plain output ...), git clone checks whether its output (it looks like git clone specifically checks its stderr) is actually a terminal (a tty) and changes the information it outputs based on that.

It is the normal behavior to not see the progress meters when redirecting stderr.

You can instruct git clone to output its progress on stderr anyway by adding --progress; if you turn it on and still redirect stderr to /tmp/build.log, you will see that the content of your build.log file is a bit funky.


Check if your "git clone doesn't work" impression is real, or just the fact that since you don't have the meter anymore it feels stuck.

0
Mohammed Ehab On

I think the issue you're experiencing might be related to the use of process substitution (|&) and how it interacts with the tee command. The |& operator redirects both the standard output and standard error of a command to the command following it. Try this

time build $@ 2>&1 | tee /tmp/build.log

This explicitly redirects standard error (file descriptor 2) to the same location as standard output before piping it to tee. This might resolve the issue and allow git clone to work as expected.

If this didn't work then it might be related to buffering. When you use tee, it buffers the output, and if the buffer fills up, it can cause commands like git clone to hang.

Try to remove tee, then you eliminate the buffering, allowing the output to flow directly without delay. This is why the command works fine without tee. If you still need to log the output, you can try flushing the buffer after each line by using stdbuf with tee:

time build $@ | stdbuf -oL tee /tmp/build.log

This command uses stdbuf to set the output buffering mode to line-buffered, which can prevent the buffer from filling up and causing the hang.