|
|
Subscribe / Log in / New account

Debian's which hunt

Debian's which hunt

Posted Oct 28, 2021 15:00 UTC (Thu) by dskoll (subscriber, #1630)
Parent article: Debian's which hunt

Huh, I did not know about command -v. I'd always used the type shell built-in, though it's output is not designed for computer-parsing.


to post comments

Debian's which hunt

Posted Oct 28, 2021 15:50 UTC (Thu) by ncm (guest, #165) [Link] (25 responses)

Yes, this is the first time I have encountered "command -v". How are we supposed to have heard of it? Who decided it should be the real Posixy thing, and "which" not?

It should be a pretty small effort to replace uses of "which" in packages that use it. After that, replacing "which" itself with a one-liner that says "use command -v" then "exit 1" is another small effort. Moving it out of the package it is in seems like pointless extra work.

Debian's which hunt

Posted Oct 28, 2021 16:06 UTC (Thu) by Taywee (guest, #154131) [Link] (16 responses)

For the purposes of most scripting use, which could easily just be aliased to command -v, or replaced with a small wrapper script around it, given that the exit status is what the average scripter would depend upon anyway.

POSIX is specified by the IEEE Computer Society, so that's who decided it. I don't think it much matters, though, as much of Linux use isn't constrained by POSIX anyway. I wonder how many build scripts would break if POSIX command line argument parsing was strictly followed (which mandates all option arguments before all positional arguments). I don't think having which as some universally-available alias for command -v would do any harm.

Debian's which hunt

Posted Oct 28, 2021 16:17 UTC (Thu) by abatters (✭ supporter ✭, #6932) [Link] (15 responses)

Note that they do not always give the same output:

# which ls
/usr/bin/ls

# command -v ls
alias ls='ls --color=auto'

Debian's which hunt

Posted Oct 28, 2021 18:08 UTC (Thu) by Taywee (guest, #154131) [Link] (3 responses)

Sure, but for scripting purposes, the primary use of it that I've seen is to answer the question "can I run this command?"
If you need to find whether an executable exists somewhere in PATH even if a built-in, function, or alias would subvert it, then the GNU which behavior is going to be more useful, but I can't think of a lot of use-cases for that, honestly.

Debian's which hunt

Posted Oct 28, 2021 18:44 UTC (Thu) by joey (guest, #328) [Link]

One use case is eg:

#!/bin/sh
foo=$(which foo)
PATH=something:else
$foo

Whether that will work with command -v will depend on what shell /bin/sh uses, since different shells read different dotfiles which could contain aliases. Yeah, I had a case of this in my ~/bin/.

Debian's which hunt

Posted Oct 28, 2021 20:37 UTC (Thu) by jond (subscriber, #37669) [Link]

Here’s another example in a high profile tool that by coincidence I was working on recently

https://github.com/apache/maven/pull/556

Debian's which hunt

Posted Oct 29, 2021 10:27 UTC (Fri) by GhePeU (subscriber, #56133) [Link]

$ alias "fakeprogram"="/usr/bin/notarealprogram -a"

$ which fakeprogram; echo $?
1

$ command -v fakeprogram; echo $?
alias fakeprogram='/usr/bin/notarealprogram -a'
0

$ command -V fakeprogram; echo $?
fakeprogram is aliased to `/usr/bin/notarealprogram -a'
0

Debian's which hunt

Posted Oct 28, 2021 19:01 UTC (Thu) by marcH (subscriber, #57642) [Link] (10 responses)

My favorite demo

$ which type
/usr/bin/type
$ type type
type is a shell builtin

I stopped using "which" after that and switched to type -p

BTW https://github.com/koalaman/shellcheck/wiki/SC2230

(everyone should use shellcheck)

Debian's which hunt

Posted Oct 29, 2021 6:24 UTC (Fri) by weberm (guest, #131630) [Link] (4 responses)

Pretty useless, isn't it?

$ which type
$ type type
type is a shell builtin
$ type -p type
$
# yes, its exit status tells me type exists, but not where
$ type ls
ls is aliased to `ls --color=auto'
# I hate that alias with a passion but sometimes forget to remove it. Not the point. It ought to tell me where the expanded alias is pulling that 'ls' in.
$ which ls
/bin/ls
$ command -v ls
alias ls='ls --color=auto'
$ command -V ls
ls is aliased to `ls --color=auto'

Nothing scratches my back just like which does.

Debian's which hunt

Posted Oct 29, 2021 13:59 UTC (Fri) by pj (subscriber, #4506) [Link] (2 responses)

$ type -a ls
ls is aliased to `ls -F --color=auto'
ls is /bin/ls

IMO, `type` seems to be the best-thought-out version of this tool, and should be made standard.

Debian's which hunt

Posted Oct 29, 2021 21:15 UTC (Fri) by weberm (guest, #131630) [Link] (1 responses)

I assume you're using bash? zsh?

$ type -a ls
mksh: whence: -a: unknown option

IMO which being an external tool actually comes in quite handy here. It has its drawbacks, but also its benefits.

Debian's which hunt

Posted Oct 29, 2021 21:29 UTC (Fri) by marcH (subscriber, #57642) [Link]

For scripts it may depend on what you're trying to achieve but in _interactive_ use you should always, always use the builtin provided by your particular shell. It's likely not portable but who cares: it's interactive use. There's no drawback and huge benefits.

Debian's which hunt

Posted Oct 29, 2021 16:28 UTC (Fri) by overfl0w (guest, #155055) [Link]

On the other hand on my system I have vim and nvim installed simultaneously. I also apparently have the following alias which I've forgotten about in .bashrc:
alias vim='nvim' in .bashrc

So when I execute the 'vim' command, actually 'nvim' is executed.

$ which vim
/usr/bin/vim
$ command -v vim
alias vim='nvim'

So in this particular case 'which' did not return the correct path. Perhaps this is due to the fact that 'vim' is a valid command. But if I executed 'vim', it would not execute the executable returned by 'which'. I found this by accident as I hadn't heard about 'command -v' before.

Debian's which hunt

Posted Oct 29, 2021 14:40 UTC (Fri) by smoogen (subscriber, #97) [Link] (3 responses)

So /usr/bin/type is a shell script which just does:
#!/usr/bin/sh
builtin type "$@"

It is there so you can run type foo in CSH or some other shell and still have it work. So which is telling you what could be executed via your path no matter what your shell is.

Debian's which hunt

Posted Oct 29, 2021 15:26 UTC (Fri) by marcH (subscriber, #57642) [Link] (2 responses)

> So which is telling you what could be executed via your path no matter what your shell is.

Ignoring functions , built-in and aliases is really harmful. This has cost me a lot of time so I simply stopped using it. Problem solved.

Debian's which hunt

Posted Oct 29, 2021 15:52 UTC (Fri) by marcH (subscriber, #57642) [Link]

To be clear:

- You should use "which" if you're still stuck with a C-shell for some reason
$ tcsh
> which which
which: shell built-in command.

More C-shell history below

- I'm not saying "which" must be removed or deprecated or whatever (I don't care). But I am saying it is harmful for bash and other Bourne shell users and that they should stop using it for their own good.

Debian's which hunt

Posted Oct 29, 2021 21:38 UTC (Fri) by buck (subscriber, #55985) [Link]

well, /usr/bin/which can't (easily) tell you if something is an alias or shell function, since it's not running in your shell. but the C/tcsh shell builtin `which` or Bourne/Korn/bash builtin `type` can. (sorry to possibly exclude mention of your shell; i just don't have any experience with it)

and, yes, count me in as one of the folks who never knew about the existence of `command` and had always resorted to `type -p` (and will continue to use it for my [occasional] purposes, which is in scripts and not interactive shells, when having `command -v` tell me about an alias isn't gonna work)

as for the matter somebody else raised about fetishizing POSIX, one only has to look at a `configure` script (maybe more so in the past than nowadays, as i guess checks for things like ULTRIX quirks may have gone by the wayside) to find plenty of reasons to be thankful for when an OS or distribution tries to take its cue from a formal or de-facto or what's-everybody-else-doing standard to reduce the heterogeneity when it doesn't add any meaningful value, ... if it's not already too well entrenched. and Linux itself got to be the dominant force it is by using (might-as-well-be) POSIX conformance as the calling card to present to get the door open, for it then to barge in and trample all the other guests

Debian's which hunt

Posted Nov 12, 2021 18:44 UTC (Fri) by rmc032 (guest, #131846) [Link]

> I stopped using "which" after that and switched to type -p

Which ironically, `type -p` is a GNU specific option and isn't POSIX compliant, as far as I can tell. I think I have the correct version here, but skimming the POSIX shell standard, it seems that the specification for the `type` utility doesn't list any options:
- OpenGroup link: https://pubs.opengroup.org/onlinepubs/9699919799/utilitie...
- Linux POSIX man page link: https://man7.org/linux/man-pages/man1/type.1p.html

Figured it was worth mentioning since a decent chunk of the article discussion is about how `command -v` is the POSIX way to find a command rather than `which`

Debian's which hunt

Posted Oct 29, 2021 2:18 UTC (Fri) by da4089 (subscriber, #1195) [Link] (4 responses)

To clearly state my bias up front: I've used various Unices since the mid-80's, and have always used 'which' (although I'm aware of 'type' in Bash). I'd not heard of 'command' until reading this article.

There's a kind of fundamentalism in the Unix world that sees the POSIX specification as some sort of authority. In my experience, this was mostly a problem in the transition to System V: Solaris tended towards POSIX compliance (or was it the other way around?) and SunOS was more historically based on BSD. The /usr/ucb tree saved my finger memory for many years.

HP/UX had a similar split, IIRC.

Linux has mostly been free of this kind of dogma. It took the GNU coreutils/shutils/etc and ran with them, but every so often little things popped up, and the gaps were plugged by things like bsdutils, bsdmainutils, and (apparently) debianutils.

Sometimes it's useful to have people move forward: newer ways can be better ways. But 'which' vs. 'command -v' ... is that really an improvement? Is it really a problem to have both available by default?

Debian's which hunt

Posted Oct 29, 2021 3:39 UTC (Fri) by unixbhaskar (guest, #44758) [Link]

Agreed. Having both available in the system makes no harm.

Debian's which hunt

Posted Oct 29, 2021 8:11 UTC (Fri) by mbunkus (subscriber, #87248) [Link]

Reading through the discussion archives, it seems that the reason for the intended removal wasn't technical or adherence to some standard. It was social. The (one of?) maintainer of the debianutils seriously got a lot of request, often in hurtful language, about perceived downsides of the which packaged in debianutils. See here:

https://lists.debian.org/debian-ctte/2021/10/msg00001.html

Basically he simply didn't want to have to deal with that shit anymore. Which (no pun intended) I emphatically agree with.

Debian's which hunt

Posted Nov 1, 2021 21:56 UTC (Mon) by mirabilos (subscriber, #84359) [Link]

which -a is functionality not available elsewhere, though.

Debian's which hunt

Posted Nov 4, 2021 16:13 UTC (Thu) by Karellen (subscriber, #67644) [Link]

There's a kind of fundamentalism in the Unix world that sees the POSIX specification as some sort of authority.

I think mostly it's just about reliability and portability.

If you only use features that's been ratified by POSIX then your code will be maximally portable to all Unices, no matter if they're derived from SysV or BSD, or from neither (e.g. Linux). If you want your code to be as useful to as many people as possible (or to be sellable to as many people as possible) then sticking to POSIX guarantees that. And if your code doesn't work on a platform, you get to blame the OS vendor, and to only grudgingly write a work-around (and maybe only if you get paid enough).

On the vendor side, if you want your platform to get any traction then you want as much existing code as possible to work on it, which means you need to embrace POSIX. Yeah, you can try and value-add stuff on top of that and go for the "extend" step (which traditional Unices did), but that carries a bad taste for Free Software/Linux devs (I wonder why?) and software devs don't always like to take advantage because then their software might not be usable by all their current users/customers.

Of the complaints I've seen about systemd and wayland (among others), the ones I have the most sympathy with are those from software devs who write apps that are meant to run on Linux and the BSDs, and for whom moving to the new native Linux APIs would mean either increasing their workload or dropping support for some platforms. Yes, back-compat support for init scripts and X11 exists and is supported, but some will still end up feeling like 2nd class citizens.

Debian's which hunt

Posted Oct 29, 2021 5:42 UTC (Fri) by nilsmeyer (guest, #122604) [Link]

> Yes, this is the first time I have encountered "command -v". How are we supposed to have heard of it? Who decided it should be the real Posixy thing, and "which" not?

Also first time I heard it, and glad I did because now I can once more considered to be competent in the eyes of Clint Adams.

I'm now wondering how much of what I use in my day to day shell use are builtins vs. dedicated programs (I'm using zsh). `which` in zsh is at least explicit about what's builtin, e.g.:
zsh:~ $ command -v command
command
zsh:~ $ which command
command: shell built-in command

Debian's which hunt

Posted Oct 29, 2021 9:04 UTC (Fri) by tchernobog (guest, #73595) [Link]

Well, user scripts are certainly something to consider. Deprecation/removal should be done over separate Debian release cycles.

Debian's which hunt

Posted Nov 2, 2021 20:41 UTC (Tue) by SomeOtherGuy (guest, #151918) [Link]

I'd never heard of command -v, there's even a bug with some bashes like mine where command -v returns the first match, not an actual executionable match.

It's going to be difficult

Debian's which hunt

Posted Oct 28, 2021 17:48 UTC (Thu) by oever (guest, #987) [Link] (1 responses)

"type -Pp $command" gives the path to the file that would be executed and nothing for aliases.

That seems at least as good as "command -v $command".

Debian's which hunt

Posted Oct 28, 2021 18:18 UTC (Thu) by smcv (subscriber, #53363) [Link]

> "type -Pp $command" gives the path to the file that would be executed and nothing for aliases.

In bash, yes. In other shells or on non-Linux OSs, no, so this is less portable than `command -v` (and in particular dash doesn't implement the -P or -p options).

POSIX specifies the `type` command, but does not specify any valid options for it.

Debian's which hunt

Posted Oct 29, 2021 9:46 UTC (Fri) by MarcB (guest, #101804) [Link]

Same here, but not really surprising:

$ man command
No manual entry for command

It is only mentioned in "builtins".

Also, it is not a drop-in replacement for which:
$ which ls
/bin/ls
$ command -v ls
alias ls='ls --color=auto'


Copyright © 2025, Eklektix, Inc.
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds