grep returns a non-zero exit code when no matches are found, making it easy to include in shell scripts and if conditions directly without having to shell out to test to analyze the results.
What are your thoughts on having fd do the same so that fd not-exists and fd exists have differing exit codes that could be directly checked?
Thank you for the feedback!
Interesting thought. However, I'm not sure that it's a good idea to implement it this way. find always returns 0 if it finished the search without any errors, even if there are no results.
The idea is that you can use the exit code to tell whether or not you can rely on the search results. If the exit code is non-zero, there might be folders/files which were not searched (due to permission issues, for example). I believe we should probably do the same with fd (we currently silently ignore these).
Coming back to your use case, I agree that it would be nice to use fd this way in shell scripts, but I guess there are some rather simple workarounds that would achieve the same, for example
fd ... | grep .
Fair enough.
It does occur to me that a better option here (if one were to want to improve this) might be to add a --has-results or similar flag that _would_ use the 0/1 return code, which has the added benefit of allowing fd to terminate early when a match is found.
If you want early return, you can use head -n 1:
fd ... | head -n 1 | grep .
I'm going to close this as there are reasonable solutions including other CLI tools.
Good reasoning for not giving exit code by default in the second comment, thanks for explaining.
To enumerate the benefits of a built-in CLI option, however:
--help and the man page, which can lead to people getting their job done faster. After all, it is a common requirement to test for emptiness.fd --quiet something VS fd something | head -c 1 | grep . 1>/dev/nullIn the meantime (since writing the comments above) there have been some new developments:
We now have a --max-results=<count> option and a -1 alias for --max-results=1 that can be used to exit early after finding the first result(s). This is even faster than the early exit via fd … | head -n1 because the latter is actually running until the second result.
we can list the flag in
--helpand the man page, which can lead to people getting their job done faster. After all, it is a common requirement to test for emptiness.
Ok, agreed. But I would assume that this use case (testing for existence of search results) is something that usually comes up in a script, not in the interactive use of a terminal. Therefore, I don't think it's too bad if there is no super-short way to achieve that result is found.
there's a tiny overhead in calling 2 extra binaries piped together, even though that's more aesthetics than practical concern (for most people?)
As you said, I think that's negligible compared to the IO overhead (accessing the disk / cache) to get the search results.
- it's more readable:
fd --quiet somethingVSfd something | head -c 1 | grep . 1>/dev/null
Fair point. I think there are slightly more readable alternatives though:
if [[ $(fd -1 …) ]]; then
echo "found something!"
else
echo "did not find anything"
fi
- not everybody is a pro at bash (who is, anyway?), it's nice when you can get the job done faster and simpler
Ok. Let's reopen this ticket and see what others think.
Just chiming in that I'd also appreciate a flag for setting exit status :)
Sure, the given alternatives work; but I'd need to add a comment to have any faith that anyone would understand why. If I saw something like fd something | head -c 1 | grep . 1>/dev/null I'd have no clue what the intent was; whereas if I saw:
if fd --set-exit-status 'pattern'; then
...
fi
Then the intent is clear and my coworkers won't get confused 😄
Alternative names for the option could be --test or --match
Ok, let's try to implement this. I like --test. We can probably reuse the --max-results functionality and run a --max-results=1 search. Instead of printing anything to the console, we would simply return 0 or 1, depending on whether we have at least one result or not.
if fd --test pattern; then
...
fi
What do you think @ChrisPenner @mqudsi @vn971?
In particular, the decision not to print anything? Otherwise, we would have to use > /dev/null in scripts. And we already have fd -1 pattern to print the first search result and quit.
I guess the decision to not print anything makes even more sense if the flag is called --silent / --quiet. Another argument in favor of that naming would be that it's standard in CLI tools (grep, curl, wget, indirectly ssh, indirectly ping, etc)
@sharkdp I love it. --test sounds good to me and reminds me of the test command, which is good since this is similar to how that command is used. I also like the idea of hiding output. It makes it faster if we only need to find a single match, and if we WERE printing something it'd be very unintuitive to only print a single thing. Hiding it all seems best to me 👍
I believe that -q/--quiet is "the norm" for this sort of behavior (no output + early termination if possible), --test doesn't really imply anything that one could intuit as being suppression of output.
I still feel that in addition to/apart from any "fast eval" mode, the standard exit code should also reflect the match/no match status to match standard unix tools like grep and find.
I believe that
-q/--quietis "the norm" for this sort of behavior (no output + early termination if possible),
Really? I would expect a --quiet option to do exactly the same, but without the output. The option that is being proposed here would change the behavior (only search for the first result, then quit).
--testdoesn't really imply anything that one could intuit as being suppression of output.
that's true, but it would be used to test if a search has a match. Another possibility would be --check or --has-match ….
I still feel that in addition to/apart from any "fast eval" mode, the standard exit code should also reflect the match/no match status to match standard unix tools like
grepandfind.
I argued above that we don't want to do this because it would not reflect what find does. find does return 0 if there are no matches (and no filesystem errors have occurred). We don't necessarily have to be consistent with find, but in this case, I think we should aim to be.
Most helpful comment
Ok, let's try to implement this. I like
--test. We can probably reuse the--max-resultsfunctionality and run a--max-results=1search. Instead of printing anything to the console, we would simply return 0 or 1, depending on whether we have at least one result or not.What do you think @ChrisPenner @mqudsi @vn971?
In particular, the decision not to print anything? Otherwise, we would have to use
> /dev/nullin scripts. And we already havefd -1 patternto print the first search result and quit.