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?

  • Make it work how exactly? To copy standard input to standard output, use cat, not echo. – tripleee May 16 '17 at 18:15
  • And quote your variables, "$1" and "$2". – tripleee May 16 '17 at 18:16
  • @tripleee currently it prints {} not the result from previous pipe. – Philip Kirkbride May 16 '17 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 '17 at 18:18
  • 2
    You might also want to replace the rev | cut | rev with sed 's~.*/~~' – tripleee May 16 '17 at 18:22
up vote 7 down vote accepted

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
    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 '17 at 18:57

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.

Your Answer

 

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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