0

I want use git pull in my shell script, it print 'Already up-to-date.', but I don't want it be printed. I want to save these message to a variable. How to do this? Thanks very much!


update: ➜ gitvar=$(git checkout alpha) Already on 'alpha' ➜ echo $gitvar M _gg.sh M _posts/2018-10-22-about.md I want to save "Already on 'alpha'" to variable "gitvar". The $(...) don't. Does this have anything to do with zsh?


update: I'm sorry. I didn't know stdout and stderr before. Thank you for telling me this. The answer to the question is that the print of the command may be stdout, or it may be stderr. 1 output=$(command) # stdout only; stderr remains uncaptured 2 output=$(command 2>&1) # both stdout and stderr will be captured

wang
  • 562
  • 6
  • 19
  • Aside: avoid `git pull` in scripts; use the two Git commands that `git pull` will run, instead. You'll get proper control that way. – torek Dec 30 '18 at 12:55
  • @torek thanks for your comments, what do you mean, "use the two Git commands"? – wang Jan 01 '19 at 15:48
  • @Eitrigg, `git pull` is `git fetch` + `git merge`. It doesn't do anything you don't get by combining the other two. – Charles Duffy Jan 01 '19 at 15:49
  • BTW, your "already on alpha" is on stderr, not stdout, which is why it isn't captured... which is what our many, *many* existing knowledgebase entries about the same problem already say. This is also covered in [BashFAQ #2](http://mywiki.wooledge.org/BashFAQ/002). – Charles Duffy Jan 01 '19 at 15:50

3 Answers3

3

You can save the standard output of the command to a variable in two ways:

a=`git pull`
a=$(git pull)

The latter is easier to nest, e.g.:

a=$(ls $(pwd))

However, you should note that the programs usually print the messages on two streams: stdout and stderr. E.g. git pull will print Already up-to-date on the stdout which would be correctly captured by the commands above. The error messages like fatal: not a git repository are printed on the stderr stream. In order to capture all output into the variable you need to redirect stderr into the stdout:

a=`git pull 2>&1`

The numbers 1 and 2 correspond to stdout and stderr, accordingly.

pkubik
  • 780
  • 6
  • 19
0

you can do that by

var=$(command)

and access var such as

echo $var
Auxilus
  • 217
  • 2
  • 9
  • In [How to Answer](https://stackoverflow.com/help/how-to-answer), note the section "Answer Well-Asked Questions", and the bullet therein regarding questions which "have already been asked and answered many times before". – Charles Duffy Jan 01 '19 at 15:48
0

As Auxilus has indicated, you can capture the output of a command within a variable using command substitution, e.g. $(...). The output for the command within $(...) can then be assigned to a variable, e.g.

$ gitvar=$(git pull)

Above, the output from git pull is now stored in gitvar. If you are waning to use this in a log file, then you can prepend the date to the output allowing a chronological log be maintained. A good log date format is "%b %e %T" (e.g. Dec 30 04:36:22). Creating your logvar is a simple matter of preprending the date to the string and adding the content of gitvar, e.g.

$ logvar="$(date +"%b %e %T") - $gitvar"
$ echo "$logvar"
Dec 30 04:36:36 - already up to date

You can then redirect the output to any log of your choice or make use of the original gitvar however you need.

David C. Rankin
  • 81,885
  • 6
  • 58
  • 85
  • thank you very much, I have try, but it don't work, this is the result: ```➜ gitvar=$(git checkout alpha) Already on 'alpha' ➜ echo $gitvar M _gg.sh M _posts/2018-10-22-about.md``` – wang Jan 01 '19 at 15:50
  • I don't understand. If you do a `git pull`, it will either report `"Already up-to-date."` or it will return `"remote: Enumerated objects.."` written to `stderr` and a list of files updated. (e.g. `"Updating 6e76e48..0ec1232 Fast-forward..."`) written to `stdout`. Using `$ gitvar=$(git pull)` only captures information written to `stdout`. If you want to capture both, use `$ gitvar=$(git pull 2>&1)` to write both `stdout` and `stderr` to `gitvar`. – David C. Rankin Jan 01 '19 at 18:36
  • If you don't want some part of the output, you can always use `head` or `tail` to trim lines from the start or end, or `sed` to trim from the middle based on some pattern match. – David C. Rankin Jan 01 '19 at 18:50