Live data from Hacker News

Use Long Options in Scripts

matklad.github.io

91–100 of 157 posts

Re: Use Long Options in Scripts

#91
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…

> I don't actually know what system in the past decade (or more) wouldn't have bash.

I have written a bit more about it in these comments:

https://news.ycombinator.com/item?id=40681382

https://news.ycombinator.com/item?id=17074163

Re: Use Long Options in Scripts

#93

Earlier quoted context omitted.

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.

> 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.

With quotes the program will receive a single argument -n␣o␣p␣e instead of multiple ones -n, o, p, e. At least it works on the machine here:

    ]$ echo "-n o p e"
    -n o p e
    
    ]$ /bin/echo "-n o p e"
    -n o p e

Re: Use Long Options in Scripts

#94
post #29

Earlier quoted context omitted.

Not trying to spam this thread with praises of nix, because it does have its own problems, but it certainly solves the portability problem. Four years in to using it at work for dev environments across mac (x86 & ARM) and various linuxes and can’t imagine going back. I also always make dev environment definitions for my open source projects, so even if people aren’t using nix, there is at least a record of what tools…

Does nix work well on BSD-derived Unices? In particular, the most widespread of them, macOS?

Yes, works great on Mac. About half our engineers us Macs, the other half Linux. We have one nix configuration for the dev environment, which works for everyone.

Re: Use Long Options in Scripts

#95
post #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 ($A…

That might be sensible, but also obscure the script logic.

Since using Linux exclusively, I don't think I've ever encountered an issue due to too many arguments/length. And it's the first time I'm actively searching online for ARG_MAX.

I understand that different shells might be different, but with reasonable lengths is there any chance of it being relevant (aside from xargs, where it's generally intended, or better, to pass along each argument individually).

Re: Use Long Options in Scripts

#96
post #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 ($A…

You should always type check your shell scripts as well. For example, you just:

    $ shelltypes script.sh
    # Welcome to shelltypes v 3.23.2
    # type ‘help’ if you’re stuck
    >>> {1) # import POSIX;;
    Importing 73 items.
    >>> {2} # append loadpath “/opt/local/shelltypes/base”;;
    >>> {3} # import base::YOURPROJECT;;
    Importing 15 items.
    >>> {4} # check “YOURSCRIPT.sh”
    Parsing YOURSCRIPT.sh.
    Reticulating splines.
    Expanding aliases.
    Analyzing free shell environment variables.
    Found inconsistencies in PATH.
    Warning: Low battery!!!
    Warning: found free type for ‘shred’, ignoring.
    Warning: use of sudo requires password under /etc/sudoers.
    Warning: this utility is fake.
    Error: use of cat impossible in the presence of mutt.
    Found 15 errors.
    Try again. Goodbye.
    $

Then you can be pretty sure your script isn’t going to do unnecessary harm, and has some proper guardrails in place.

Re: Use Long Options in Scripts

#97

Earlier quoted context omitted.

Using nix has really spoiled me on this. Everyone gets the same versions of all the CLI utilities in the dev environment, whether on mac or linux, and those are the same versions that run in CI and any prod systems. It’s really nice being able to use whichever newer bash features or gawk extensions you like, without having to deal with trying to ensuring the mac engineers have brew-installed all the right stuff to ma…

nix didn't solve your issue here. nix didn't do anything. You're just describing the benefit of a reproducible development environment. You could do the same thing with brew, pacman, apt, or by just compiling every package from source from some huge mirror. It's exactly the same thing people initially loved about docker or vagrant.

Sure, but it works on Mac and Linux and doesn’t require virtualization. I think brew might qualify, but it can’t define which environment variables should be available in the developer shell or which hooks to run upon entry.

I don’t think any of the other options you specified can manage the same thing.

Re: Use Long Options in Scripts

#98

Earlier quoted context omitted.

Using nix has really spoiled me on this. Everyone gets the same versions of all the CLI utilities in the dev environment, whether on mac or linux, and those are the same versions that run in CI and any prod systems. It’s really nice being able to use whichever newer bash features or gawk extensions you like, without having to deal with trying to ensuring the mac engineers have brew-installed all the right stuff to ma…

Everyone has to use nix :) But yes, that is nice.

That is the caveat. I initially set it up such that it wasn’t required: you could choose to use it if you wanted to, and otherwise here is a list of specific versions things you must install, etc. Everyone ultimately chose to use nix, and now it’s required. Makes for a pretty easy setup though for new devs: install nix, then run `nix develop`, then `make setup`, and you’re off to the races.

Re: Use Long Options in Scripts

#99
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…

FreeBSD doesn’t come with bash though.

Re: Use Long Options in Scripts

#100
post #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 ($A…

On my system, `getconf ARG_MAX` is over 2m.

I have seen some heinously long cmdline strings, but nothing close to that. Usually when invocations have creeped up into the O(1k) character limit at places I've worked, I've implemented a "yaml as cmdline args" option to just pass a config file instead.

Have you seen scenarios where this is actually limiting?

Post reply on HN