Nnn: "which" vs "command -v"

Created on 4 Nov 2019  路  13Comments  路  Source: jarun/nnn

@eugene55 wrote

why not use command -v?
Look at description here: https://github.com/koalaman/shellcheck/wiki/SC2230

Throughout the source we use which, and he proposes we use command -v.

Rather than just changing that specific plugin I figured I'd ask what we do with the entire codebase as it's probably better to be consistent.

I have previously run into this discussion and from what I remember no one had a universal solution but the text he is citing makes it look like the proper solution...

Most helpful comment

Thanks, I'll add you. I am also integrating shellcheck in CI so we are guarded against future lints. So please allow me some time.

All 13 comments

I agree :+1: .

A few points to add:

  • command looks like a shell built-in, which means we need to invoke the shell in nnn.c which will do this. I think which will be much faster. @eugene55 can you please do a profiling with 10 random files in /usr/local/bin and share with us?
  • I can't think of any OS without which. It's in *BSD, Solaris and *nix. Probably the next version of POSIX should include it.

For now, I would suggest we update our scripts with command -v and leave the source code with which.

May I ask what was the problem with which?

Speed of shell spawning depends on actual shell implementation. in my case:

$ time for run in {1..1000}; do which vi > /dev/null; done

real    0m3.360s
user    0m1.322s
sys 0m2.136s
$ time for run in {1..1000}; do bash -c 'command -v $0 > /dev/null' vi; done

real    0m11.182s
user    0m7.055s
sys 0m3.963s
$ time for run in {1..1000}; do dash -c 'command -v $0 > /dev/null' vi; done

real    0m3.301s
user    0m1.095s
sys 0m2.330s

I agree with suggestion to change just scripts, leaving source code as is

The larger problem I see is the link says which is _non-standard_.

Why??? @koalaman did you audit the code and notice any non-compliance?

If not, then by this logic every utility that doesn't appear in the POSIX docs is _non-standard_. Utilities are added in open source everyday. They can be POSIX-compliant or not. But I don't think it's correct to term them _non-standard_ without an audit.

On Ubuntu, man which says:

_which returns the pathnames of the files (or links) which would be executed in the current environment, had its arguments been given as commands in a strictly POSIX-conformant shell._

I think that's pretty well-defined behaviour with respect to POSIX compliance.

I'm closing this as I am not convinced which is a _non_standard_ utility. If we have some alternative arguments we can always reconsider.

I'd tend to agree. It's similar in rationale to egrep vs grep -E where the former is a very common but non-POSIX version of the latter so you might as well pick the better one. However in this case, which has some relatively small differences (e.g. relating to builtins and aliases) that people sometimes find desirable, so it's not as clear cut. And, I mean, if you're not using it in a shell script...

Chances are that this check will become opt-in and/or more readily ignored in the future.

Yep, we left it unchanged. Thank you for sharing your view as well!

BTW, I am actually sanitizing our plugins using shellcheck as I am writing this. Would you be interested in reviewing the changes? Not too many but I am not very confident on the changes I made to check exit status from a command.

Sure, I could do that

Thanks, I'll add you. I am also integrating shellcheck in CI so we are guarded against future lints. So please allow me some time.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

tim77 picture tim77  路  9Comments

CantoroMC picture CantoroMC  路  4Comments

billop picture billop  路  5Comments

harriott picture harriott  路  6Comments

akimdi picture akimdi  路  6Comments