|
|
Subscribe / Log in / New account

Debian's which hunt

Benefits for LWN subscribers

The primary benefit from subscribing to LWN is helping to keep us publishing, but, beyond that, subscribers get immediate access to all site content and access to a number of extra site features. Please sign up today!

By Jonathan Corbet
October 28, 2021
One does not normally expect to see a great deal of angst over a one-page shell script, even on the Internet. But Debian is special, so it has been having an extended discussion over the fate of the which command that has been escalated to the Debian Technical Committee. The amount of attention that has been given to a small, nonstandard utility shines a light on Debian's governance processes and the interaction of tradition with standards.

The which command will locate an executable program within the current search path and print the result:

    $ which nethack
    /usr/bin/nethack

This long-present tool is often used at the command line to locate the binary for a program; scripts also use it for similar purposes, or to determine whether a given program is available at all. For many users, which has long been baked into muscle memory and is used reflexively at need.

For all that, which is not a standardized component on Unix-like systems; POSIX does not acknowledge its existence. For that reason, among others, there are a number of implementations of which, each differing in its own special ways. Many distributions ship the GNU version of which, for example, with its characteristic long list of options. FreeBSD has its own version. Some shells also implement which as a built-in command. Debian ships yet another version, in the form of the aforementioned one-page shell script; it is part of the debianutils package.

In August 2020, Erik Gustafsson noted that the FreeBSD version of which supports a -s flag that suppresses the printed output and sets the exit status based on the existence of the queried program. He thought that feature would be useful in Debian, and helpfully provided a patch adding that feature. Thus began the discussion of the value of which and whether Debian's version should gain more features; at one point Clint Adams, the co-maintainer of debianutils, opined that which should be removed from that package.

Fast-forward to one year later, and Boyuan Yang observed that the which command in the Debian unstable distribution now prints a deprecation warning saying that which is going away. This resulted in a fair amount of consternation (and requests for a reversion of the change) for a number of reasons, starting with the fact that many users simply expect to have which available to them. It turns out that a number of build scripts for Debian packages use which as well; as an extra annoyance, the printed deprecation warning breaks the build process for some packages. The amount of pressure applied to Adams to restore which began to increase.

Adams has a number of reasons for wanting to remove which from debianutils. The POSIX-blessed way of finding an executable program is command -v, which is consequently built into most shells. Given the standard alternative, Adams said, "surely no one competent would choose to have a package depend on `which` when a standard POSIX utility can do a better job". Given that there are numerous variants of which, each with its own advocates, it makes little sense to ship one version in a package marked "essential" (meaning that it must be installed on every Debian system). The Debian Developer's Reference manual once suggested using which in maintainer scripts, but that suggestion was removed in 2018 in favor of command -v. So the which command, Adams argued, is certainly not essential; even if Debian ships it at all, it should not be part of an essential package.

In the end, Adams argued, there are several paths that could be followed regarding which, none of which can please everybody. The path he has chosen is, in his opinion, the best one:

Another is to build a runway for people to get what they want and remove myself from the equation. This is what I have attempted to do. Now, provided anyone elects to maintain them and the FTP team allows them in, users will be able to install and use GNU which, *BSD which, busybox which, rewrite-it-in-rust which, or whatever should float someone's boat. I can think all of this is pointless, and it doesn't matter, because I am not impeding anyone else in their pursuit of which(1) apotheosis.

While most Debian developers do not appear to be opposed to the idea of gracefully moving which out of the debianutils package, many of them disagree with how that is being done. As laid out by Wookey, this change, if done with a bit more care, could avoid many of the problems that are being seen now:

A proper transition plan would mean that I would never even notice this. One which would replace another and nothing would break. That is the sort of thing I expect to happen in Debian - we are generally good at this stuff, and it's a big reason for using the distro.

