5

I'm writing a bash script. I have a series of pipes working to get all the branches on a git repository:

git ls-remote $1 'refs/heads/*' \
  | rev \
  | cut -d'/' -f1 \
  | rev \
  | if [ -z $2 ]
      then
        echo {}
      else
        echo {} > $2
    fi

Currently the if statement part of this doesn't work properly. What do I replace {} with to make this work?

6
  • Make it work how exactly? To copy standard input to standard output, use cat, not echo.
    – tripleee
    May 16, 2017 at 18:15
  • And quote your variables, "$1" and "$2".
    – tripleee
    May 16, 2017 at 18:16
  • @tripleee currently it prints {} not the result from previous pipe. May 16, 2017 at 18:17
  • 1
    If you mean the standard input received by the if statement, ... Sorry, I can't think of any simpler way to say it. I think you want cat.
    – tripleee
    May 16, 2017 at 18:18
  • 2
    You might also want to replace the rev | cut | rev with sed 's~.*/~~'
    – tripleee
    May 16, 2017 at 18:22

2 Answers 2

10

To copy standard input to standard output, use cat, not echo.

git ls-remote "$1" 'refs/heads/*' |
sed 's~.*/~~' |
if [ -z "$2" ]
  then
    cat
  else
    cat > "$2"
fi

Notice also the proper use of quotes and the placement of the pipes so you can avoid the backslashes. The use of sed is a very minor optimization but I also find it clearer than the double rev around a cut (provided you grok regex). You could also use awk -F/ '{ print $NF }' (but then that requires you to grok Awk).

You could avoid the cat by doing this instead;

${2+exec >"$2"}
git ls-remote "$1" | sed 's~.*/~~'

(The failure if you pass in an empty string as the second argument should at least be more explicit, if not necessarily more helpful, than with [ -z, which fails to distinguish between an unset and an empty value.)

1
  • 1
    Yes, it also protects any wildcard characters in the values from being expanded by the shell; and newline could still be included in the values, although that woud be a rather pathological corner case here.
    – tripleee
    May 16, 2017 at 18:57
5

You can just replace {} syntax you're trying to use with cat since you're trying to read from stdin:

git ls-remote $1 'refs/heads/*' \
  | rev \
  | cut -d'/' -f1 \
  | rev \
  | if [ -z $2 ]
      then
        cat
      else
        cat > $2
    fi

Update: no subshell is needed, thanks @tripleee.

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.