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.
The behavior of which on different machines has a meaningful enough common subset that I would argue most people have absolutely no idea that there are this many different implementations. It’s possible this would lead to an undesirable standard that specifies less behavior than it should, but on the other hand, I believe that is easier to improve incrementally rather than all in one bandaid rip.
1) Require the output of which in non-interactive environments to conform to the behavior a reasonable shell script author is likely to have assumed the specification was based on observations. In the case of historic 'which' that would be to print the absolute path to an executable without any other arguments, or a specific error message and exit status.
2) Allow __interactive__ shells to deviate from that behavior. E.G. with a warning, with alias information, etc.
I feel like I'm going to be bit when I try commands interactively and then that act differently in a script. I think the current solution is the pragmatic one, don't standardize things you can't pull off standardizing! #!
The ls command does this: if output is to a tty then it prints in columns. Many commands add color when the output is a tty. I don’t think it would be a big issue.
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.
Or, add a new standard describing the wanted behavior from `which` which everyone is already using, but put it under a new binary name. If it's supposed to show the path for the thing passed in, maybe `where` would make sense.
That’s not usually how standards are supposed to work — a POSIX operating system should not reimplement Linux, it should only have to reimplement what’s portable to existing systems.
Except POSIX has historically always been the intersection of the major Unix vendors. Which is why its always been the lowest common denominator, and is largely crap as a result.
Of course to a certain extend all non defacto-standards suffer from this because invariably one group or the other doesn't want to rework their system to fit the standard so they NAK it.
POSIX does simplify things, diverging from historical practice, when it’s reasonably the only way to standardize stuff that arguably should be standardized. And the vast majority of scripts are easily converted to POSIX-compliant shell script anyways — it’s certainly not “largely crap”.
This was the case for literally all of the unix toolset before Posix came along, and how they solved this exact problem in every other case was to define a common subset (which usually involves almost all the functionality you really actually use most of the time) and make that the standard and everyone implements anything that's missing from the standard into their version and keeps all their existing extensions. That's why on linux you can do 'ps -leAf' or 'ps auxww' and have them do almost exactly the same thing for example.
The simple solution could be that POSIX defines that if the output has a leading slash, it references a path where the command inputted can be found. Any other output is informational in nature only and has no standard texts.
That is NOT a problem. Because which is an external program, it can't know about things like shell aliases and functions, and that's OK because users know it or expect it. Indeed, if you're writing a script then you already know what aliases and functions are in it, and you're only going to be interested in knowing what's outside the script -- which(1) does that just fine.
Stop looking for problems to solve where there are no problems. It's a waste of others' time, not just your own. Be respectful of others' time.
I don't understand why people even care about POSIX in 2021. It's not like Linux distributions are POSIX certified. So many things can't be good because it's not in POSIX or because POSIX requires something else. People actually force themselves to write scripts in some mythical POSIX shell that nobody uses.
There are some cases where it makes sense. For example let's say I was developing something like a build script for ncurses: that runs on many different systems, and sticking to POSIX for compatibility makes sense there. There still quite a bit of stuff like that.
But a lot of the time I see people write some shell script that's Linux or BSD specific in the first place as "compatible" shell scripts. I don't see how that makes much sense. The only advantage I can see is that dash is a bit faster than bash or zsh, but it's not that much of a difference in real scripts.
> The only advantage I can see is that dash is a bit faster than bash or zsh, but it's not that much of a difference in real scripts.
It also consumes quite a bit less memory, which can be relevant for shell wrappers or other long running scripts. That's the primary reason I started writing my scripts for dash rather than bash. The other advantages (portability, lack of cognitive overload caused by bash's infinitely long list of features and quirks) were an unforeseen bonus.
It's minimal effort to maximize compatibility and consistency, regardless of where the script may be run.
Shell scripts can run in a myriad of hosts, from VMs to stripped-down containers. When writing robust production code (not to say that shell scripts are ideal for that purpose), you'll want to minimize moving parts and risk surface, so that you can go home more confident that things will just work regardless of what you throw at it.
Making it standard is a lot of hard work while you make a lot of people argue and act in a way that makes sure that some part of the thing will work everywhere.
Standards exist on the real world, you can't just define them into existence without doing the work.
You can't quite be. Standards are norms, so there's no escaping normativity there. And simply describing existing conventions can't solve the problems that standards are introduced to solve, which is when you are faced with multiple, sometimes incompatible ways of doing things.
There's room for a kind of descriptivist reconciliation with updates to standards, though. You can say ‘Future versions of the standard should, as far as possible, directly incorporate contemporaneous usage. Where contemporaneous usage is divergent, they should reflect the virtues of contemporaneous usage in a new standard capable of replacing divergent uses.’
Also, POSIX is basically irrelevant now. There are only two Unixen that anyone uses: RMS/Linux and whatever outdated garbage userspace Apple is shipping with macOS.
That's just not true. There are various BSD systems, AIX, HP-UX, Solaris, etc. still exists, Alpine uses busybox.
Hell, I still see people being stuck with csh scripting sometimes with no alternative (sucks to be them!)
There is some common software that wants to run on all these platforms. Do you or I need to care about that for our Docker build script or whatnot? No, probably not. But that doesn't mean others don't. There's still very much a valid use-case for POSIX, even though it doesn't apply to everything.
Lots of specialised hardware ( networking or storage for instance) uses various flavours of *BSD under the hood, which is reflected in the main enterprise contributors to FreeBSD.
Maybe one day you’ll try out OpenBSD and find that you actually like it… and then you’ll be hit by the force of hundreds of thousands of software developers who subscribe to the philosophy you describe above. Standards are important — they’re the balance between a monopoly and a fragmented ecosystem, and give developers a chance to create new platforms that can innovate while supporting existing code.
> whatever outdated garbage userspace Apple is shipping with macOS
Is that a criticism of the FreeBSD userspace? Because that's where much of Apple's UNIX userspace is derived from, and they're regularly synced with upstream.
How much of macOS is actually still upstream BSD. I was under the impression they were slowly ripping it all out and replacing it (launchd, different logging subsystem, different file paths/directories)
I assume the parent is referring to command line utilities like sed, awk, and coreutils. The examples you're referring to are Apple's own software and not forks, so it'd be weird to call them "outdated."
Moving away from standards won't make it any easier to diversify our operating system choices. Standards compliance is what allows alternatives to be usable with existing software.
A lack of alternatives simply means that not enough standardization is happening, and we need more standards compliance.