0

Are the two commands $(git ls-files -s | wc -l) and $(git ls-files -s >out && wc -l <out) different or same, as when first is written in the second form, i end up getting errors.

Jim Stewart
  • 15,555
  • 4
  • 60
  • 83
  • 1
    BTW -- instead of just saying that you're "getting errors", providing the *exact* error seen helps folks tailor answers to your specific situation. (Certainly, surprising results would be expected if you had more than one copy running at the same time in the same directory, as the second one to start would truncate the `out` file created by the first). – Charles Duffy Mar 06 '17 at 18:25
  • 1
    ...and btw, the surrounding `$()`s mean that you're taking the output of `wc -l`, and running that output as a command *itself*, if that's the entirety of the command you're running (as opposed to an assignment, ie. `var=$(...)`). Certainly, that would be an error, but it's one you'd get in both scenarios. – Charles Duffy Mar 06 '17 at 18:27

1 Answers1

3

When you pipe the output of one program into the input of another, as in:

$(git ls-files -s | wc -l)

...the programs run concurrently. wc will start counting lines as soon as it receives them. The pipe also directs the output of git to the input of wc without any intermediate file.

Note that in this case, wc will run even if the git command fails for some reason, so you'll get the wc output (in most cases, 0).

In your second example:

$(git ls-files -s >out && wc -l <out)

...the git command runs first, and stores its results in a file called out. Then, if that was successful, wc runs and counts the lines. Because of &&, if the git command fails, wc won't run at all. In either case, you'll have a file named out laying around with the results of the git command in it.

Piping is generally better; it'll run faster and if you don't need to keep the intermediate results, it won't have any side effects.

Jim Stewart
  • 15,555
  • 4
  • 60
  • 83