Remix.run Logo
amelius 5 hours ago

It's a reminder of how archaic the systems we use are.

File descriptors are like handing pointers to the users of your software. At least allow us to use names instead of numbers.

And sh/bash's syntax is so weird because the programmer at the time thought it was convenient to do it like that. Nobody ever asked a user.

Dylan16807 22 minutes ago | parent | next [-]

> At least allow us to use names instead of numbers.

You can use /dev/stdin, /dev/stdout, /dev/stderr in most cases, but it's not perfect.

xenadu02 3 hours ago | parent | prev | next [-]

> At least allow us to use names instead of numbers.

You can for the destination. That's the whole reason you need the "&": to tell the shell the destination is not a named file (which itself could be a pipe or socket). And by default you don't need to specify the source fd at all. The intent is that stdout is piped along but stderr goes directly to your tty. That's one reason they are separate.

And for those saying "<" would have been better: that is used to read from the RHS and feed it as input to the LHS so it was taken.

zahlman 5 hours ago | parent | prev | next [-]

At the time, the users were the programmers.

amelius 5 hours ago | parent | next [-]

This is misleading because you use plural for both and I'm sure most of these UX missteps were _each_ made by a _single_ person, and there were >1 users even at the time.

Msurrow 4 hours ago | parent | next [-]

I think he meant that at that time all users were programmers. Yes, _all_ .

zahlman 39 minutes ago | parent [-]

It was a bit of an over-generalization, but yes that's basically what I was going for.

ifh-hn 4 hours ago | parent | prev | next [-]

> and there were >1 users even at the time.

Are you sure there wasn't >&1 users... Sorry I'll get my coat.

andoando 4 hours ago | parent | prev [-]

programmers are people too! bash syntax just sucks

booi 5 hours ago | parent | prev [-]

arguably if you're using the CLI they still are

spiralcoaster 3 hours ago | parent | next [-]

Yeah but now they're using npm to install a million packages to do things like tell if a number is greater than 10000. The chances of the programmer wanting to understand the underlying system they are using is essentially nil.

spott 3 hours ago | parent | prev | next [-]

Yea, they are just much higher level programmers… most programmers don’t know the low level syscall apis.

kube-system 4 hours ago | parent | prev [-]

nah, we have long had other disciplines using the CLI who do not write their own software, e.g. sysadmins

agentdrek 3 hours ago | parent | prev | next [-]

It should be a lesson to learn on how simple, logical and reliable tools can last decades.

bool3max 3 hours ago | parent | next [-]

… Or how hard it is to replace archaic software that’s extremely prevalent.

phailhaus 2 hours ago | parent | prev | next [-]

Bash syntax is anything but simple or logical. Just look at the insane if-statement syntax. Or how the choice of quotes fundamentally changes behavior. Argument parsing, looping, the list goes on.

akdev1l an hour ago | parent [-]

if statements are pretty simple

if $command; then <thing> else <thing> fi

