Live data from Hacker News

Debian's Which Hunt

lwn.net

61–70 of 257 posts

Re: Debian's Which Hunt

#61
post #58
post #45

I'm a descriptivist when it comes to standards. When everyone uses `which`, POSIX should add it. "but it's non-standard!" can be fixed by making it a standard.

The problem is that `which` behaves differently in many different existing use-cases (sometimes reporting aliases and sometimes not). If POSIX defines the behavior, then many existing uses become non-standard, and the existing implementations have to decide to change to become standard and possibly break backward compatibility or remain the same and stay non-standard.

In that case, pick the system which is statistically dominant and clone that. That'd be GNU first and FreeBSD second. The standard can be some subset of their behavior.

Re: Debian's Which Hunt

#62
I actually disagree that they shouldn't allow alternatives for `which`. IMO, just provide all of them and let the user decide. I should be able to choose from GNU which, BSD which, busybox which, or an alias to `command -v`. Default just keep it as GNU which.

Re: Debian's Which Hunt

#63
post #12

Earlier quoted context omitted.

I learned about `command -v` just now reading this article. I only knew of `which` and `type` (as well as the very convenient `=executable` syntax that expands to the path of the binary, but I think that's a zsh-ism). What makes `command -v` not machine friendly? It seems to always output just the PATH, unlike type which tries to be human friendly.

> I learned about `command -v` just now reading this article Me too and I'm sure we're not the only ones. But look at this quote from the article: > surely no one competent would choose to have a package depend on `which` when a standard POSIX utility can do a better job This is an mind-bogglingly misguided attitude. Anyone that has never heard of an obscure POSIX command is incompetent? Or is it that really that mos…

I heard of 'command -v' once before years ago, then completely forgot about it until this article. I don't like it because it's harder to type and harder to remember (why the -v?).

But I've only been using Unix for 37 years, so I'm not really competent.

Re: Debian's Which Hunt

#64
post #51

Huh. Apparently `command` is a shell builtin for POSIX shells, not a standalone program. You might still want `which` if you're running in a non-POSIX shell that doesn't implement `command`. Seems fine to deprecate its usage inside bash scripts or scripts that you know are pegged to an interpreter that implements `command`, though.

The Debian shell's implementation of "command" isn't POSIX compliant due to the following bug: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264

Re: Debian's Which Hunt

#65

I actually disagree that they shouldn't allow alternatives for `which`. IMO, just provide all of them and let the user decide. I should be able to choose from GNU which, BSD which, busybox which, or an alias to `command -v`. Default just keep it as GNU which.

In that case, have fun finding out which particular version is needed by the next install script you want to run.

Re: Debian's Which Hunt

#66
Here's how zsh 5.8 behaves on macOS:

    $ which {which,type,command,vi}
    which: shell built-in command
    type: shell built-in command
    command: shell built-in command
    /usr/bin/vi

    $ type {which,type,command,vi}
    which is a shell builtin
    type is a shell builtin
    command is a shell builtin
    vi is /usr/bin/vi

    $ command -v {which,type,command,vi}
    which
    type
    command
    /usr/bin/vi
Which is quite different from how bash 5.1 behaves:

    bash-5.1$ which {which,type,command,vi}
    /usr/bin/which
    /usr/bin/type
    /usr/bin/command
    /usr/bin/vi

    bash-5.1$ type {which,type,command,vi}
    which is hashed (/usr/bin/which)
    type is a shell builtin
    command is a shell builtin
    vi is /usr/bin/vi

    bash-5.1$ command -v {which,type,command,vi}
    /usr/bin/which
    type
    command
    /usr/bin/vi
I wouldn't want to be the one responsible for making this change, that's for sure.

command -v does seem like the most reasonable choice in both circumstances, though.

/usr/bin/type and /usr/bin/command are indeed just the same shell scripts.

    file /usr/bin/{which,type,command}
    /usr/bin/which:   Mach-O universal binary [...]
    /usr/bin/type:    POSIX shell script text executable, ASCII text
    /usr/bin/command: POSIX shell script text executable, ASCII text

    cat /usr/bin/command
    #!/bin/sh
    # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $
    # This file is in the public domain.
    builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"}

Re: Debian's Which Hunt

#67
post #55

Earlier quoted context omitted.

Unless you're using a shell that subverts that by providing its own built-in, like Zsh, which is allowed because there is no standard for `which`, and depending on its behavior can be problematic and inherently non-portable. That description is also doesn't correctly describe the behavior of the command if the shell has any aliases or built-ins of that name. If you have an alias that points to a different command, th…

As I said, it depends on which which you mean. In this case, Debian is changing it's behavior away from how it's been for 28 years or whatever and breaking heaps of code and people's habits in the process.

Yes, you're right. I think it's fine to depend on the existing which behavior for the current use cases. I just disagree that the behavior is really more useful than `command -v` for any sort of build or scripting purposes. It's definitely more useful as a user-facing utility to have a very recognizable name, like `which`. I'm one of the people who had never heard of `command -v` before now, and I'd used `which` for scripting, because I assumed it was standardized. I just don't see much use case for a shell command that finds a command in the path while specifically ignoring all aliases, functions, and built-ins over something like `command -v`.

> In this case, Debian is changing it's behavior away from how it's been for 28 years

In this case, Debian has voted to keep it the same: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=994275

Re: Debian's Which Hunt

#68
I gotta believe Mr Corbet's impetus for writing this story was for the season-appropriate pun. But as always, he still produced an insightful story on important Linux infrastructure.

Re: Debian's Which Hunt

#69
post #35
post #11

Earlier quoted context omitted.

What's not machine-friendly about `command -v`'s output? Can you not just use the exit status? Or did you mean that you avoid `which` in favor of `command -v`?

$ which true /usr/bin/true $ command -v true true $ which ls /usr/bin/ls $ command -v ls alias ls='ls --color=auto'

In a script, there will almost never be any aliases defined, because noninteractive shells don’t load ~/.bashrc.

    $ sh -c "which ls; command -v ls"
    /bin/ls
    /bin/ls
If the script is #!bash rather than #!sh, it’s not even possible to define an alias.

    $ bash -c "alias ls='ls --color=auto'; which ls; command -v ls"
    /bin/ls
    /bin/ls

Re: Debian's Which Hunt

#70

> 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". While I can understand having this attitude, a whole lot of package build scripts, not just in Debian, but in the upstreams, rely up…

Wait. Is the problem here extra _text_ in the output that shouldn't be parsed? I cannot believe people are parsing text output from other commands in the year 2021. To me that this sounds like incredibly unsafe practice and am just astounded it happens.

I've seen this happen as a workaround for the following bug in Dash: https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=874264

If Dash was POSIX compliant, this wouldn't be necessary, but it isn't, so hacky text parsing is sadly necessary.

Post reply on HN