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.
![](../../users/profiles/719547.webp)
- 15,555
- 4
- 60
- 83
![](../../users/profiles/6235771.webp)
- 1
- 1
-
1BTW -- 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 Answers
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.
![](../../users/profiles/719547.webp)
- 15,555
- 4
- 60
- 83