Live data from Hacker News

Use long flags when scripting (2013)

changelog.com

51–60 of 197 posts

Re: Use long flags when scripting (2013)

#51
post #13

Earlier quoted context omitted.

This attitude is definitely something that makes my life harder. My OS is usually OpenBSD, and I constantly need to fix other people's scripts. It's not difficult to do, but it is annoying. I don't blame people for ignorance, but it'd be nice if people thought about portability. Non-portable scripts can also bite you on Linux, where Debian, for example, will swap out the shell from bash to dash for performance. but o…

Sounds to me like your choice of OS is what makes your life harder...

It makes my life easier in most ways. This is one of the costs.

And, again, this still bites whenever using different linux distros.

Re: Use long flags when scripting (2013)

#52

Great suggestion, but I'd go for a middle ground: use long flags for the long tail, but short flags are fine for stuff that's very commonly used. I think I'll continue to write these: grep -i rm -rf ln -s gzip -v sed -e instead of: grep --ignore-case rm --recursive --force ln --symbolic gzip --verbose sed --expression If you're working on shell scripts, you probably know certain short flags well enough that long flag…

The short flags are really there for when you're doing things interactively. For scripts that are read and executed more often than they're written or changed, the long flags really help ensure you don't fat-finger. I'm accustomed to typing `rm -rf` when really I just need `rm -r` in a lot of cases, and in PRs it's very easy for your eyes to glaze over when there's more than a single short flag.

Why are you more likely to typo something in a script you can read, review, and test than an interactive command prompt that executes immediately?

Re: Use long flags when scripting (2013)

#53
post #2

If you're trying to stick to the POSIX standard, you have to use short options for standard commands like grep, since the long options are GNU extensions.

Unless you count things like Makefiles, I don't think I've ever written or encountered a "script" that was intended for use on multiple *nix flavors. This strikes me as a YAGNI situation: do it if it comes up, but not before.

I think that's a reasonable attitude to have for your own personal scripts that you use on your own machines. But for stuff you do for work it might make sense to go for portability. Where I work most people develop on macOS, and our infra runs on Linux. I happen to develop on Linux, but if I'm writing development scripts that are intended to be run locally, I can't assume that GNU tools will be installed everywhere.

Re: Use long flags when scripting (2013)

#54
This is how I write PowerShell scripts. I use full cmdlet names, full argument switch names, and I even specify argument switches to positional arguments. I also do my best to honor common flags like `-WhatIf`, `-Verbose`, and `-ErrorAction`. So I end up with scripts like this:

    if (-not $(Test-Path -Path "$Path" -PathType Container)) {
        Write-Error -Message "Path ($Path) does not exist or is not a directory." -Category InvalidArgument;
        return;
    }
When you do this properly, it feels like magic. For example, I wrote a script that does local Maven and Docker builds for a bunch of related projects. So I wrote two functions `Build-Maven` and `Build-Docker` with proper common flag support and error handling. Then, when I use them, I just do something like this:

    $PSDefaultParameterValues = @{
        'Build-Maven:ErrorAction' = 'Stop';
        'Build-Docker:ErrorAction' = 'Stop';
    };

    Build-Maven "$Path\A";

    Build-Maven "$Path\B";
    Build-Docker -Path "$Path\B" `
        -Dockerfile "$Path\B\Dockerfile" `
        -Tag "B:$Tag";
That first clause automatically amends `Build-Maven` and `Build-Docker` commands with `-ErrorAction Stop`. So if any of those build commands fail, the entire script halts there. And, if I pass in `-Verbose` to this script, that's forwarded to the build commands and I'll see the Maven and Docker build output.

Re: Use long flags when scripting (2013)

#55

Earlier quoted context omitted.

The short flags are really there for when you're doing things interactively. For scripts that are read and executed more often than they're written or changed, the long flags really help ensure you don't fat-finger. I'm accustomed to typing `rm -rf` when really I just need `rm -r` in a lot of cases, and in PRs it's very easy for your eyes to glaze over when there's more than a single short flag.

You literally always need -f with -r in a script (unless you want rm to prompt the user), though...

You must have an alias rm='rm -i' lying around. rm doesn't prompt by default (unless you're the owner of the dir, but not its contents).

    mkdir demodir && touch demodir/{foo,bar} && rm -r demodir

Re: Use long flags when scripting (2013)

#56
post #37

Earlier quoted context omitted.

It's nice but you cannot comment individual lines. For that you can go one step further and use arrays: cmd=( command -x -y --bar OPTARG ARG ARG ) $cmd This works in Zsh. In Bash that would be ${cmd[@]} I think. I use this with long qemu command lines where I often modify and comment out arguments during testing.

You can comment using a hack; check this out: command `# a comment` \ --longopt1 `# another comment` \ --longopt2 arg \ argument

I didn't mean commenting arguments for documentation but commenting them out while you're writing and testing the script. I.e. this won't work:

  command `# a comment` \
    # --longopt1 \
    --longopt2 arg \
    argument
AFAIK there's no hack for this.

EDIT: Oh, `# a comment`. Didn't notice that. I'm going to explore it, thanks.

Re: Use long flags when scripting (2013)

#57
post #40

Earlier quoted context omitted.

Particularly in this case, because `-v` sometimes means "print out the version number".

That's why they mentioned `grep -v`. Go look it up. It doesn't mean verbose OR version. Doubt you'd be printing out a version number in a shell script though.

You may want to compare a version number of a command to make sure it's bigger than (or equal to) the minimum version required by your script, though.

Re: Use long flags when scripting (2013)

#58

Great suggestion, but I'd go for a middle ground: use long flags for the long tail, but short flags are fine for stuff that's very commonly used. I think I'll continue to write these: grep -i rm -rf ln -s gzip -v sed -e instead of: grep --ignore-case rm --recursive --force ln --symbolic gzip --verbose sed --expression If you're working on shell scripts, you probably know certain short flags well enough that long flag…

I agree. To me, "sed -e" is an expression as a whole, and replacing -e with --expression is on the same level as aliasing "sed" to "stream-editor".

Though I would make the list of "allowed" short flags very short. I can't think of many more than the ones you listed:

  mkdir -p
  sh -c
  cp -r
  tar -xaf
  tar -caf

Re: Use long flags when scripting (2013)

#59
post #3

In scripts, I usually do stuff like this command \ --longopt1 \ --longopt2 arg \ argument or command | \ command 2 | \ command 3 \ --opt1 \ --opt2 \ arg

If I'm splitting across lines, I prefer to put the pipe _after_ the newline. Otherwise, I like the cut of your jib, and will likely do this with arguments in scripts from now on.

Re: Use long flags when scripting (2013)

#60

Earlier quoted context omitted.

You literally always need -f with -r in a script (unless you want rm to prompt the user), though...

You must have an alias rm='rm -i' lying around. rm doesn't prompt by default (unless you're the owner of the dir, but not its contents). mkdir demodir && touch demodir/{foo,bar} && rm -r demodir

IIRC 'rm -r' prompts by default for read-only files as well even if you own them.
Post reply on HN