In mid-September, Adrian Bunk took the matter to the Technical Committee, asking that Adams be overridden in a number of ways. Specifically, he requested a decision that which be provided by an essential package (he didn't say which one), that it not be allowed to print deprecation warnings, and that it not be provided via the "alternatives" mechanism. "Alternatives" is how Debian allows users to choose between multiple implementations of a command; it would seem to fit the bill here, given the number of versions of which that exist. Bunk said that was not an option because it could break upgrades if a maintainer script tries to use which before the package providing it is completely configured.

Bunk's message also asked for two other opinions from the Technical Committee, neither of which generated as much heat. One was to mandate that debianutils must continue to provide tempfile, which is also on the chopping block; the other was that debianutils programs cannot be moved into /usr. That last request ties into another big debate within Debian over the ongoing implementation of the /usr merge transition. The committee issued a lengthy ruling on that subject on October 18, essentially saying that packages cannot count on a merged /usr until after the upcoming Debian 12 release.

Early discussions within the Technical Committee seemed to lead to a relatively quick consensus that, indeed, debianutils must continue to provide which at least until some other essential (or "transitively essential", meaning that an essential package depends on it) package provides it. There was a disagreement over the deprecation warning, though; while most committee members seemed minded to mandate its removal, David Bremner disagreed: "I don't think people are really entitled to expect which(1) to never print to stderr". Even if the warning is annoying, he said, it doesn't rise to the level where overriding a maintainer is justified.

So the ballot that went to the committee on October 20 reflected that disagreement. It mandates that debianutils keep which for now, but gives committee members the choice of whether they would require the warning to be removed. There is no mandate when it comes to the use of alternatives; it is up to the relevant developers to decide how the transition is to be managed. The ballot does mandate keeping tempfile and includes the language on not moving files to /usr, which is consistent with the October 18 ruling.

In the resulting voting, two of the members (Bremner and Elana Hashman) voted for the resolution without the removal of the deprecation warning; all other members were in favor of the whole thing. The resolution thus passed, Adams has been overridden, and which stays within debianutils — without the warning — for now. Assuming that a home for which (and tempfile) can be found in another essential package, though, the path is clear for them to transition out of debianutils before the Debian 12 release.

All of this may seem like a big fuss over a tiny program, and that is indeed what it is. But it is also a statement of how the Debian project wants changes like this to be made. Debian developers have nearly absolute control over their packages, but there are mechanisms in place to intervene when one developer exercises that control in a way that appears damaging to the distribution as a whole. This sort of whichcraft is how Debian has managed to keep hundreds of independent-minded developers working toward a common goal for the better part of three decades.


(Log in to post comments)

Debian's which hunt

Posted Oct 28, 2021 14:53 UTC (Thu) by clugstj (subscriber, #4020) [Link]

I must be getting slow in my old age. It took me until the end of the article to see the "which/witch" joke.

Debian's which hunt

Posted Oct 28, 2021 21:32 UTC (Thu) by nix (subscriber, #2304) [Link]

I do wonder whether the whole article was written so our editor could get the pun in the last line in. (Which is obviously an excellent reason to write a very interesting article!)

Debian's which hunt

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

Maybe, I'm looking forward to the follow-up "Ding Dong, the which is dead" if they ever decide to remove which.

Debian's which hunt

Posted Oct 31, 2021 12:49 UTC (Sun) by ermo (subscriber, #86690) [Link]

> I do wonder whether the whole article was written so our editor could get the pun in the last line in. (Which is obviously an excellent reason to write a very interesting article!)

Which may or may not be viewed as an excellent pun in and of itself. Well played Sir.

Debian's which hunt

Posted Oct 31, 2021 12:52 UTC (Sun) by nix (subscriber, #2304) [Link]

Hah! I... didn't even notice that :) the power of unconscious double meanings!

Debian's which hunt

Posted Oct 28, 2021 21:38 UTC (Thu) by developer122 (guest, #152928) [Link]

25, and I got to the end of the article ("whichcraft") before I realized that I haven't read about a single witch hunt in this entire article.

Debian's which hunt

Posted Oct 28, 2021 15:00 UTC (Thu) by dskoll (subscriber, #1630) [Link]

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.

Debian's which hunt

Posted Oct 28, 2021 15:50 UTC (Thu) by ncm (guest, #165) [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?

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]

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]

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]

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]

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 (subscriber, #131630) [Link]

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]

$ 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 (subscriber, #131630) [Link]

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]

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]

> 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]

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 (subscriber, #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 (subscriber, #987) [Link]

"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 (subscriber, #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'

Debian's which hunt

Posted Oct 28, 2021 15:44 UTC (Thu) by mb (subscriber, #50428) [Link]

It's just silly to make `which` print a deprecation warning.
Millions of scripts use `which`. That is not going to change any time in the next decades.

And removing `which` from debianutils without *automatically* replacing it with a `which` from a different package is also silly. That just causes users to be mad.

Debian's which hunt

Posted Oct 28, 2021 15:48 UTC (Thu) by ballombe (subscriber, #9523) [Link]

The deprecation warning is
/usr/bin/which: this version of `which' is deprecated; use `command -v' in scripts instead.
It does not include the word 'warning' so nobody noticed it while looking at logs.

Debian's which hunt

Posted Nov 2, 2021 16:16 UTC (Tue) by JanC_ (guest, #34940) [Link]

If you are monitoring logs, "deprecated" should probably be in the warning keywords too. :)

Debian's which hunt

Posted Oct 28, 2021 16:12 UTC (Thu) by jhoblitt (subscriber, #77733) [Link]

While I confess to frequently using `which` on the interactive command line, this utility has been causing me grief in build systems for decades. The only sane thing to do when relying on a shell is to replace it with `command -v`. The behavior of `which` is *non-standard*. It is not present by default in many operating systems, including many flavors of linux. The behavior of the command, if it exists, can be strangely different. This isn't theoretical, it has caused real world portability I've experienced. Sadly, the Huffman encoding and memorability of `command -v` is terrible but it has been part of posix essentially "forever".

Debian's which hunt

Posted Oct 28, 2021 17:05 UTC (Thu) by ballombe (subscriber, #9523) [Link]

At the same time a number of shells did not implemented it correctly for a long time, this was the original motivation for which.

Debian's which hunt

Posted Oct 28, 2021 17:12 UTC (Thu) by jhoblitt (subscriber, #77733) [Link]

Everything is awful...

Debian's which hunt

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

Notably, Debian's dash shell has some issues with command -v: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264

Debian's which hunt

Posted Oct 28, 2021 20:27 UTC (Thu) by Polynka (guest, #129183) [Link]

> At the same time a number of shells did not implemented it correctly for a long time, this was the original motivation for which.

The original motivation for ‘which’ was the original C shell not having any equivalent built-in functionality, so somebody hacked together a C shell script that not only found a relevant program in the search path, but also checked if a command was aliased to anything, since C shell had an unfortunate misfeature of executing its initialization files even when you ran such script non-interactively. Seriously, look at this:

https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/whi...

When people switched to other, better shells, they kept using ‘which’ and even worse – passed this “knowledge” to other, younger users who promptly started using ‘which’ themselves, and at this point a major feature of it was lost, since the script didn’t care about any aliases defined in any shell other than the C shell. And since people mostly learn *n?x based on a hearsay, not reading the documentation*, usage of ‘which’ persists to this day and people don’t learn about better alternatives.

* Cannot blame them, honestly. When MS-DOS 6.0, released in 1993 had nice, interactive and hyperlinked help system that allowed me to learn DOS to an advanced degree in a year back when I was only a small child, Linux and BSDs have still mostly only inconvenient, horrible to use man pages which were designed originally to be printed physically as a book, but are terribly inadequate for an interactive on-screen usage. Sure, there is also GNU Texinfo, but most people don’t know about it – because “all documentation is in the man pages” is another incorrect knowledge passed down by generations – and its default command line viewer has an outdated, unergonomical, contrary to people’s expectations user interface.

‘Which’ is not the only C-shellism that managed to unfortunately persist to this day. Every time you see people recommending other people to learn some magic incantation like ‘sudo !@#$%^&’, you see another case of it. Back when C shell was in the widespread use, no shell actually implemented interactive command line editing or interactive history recall and search, so this was the only option to reexecute a previous command with some modification, and in fact a major selling point of the C shell. Today, it’s basically pointless, requiring bigger cognitive load, more prone to mistakes (especially those of the catastrophic kind), and in most typical cases, doesn’t even save any keystroke – for example, S U D O SPACE ! ! ENTER has the same amount of them as ↑ HOME S U D O SPACE ENTER. But the second one is much more intuitive.

Debian's which hunt

Posted Oct 29, 2021 12:01 UTC (Fri) by epa (subscriber, #39769) [Link]

I've always found GNU info to be painful to use, navigating around a couple of paragraphs at a time with weird keystrokes for 'next section' and 'up one level'. And this from someone who spends all day in Emacs. Yep, you said the same, so we agree there.

A manual page has a much simpler user interface. You just read it and scroll up and down. A workaround is to pipe info into less so it splurges all the content.

Debian's which hunt

Posted Oct 29, 2021 12:47 UTC (Fri) by nix (subscriber, #2304) [Link]

Info has a better UI of late (a very low bar): it actually handles cursor keys, page up and page down like every other program on Earth written in the last forty years does.

I don't find u (up), n (next node) and l (go back) to be too confusing. Its other keybindings are... harder to remember.

(And in thirty years of using it I never realised that you could pipe it into other programs to get whole info documents at once.)

Debian's which hunt

Posted Oct 29, 2021 13:44 UTC (Fri) by mti (subscriber, #5390) [Link]

I have started to use 'pinfo' to read info pages. Nice colors and more intuitive key bindings.

Debian's which hunt

Posted Oct 29, 2021 20:43 UTC (Fri) by Polynka (guest, #129183) [Link]

> I have started to use 'pinfo' to read info pages.

Pinfo is good, but unfortunately the only distribution that I know of that installs it by default and actually aliases ‘info’ command to it is GoboLinux. Apparently filesystem isn’t the only thing that it does better than the usual GNU/Linux distributions. And those other distributions like to install by default lots of stuff that most people aren’t even gonna use once, like Vim, ‘rmt’ or ‘mailx’, so i guess Pinfo wouldn’t bloat them too much – though one can argue that it would also belong in _that_ category…

Debian's which hunt

Posted Oct 29, 2021 20:57 UTC (Fri) by Wol (subscriber, #4433) [Link]

If you want a distro that doesn't bloat your system, what about gentoo :-)

Okay, admin'ing your own system will get a bit harder, but you'll KNOW what's there and what it's doing, because you put it there and you told it what to do.

Cheers,
Wol

Debian's which hunt

Posted Oct 30, 2021 14:29 UTC (Sat) by Polynka (guest, #129183) [Link]

> If you want a distro that doesn't bloat your system, what about gentoo :-)

Sure, there’s also Arch that doesn’t even include ‘man’ command in its base system.

But I don’t really care about bloat, if I did, I surely wouldn’t argue that Pinfo should be installed by default. I just think that the choice of default packages should be based on practical, rather than historical considerations.

Debian's which hunt

Posted Nov 2, 2021 8:06 UTC (Tue) by flussence (subscriber, #85566) [Link]

The compiling-time argument may have become less important over the years, but you still have to lug around build dependencies for everything. When CUPS unexpectedly appears in the installation list, for instance, it's usually a sign that something's trying to smuggle yet another bundled copy of chromium onto your system. Or Java.

Debian's which hunt

Posted Oct 29, 2021 13:47 UTC (Fri) by rsidd (subscriber, #2582) [Link]

This is the sort of interesting historical comment for witch I read LWN, thank you.

Debian's which hunt

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

Agreed. I dimmly remembered my instructor in the late 1980's telling me about the differences (and hidden horrors) between csh and sh so that we could write scripts on our SunOS systems witch would also work on our new HP-UX box. Reading this sparked a bunch of 'ooooh yeah.' and why we quickly moved all our systems to use tcsh to get edited history.

** ps thanks for the hidden pun.

Debian's which hunt

Posted Oct 31, 2021 17:52 UTC (Sun) by tzafrir (subscriber, #11501) [Link]

"sudo !!" has less interactive editing and is faster for me (arrow-up is not just a key-press, it is an interaction, so is Home, to a lesser extent). I often use somewhat slow connections and this is meaningful for me.

Debian's which hunt

Posted Nov 1, 2021 15:38 UTC (Mon) by NYKevin (subscriber, #129325) [Link]

IMHO short man pages are fine for interactive use (e.g. reminding myself that ln(1) wants the target first, against all common sense). It's only when you try to read something ungodly long like bash(1) or complicated like sudoers(5) that it gets to be bad. But nowadays the web has completely replaced that use case anyway (especially since the GNU people started compiling their texinfo pages into HTML and putting them online).

Debian's which hunt

Posted Nov 16, 2021 14:07 UTC (Tue) by nye (guest, #51576) [Link]

> ln(1) wants the target first, against all common sense

$ mv old new
$ cp old new
$ ln old new

These are all the same - why is that against all common sense? Are you saying that you think ln should be changed to work differently from the others, or that they should all have the new file before the source file, like memcpy()?

Debian's which hunt

Posted Nov 16, 2021 14:20 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

My issue with it lies more in completion and thought process when writing it than anything else. The `old` argument is relative to the `new` final location. But I must write `old` before I have written where `new` is (or write the command's arguments in reverse order). Of course, if `old` is absolute or `new` lacks a `/`, it all works out just fine, but when it doesn't, I have to stop and remember that tab completion is going to lead me astray with `old`.

Debian's which hunt

Posted Nov 16, 2021 15:50 UTC (Tue) by Wol (subscriber, #4433) [Link]

Exactly.

My brain thinks that copy, mv, etc all take a "copy" of the first argument, and leave it in the second.

ln is the "wrong" way round, in that it leaves a copy of the second argument in the first.

THAT is why there is no such thing as "intuitive" software - what you think of as bleeding obvious, I think of as "who the hell designed that monstrosity!" (and vice versa, of course :-)

Cheers,
Wol

Debian's which hunt

Posted Nov 16, 2021 16:47 UTC (Tue) by jezuch (subscriber, #52988) [Link]

I still don't get it. You "link" something into some other place. There is now a new file with the same contents as the "old" file. How's that different from copy?

Or is the mental model "create a link <here> to <this file>" instead of "link <this file> <there>"? Perhaps the former makes more sense to native speakers ;)

Debian's which hunt

Posted Nov 16, 2021 16:49 UTC (Tue) by nybble41 (subscriber, #55106) [Link]

If you use `ln --relative --symlink` or `ln -rs` then the symlink target is resolved relative to the current directory (so you can use your tab completion) and the proper relative path is placed in the symlink.

$ mkdir -p a/b/c
$ touch test.file
$ ln -rs test.file a/b/c
$ ls -l a/b/c
total 0
lrwxrwxrwx 1 user group 18 Nov 16 00:00 test.file -> ../../../test.file

The --relative option was introduced in GNU coreutils 8.16.

Debian's which hunt

Posted Nov 16, 2021 21:35 UTC (Tue) by mathstuf (subscriber, #69389) [Link]

That is indeed useful for on the command line. Unfortunately, being GNU-specific, I am stuck without it for portable scripts. And some testing shows that `../` in the presence of directory symlinks shifting around what `../` means doesn't confuse it (probably by doing `realpath` on everything rather than trying to do string logic on paths).

Debian's which hunt

Posted Nov 4, 2021 13:59 UTC (Thu) by jschrod (subscriber, #1646) [Link]

While I don't use !!, !^ and !$ are used by me all the time; and are not so easy replaced by interactive editing with cursor keys. Even !* is sometimes easier to add to a longer new command then editing the previous command. And, if we talk about readline, don't forget M-C-e to expand such edit escapes, to be able to change them afterwards.

So you have chosen exactly an ! edit escape that one needs very seldomly and ignored the ones that are still usable nowadays. Not a very fair description, IMNSHO.

Debian's which hunt

Posted Oct 28, 2021 16:21 UTC (Thu) by smoogen (subscriber, #97) [Link]

I had not heard of command -v before I wanted to see what it was like on Fedora/CentOS. On my older CentOS box I got:

$ command -v which
which
$ which which
which ()
{ 
    ( alias;
    eval ${which_declare} ) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot "$@"
}

on a newer Fedora box, I got

$ command -v which
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'
which which
alias which='(alias; declare -f) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot'
	/usr/bin/which

Both are based off of https://savannah.gnu.org/projects/which/ 2.21 so I wonder how much it will break Fedora to change also.

Debian's which hunt

Posted Oct 28, 2021 17:11 UTC (Thu) by magfr (subscriber, #16052) [Link]

I tried dnf erase which on Fedora 32. Nothing important had dependencies of it, just gnome-shell, libreoffice, redhat-lsb, libvirt and some other similarly unimportant packages.
I then tried on fc34 and got told it would remove the protected package grub-pc.

I think there is room for a which hunt in fedora as well.

Debian's which hunt

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

FWIW, the which is not installed in the UBI minimal base container images, at least.

Debian's which hunt

Posted Oct 28, 2021 17:03 UTC (Thu) by atai (subscriber, #10977) [Link]

$ which which
/usr/bin/which

Debian's which hunt

Posted Oct 29, 2021 3:47 UTC (Fri) by areilly (subscriber, #87829) [Link]

% which which
which: shell built-in command

(on my macOS and FreeBSD systems).

Debian's which hunt

Posted Oct 28, 2021 19:43 UTC (Thu) by NYKevin (subscriber, #129325) [Link]

So the alternatives system will have to determine which which is the good which, and which which is the bad which. That should make for some entertaining arguments over default priority values.

Debian's which hunt

Posted Oct 28, 2021 19:56 UTC (Thu) by dskoll (subscriber, #1630) [Link]

Clearly, the one in the West is the Wicked Which, and the one in the North is the Good Which.

Debian's which hunt

Posted Oct 29, 2021 13:42 UTC (Fri) by rsidd (subscriber, #2582) [Link]

BSD Which is bad, GNU Which is good?

Debian's which hunt

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

Personally I feel if we end up with more than one which implementation in Debian we will have failed our users. For the avoidance of doubt I think there should be exactly one.

Debian's which hunt

Posted Oct 29, 2021 12:15 UTC (Fri) by joib (subscriber, #8541) [Link]

One could make the argument that some user could want to dedicate some debian machine to running some application glued together with a hodgepodge of shell scripts originally written for another implementation of 'which'. Say, GNU which as used by RH-derived distros. In which case (ha ha) it would be convenient if

a) No essential debian packages themselves would be dependent on the debianutils version of which.

b) One could choose the which implementation (ba dum tss, I'll be here all night!) to use via the alternatives mechanism.

Debian's which hunt

Posted Nov 1, 2021 9:06 UTC (Mon) by jond (subscriber, #37669) [Link]

Well, that's true, someone might want to do that. And one way they could do that is building GNU which themselves, dumping it into a private directory, and running the ball-of-mud with a suitably modified PATH. Obviously for those needing to do this, it would be more work that way. The project has to weigh up the likelyhood of Debian users needing to do this versus the costs to the project and all other users in terms of complexity, confusion, likelyhood of bugs, etc.

Debian's which hunt

Posted Oct 29, 2021 5:33 UTC (Fri) by dancol (guest, #142293) [Link]

I've never understood the total obsession some people have with making programs worse just so that they can fit inside the POSIX hairshirt. That's ridiculous. Why would we do that? Instead of changing every program on Earth to avoid which(1) because it's not The Standard, just change POSIX to reflect the reality we already inhabit and standardize the behavior of which(1).

The POSIX standard was not inscribed on stone tablets delivered to us from the summit of Mount Sinai. POSIX is made by humans to accomplish useful goals. We can change it!

Debian's which hunt

Posted Oct 29, 2021 7:45 UTC (Fri) by jond (subscriber, #37669) [Link]

I agree with you in principle. The problem to solve then would be to specify what the standard which should look like. Debian-derived distributions use a completely different implementation from redhat-derived, with different options and behaviours.

Debian's which hunt

Posted Oct 29, 2021 11:45 UTC (Fri) by mina86 (guest, #68442) [Link]

> just change POSIX to reflect the reality we already inhabit and standardize the behavior of which(1).

That’s easier said than done. First of all, changing the standard is non-trivial in general but here we have another complication of multiple different and incompatible implementations of ‘which’.

Debian's which hunt

Posted Nov 1, 2021 15:42 UTC (Mon) by NYKevin (subscriber, #129325) [Link]

Eh... you could take the echo(1) approach and basically say "If it's on your PATH and not an alias, shell function, etc., and you don't pass any flags, then output looks like it did in csh, otherwise the behavior is undefined."

(Yes, there are implementations which will print something funny if it's an alias, shell function, etc. See for example the builtin which in zsh.)


Copyright © 2021, Eklektix, Inc.
This article may be redistributed under the terms of the Creative Commons CC BY-SA 4.0 license
Comments and public postings are copyrighted by their creators.
Linux is a registered trademark of Linus Torvalds