Hacker News new | ask | show | jobs
by amiga386 412 days ago
* in Linux, the kernel is responsible for accepting a list of execve(2) argument-words

Yes it does, but the more surprising thing is (coming from AmigaOS with its dos.library function ReadArgs()) that the shell does this. The shell is also responsible for argument expansion - madness!

On AmigaOS, when you type "delete foo#? force", the shell passes the entire command line to the delete command. The delete command calls ReadArgs() with a template (FILE/M/A, ALL/S, QUlET/S, FORCE/S), and the standard OS function parses it into lists of files, flags, keyword arguments, etc. The "file" passed is "foo#?", and the command uses MatchFirst()/MatchNext() to do file pattern matching.

Every command (that uses ReadArgs() and didn't plump for "standard C" parsing) has the same behaviour: running the command with "?" gives you the template, which tells you how to use it. Args are parsed consistently across all programs.

Then you get "standard C", which because K&R and main(), ignores this standard Amiga parsing function and just does naive splits. Across multiple Amiga C compilers, quoting rules are inconsistent. Amiga C compilers have to produce an executable, and it knows it'll be called with a full command line, so the executable itself has to break that into words before it can call main(), and it's up to each compiler writer how they're going to do that. Urgh.

In unix-land, it's up to the shell to parse the command line, and pass only the words... hence why the shell naturally does all the filename globbing, and why you have gotchas like when these two commands are sometimes the same and sometimes they're not:

    find . -name foo*
    find . -name 'foo*'
Then we have Windows, which is like Amiga C programs - it's being passed a full command string and will have its C runtime parse it for main() to consume. There's a vague expectation that it'll do quoting "like COMMAND", which itself has very odd quoting rules. At least, most people are all using the same C compiler on Windows, so it's mostly only MSVCRT's implementation so it's mostly consistent.
1 comments

Username checks out.

I think one of the most surprising things I learned about bash is that you can do this:

    touch ./-rf
    rm *
And now you have rm -rf'd. :)
We should use "--" more, but who has all this time to waste? :)
Indeed, always prefer ./* to *

I often wish there was a convenient way of doing such an operation in the shell: if path start with "/", leave it, otherwise prepend "./"

> I often wish there was a convenient way of doing such an operation in the shell: if path start with "/", leave it, otherwise prepend "./"

Both bash and zsh have enough functionality exposed via shell functions and variables for you to define a keybinding that does exactly this, interactively. Good idea.

Did you mean an interactive command? Or something else?

I meant non-interactive, for use in scripts which take user input. We already have "--" for end of options, but the support for it is not universal and even with that some programs will interpret certain strings in a special way. On the other hand, prepending the dot-slash should work for any program or argument passing style.
Prepend for all paths on a command line? Or just for the executable?

For all paths it could be dangerous and should very probably not be done. But for executables it's less dangerous and can easily be done by putting '.' into $PATH.