You may be complaining about the syntax for the test command specifically or bash’s [[ builtin

Also the choice of quotes changing behavior is a thing in:

1. JavaScript/typescript 2. Python 3. C/C++ 4. Rust

In some cases it’s the same difference, eg: string interpolation in JavaScript with backticks

viraptor 43 minutes ago | parent [-]

> Also the choice of quotes changing behavior is a thing in:

In those languages they change what's contained in the string. Not how many strings you get. Or what the strings from that string look like. ($@ being an extreme example)

crazygringo 2 hours ago | parent | prev [-]

It's more like how the need for backwards compatibility prevents bad interfaces from ever getting improved.

csours 4 hours ago | parent | prev | next [-]

The conveniences also mean that there is more than ~one~ ~two~ several ways to do something.

Which means that reading someone else's shell script (or awk, or perl, or regex) is INCREDIBLY inconvenient.

amelius 4 hours ago | parent [-]

Yes. There are many reasons why one shouldn't use sh/bash for scripting.

But my main reason is that most scripts break when you call them with filenames that contain spaces. And they break spectacularly.

nixon_why69 2 hours ago | parent | next [-]

Counter reason in favor is that you can always count on it being there and working the same way. Perl is too out of fashion and python has too many versioning/library complexities.

You have to write the crappy sh script once but then you get simple, easy usage every time. (If you're revising the script frequently enough that sh/bash are the bottleneck, then what you have is a dev project and not a script, use a programming language).

ndsipa_pomu 4 hours ago | parent | prev [-]

You're not wrong, but there's fairly easy ways to deal with filenames containing spaces - usually just enclosing any variable use within double quotes will be sufficient. It's tricker to deal with filenames that contain things such as line breaks as that usually involves using null terminated filenames (null being the only character that is not allowed in filenames). e.g find . -type f -print0

deathanatos an hour ago | parent [-]

You're not wrong, but at my place, our main repository does not permit cloning into a directory with spaces in it.

Three factors conspire to make a bug:

  1. Someone decides to use a space
  2. We use Python
  3. macOS
Say you clone into a directory with a space in it. We use Python, so thus our scripts are scripts in the Unix sense. (So, Python here is replacable with any scripting language that uses a shebang, so long as the rest of what comes after holds.) Some of our Python dependencies install executables; those necessarily start with a shebang:

  #!/usr/bin/env python3
Note that space.

Since we use Python virtualenvs,

  #!/home/bob/src/repo/.venv/bin/python3
But … now what if the dir has a space?

  #!/home/bob/src/repo with a space/.venv/bin/python3
Those look like arguments, now, to a shebang. Shebangs have no escaping mechanism.

As I also discovered when I discovered this, the Python tooling checks for this! It will instead emit a polyglot!

  #!/bin/bash

  # <what follows in a bash/python polyglot>
  # the bash will find the right Python interpreter, and then re-exec this
  # script using that interpreter. The Python will skip the bash portion,
  # b/c of cleverness in the polyglot.
Which is really quite clever, IMO. But, … it hits (2.). It execs bash, and worse, it is macOS's bash, and macOS's bash will corrupt^W remove for your safety! certain environment variables from the environment.

Took me forever to figure out what was going on. So yeah … spaces in paths. Can't recommend them. Stuff breaks, and it breaks in weird and hard to debug ways.

joshuaissac an hour ago | parent [-]

If all of your scripts run in the same venv (for a given user), can you inject that into the PATH and rely on env just finding the right interpreter?

I suppose it would also need env to be able to handle paths that have spaces in them.

nusl 2 hours ago | parent | prev | next [-]

I quite like how archaic it is. I am turned off by a lot of modern stuff. My shell is nice and predictable. My scripts from 15 years ago still work just fine. No, I don't want it to get all fancy, thanks.

spiralcoaster 3 hours ago | parent | prev | next [-]

Who do you imagine the users were back when it was being developed?

crazygringo 2 hours ago | parent [-]

People who were not that one programmer?

Even if you're a programmer, that doesn't mean you magically know what other programmers find easy or logical.

gdevenyi 2 hours ago | parent | prev | next [-]

The programmers were the users. They asked. They said it was ok.

jballanc 2 hours ago | parent | prev | next [-]

Wait until you find out where "tty" comes from!

HackerThemAll 5 hours ago | parent | prev [-]

> bash's syntax is so weird

What should be the syntax according to contemporary IT people? JSON? YAML? Or just LLM prompt?

bigstrat2003 3 hours ago | parent | next [-]

Nushell, Powershell, Python, Ruby, heck even Perl is better. Shell scripting is literally the worst language I've ever seen in common use. Any realistic alternative is going to be better.

ifh-hn 4 hours ago | parent | prev | next [-]

Nushell! Or powershell, but I much prefer nushell!

sigwinch 3 hours ago | parent | prev | next [-]

There's a movement to write JSON to fd 3, as a machine-parsable alternative to rickety fd 1.

nazgul17 3 hours ago | parent | prev | next [-]

Trying to be language agnostic: it should be as self-explanatory as possible. 2>&1 is all but.

Why is there a 2 on the left, when the numbers are usually on the right. What's the relationship between 2 and 1? Is the 2 for std err? Is that `&` to mean "reference"? The fact you only grok it if you know POSIX sys calls means it's far from self explanatory. And given the proportion of people that know POSIX sys calls among those that use Bash, I think it's a bit of an elitist syntax.

stephenr 2 hours ago | parent [-]

POSIX has a manual for shell. You can read 99% of it without needing to know any syscalls. I'm not as familiar with it but Bash has an extensive manual as well, and I doubt syscall knowledge is particularly required there either.

If your complaint is "I don't know what this syntax means without reading the manual" I'd like to point you to any contemporary language that has things like arrow functions, or operator overloading, or magic methods, or monkey patching.

xeonmc 4 hours ago | parent | prev | next [-]

Haskell

amelius 4 hours ago | parent | prev [-]

Honestly, Python with the "sh" module is a lot more sane.

Normal_gaussian 4 hours ago | parent [-]

Is it more sane, or is it just what you are used to?

Python doesn't really have much that makes it a sensible choice for scripting.

Its got some basic data structures and a std-lib, but it comes at a non-trivial performance cost, a massive barrier to getting out of the single thread, and non-trivial overhead when managing downstream processes. It doesn't protect you from any runtime errors (no types, no compile checks). And I wouldn't call python in practice particularly portable...

Laughably, NodeJS is genuinely a better choice - while you don't get multithreading easily, at least you aren't trivially blocked on IO. NodeJS also has pretty great compatibility for portability; and can be easily compiled/transformed to get your types and compile checks if you want. I'd still rather avoid managing downstream processes with it - but at least you know your JSON parsing and manipulation is trivial.

Go is my goto when I'm reaching for more; but (ba)sh is king. You're scripting on the shell because you're mainly gluing other processes together, and this is what (ba)sh is designed to do. There is a learning curve, and there are footguns.