Live data from Hacker News

Use Long Options in Scripts

matklad.github.io

81–90 of 157 posts

Re: Use Long Options in Scripts

#81
post #6

Please DO NOT mix string interpolation and command execution, especially when a command is processed through the shell. Whatever your language, use a list-based or array-based execution API that passes arguments straight through to execv(2), execvp(2), etc, bypassing the shell.

Why would they even change the language and the commands in the example? It confuses and undermines the point. Just say “use `git switch -c my-new-branch` for interactive usage and `git switch --create my-new-branch` in scripts”. It makes no sense to introduce other unexplained information.

Re: Use Long Options in Scripts

#82
post #44

Earlier quoted context omitted.

Yes. The famous echo on Linux systems does not have it and therefore it's impossible to print the string "-n o p e", because -n will be interpreted as an option.

It does if single or double quotes are used, right? Which would be necessary (or preferred to multiple backslashes) quite often.

No, the quotes are not seen by the program. The program receives a list of strings, it does not get the information about whether and how those strings were originally quoted in the shell. Programs can also be directly called with lists of strings as in execve, so often it does not even make sense to ask if the arguments were quoted or not.

Quotes live on a different level of abstraction.

Re: Use Long Options in Scripts

#83

Strongly, strongly disagree. This is a GNU-ism, and needlessly verbose. What's with people refusing to use the vast amount of memory in their brains and actually learning, instead lazily going for the lowest-common-denominator approach relying on "loanwords" from English?

Because not everyone has 20 or more years of flag memory from using Linux, and they’ve also got to maintain the scripts. If you’re not familiar with every arcane invocation of find or tar or whatever, or even if it’s just been a while, the long options are a godsend when you’re skimming a script trying to figure out what it’s doing.

You can always copy+paste it into an LLM and have it explain the options in 5 seconds.

Re: Use Long Options in Scripts

#84
I prefer long options too. However, while writing programs that need to invoke POSIX commands in a portable manner, short options are the only viable choice, as POSIX doesn't specify long options. For instance, see the specification for diff at https://pubs.opengroup.org/onlinepubs/9799919799/utilities/d...>, or that of any POSIX utility listed at https://pubs.opengroup.org/onlinepubs/9799919799/idx/utiliti...>.

That said, this is more of a corner case. In most scenarios, rather than relying on POSIX utilities, there are often better alternatives, such as using library bindings instead of spawning external processes. For example, instead of invoking grep, using something like libpcre could be a more efficient choice.

For non-POSIX utilities like git, hg, rg, ag, etc., using long options makes perfect sense.

Re: Use Long Options in Scripts

#85
post #20

Also, do not forget using “--” after all options, but before any dynamic arguments, just to be safe.

I know to do this intuitively, but I have no idea why.

It's worth it just to watch the frustration of a junior when they try tacking more arguments on the end of a command.

Re: Use Long Options in Scripts

#86
post #6

Please DO NOT mix string interpolation and command execution, especially when a command is processed through the shell. Whatever your language, use a list-based or array-based execution API that passes arguments straight through to execv(2), execvp(2), etc, bypassing the shell.

Was waiting for this comment :P

The API used handles string interpolation correctly: the string literal is parsed at compile time, and the interpolated arguments are never concatenated or escaped, and end up directly as an element of arv array passed to a child. See

https://github.com/tigerbeetle/tigerbeetle/blob/7053ecd2137a...

Re: Use Long Options in Scripts

#87
post #84

I prefer long options too. However, while writing programs that need to invoke POSIX commands in a portable manner, short options are the only viable choice, as POSIX doesn't specify long options. For instance, see the specification for diff at https://pubs.opengroup.org/onlinepubs/9799919799/utilities/d... >, or that of any POSIX utility listed at https://pubs.opengroup.org/onlinepubs/9799919799/idx/utiliti... >. Th…

> However, while writing programs that need to invoke POSIX commands in a portable manner

...probably a stupid question, but something I have earnestly been wondering about... when does this actually happen nowadays? What POSIX systems are you targeting that aren't one of the major ones (Linux, Darwin, or one of the major BSDs)?

I was writing a shell script a few months ago that I wanted to be very durable, and I targeted sh instead of bash just because, well, it seemed like the correct hacker spirit thing to do... but I don't actually know what system in the past decade (or more) wouldn't have bash.

Re: Use Long Options in Scripts

#88
Before invoking a command, always first check if the length of the command is not longer than ARG_MAX. For example, if this is your command:

    grep --ignore-case --files-with-matches -- "hello" *.c
Then invoke it as follows:

    CMD="grep --ignore-case --files-with-matches -- \"hello\" *.c"
    ARG_MAX=$(getconf ARG_MAX)
    CMD_LEN=${#CMD}

    if (( CMD_LEN > ARG_MAX )); then
        echo "Error: Command length ($CMD_LEN) exceeds ARG_MAX ($ARG_MAX)." >&2
        exit 1
    fi

    eval "$CMD" # warning, evaluates filenames

Re: Use Long Options in Scripts

#89
post #84

I prefer long options too. However, while writing programs that need to invoke POSIX commands in a portable manner, short options are the only viable choice, as POSIX doesn't specify long options. For instance, see the specification for diff at https://pubs.opengroup.org/onlinepubs/9799919799/utilities/d... >, or that of any POSIX utility listed at https://pubs.opengroup.org/onlinepubs/9799919799/idx/utiliti... >. Th…

> However, while writing programs that need to invoke POSIX commands in a portable manner ...probably a stupid question, but something I have earnestly been wondering about... when does this actually happen nowadays? What POSIX systems are you targeting that aren't one of the major ones (Linux, Darwin, or one of the major BSDs)? I was writing a shell script a few months ago that I wanted to be very durable, and I tar…

Where I can sometimes get burnt is busybox.

I more often get burnt in zsh to bash than that however

Re: Use Long Options in Scripts

#90
post #6

Please DO NOT mix string interpolation and command execution, especially when a command is processed through the shell. Whatever your language, use a list-based or array-based execution API that passes arguments straight through to execv(2), execvp(2), etc, bypassing the shell.

Miniature, in-line sh scripts are also fine as long as you use the provided parameter substitution.

If you’re averse to this:

  q(“select x where y = ‘“ + v + “‘“)
And instead do this:

  q(“select x where y = %s”, v)
Then you should be averse to this:

  x(“foo --option ‘“ + v + “‘“)
And instead do this:

  x(‘foo --option “$1”’, v)
This is particularly useful when it’s expedient to have one thing piping into another. Like it or not the sh DSL for pipes is excellent compared to doing things natively with execve() and pipe(), just as doing group by and count is far more concise in SQL than doing so natively.

Most SQL libraries give you something like q. Writing your own x is as simple as calling sh correctly. In Python, for example:

  def x(script, *args):
    run([“sh”, “-c”, script, “--“, *args])
Post reply on HN