8 ms·
I stopped using [ a few years ago because ‘test’ reinforces the idea that this is just a command like any other, not syntax. Also, “man test” is much more plea
by cellularmitosis 3y ago
I stopped using [ a few years ago because ‘test’ reinforces the idea that this is just a command like any other, not syntax. Also, “man test” is much more pleasant that sifting through “man bash”.
- kazinator 3y agoYour comment makes no sense. GNU Coreutils has a "man [" as well as "man test" man page. Bash has "help test" for a quick cheatsheet. The [ command is very old; it was already present in Version 7 Unix in 1979.
- c0l0 3y agoParts of the comment make a LOT of sense actually, when you look at shell scripts written by the uninitated. Often times, I see constructs like while [ 1 ]; do ...; done which are a pretty clear indication of the author's misconception about the perceived nature of [ ], I think.
- kazinator 3y agoThe nice way to write that isn't any kind of test command but: while true; do ...; done There is never any reason to use test, other than portability to some broken environment that is missing [ but not missing test.
- tuyiown 3y ago> There is never any reason to use test What's the reason for always using [ ?
- Diti 3y ago> There is never any reason to use test test -d /nix && echo "$_ exists" || echo "$_ doesn’t exist" You cannot do this with [ – Don’t Repeat Yourself, and your scripts become more maintainable. (Not POSIX-compliant. Documented in Bash and Zsh.)
- teo_zero 3y ago> You cannot do this with [ Why not? [ -d /nix ] && echo ...
- forgotpwd16 3y agoAs '$_' is set to last arg of previous run command, the test example will have it be the name of directory whereas for [ will always be ].
- elteto 3y agoD=/nix test -d $D && echo $D exists …
- cagey 3y ago$ V=nada echo "x${V}x" xx
- Dylan16807 3y agoV=nada; echo "x${V}x"
- teo_zero 3y agoAh yes, now I see it.
- deleted 3y ago[deleted]
- deleted 3y ago[deleted]
- watersb 3y agowhile true; do ...; done Is `true` a builtin? I might want to avoid an external process call just to create an unconditional loop.
- kazinator 3y agoPOSIX allows any command to be a builtin, as long as a real external command is also available which can be executed via execv and whatnot. $ echo $BASH_VERSION 4.4.20(1)-release $ type true true is a shell builtin Also: $ type test test is a shell builtin $ type [ [ is a shell builtin
- Karellen 3y agoI think GP's point was that `[` feels like syntax, but - importantly - isn't. Yes, `[` is a command, and has a man page and everything, but in a script it doesn't look like a command. It looks like something "special" is going on. Whereas using `test` emphasises the point that you're just running another program. That all `if` does is check the output status of whatever program is being run, whether that's `test`/`[`, or `grep`, or anything else at all. (Personally, I don't think that emphasis is necessary. But I've been using shell scripts long enough that I understand these nuances fairly well without having to think about them much any more. So I think that GP's point is a reasonable perspective to have, and worth considering.)
- rascul 3y agoNote that bash implements [ as a builtin so the coreutils man page might not match exactly.
- tuyiown 3y agoI'm with you, the [ (and [[ bashism) introduces lots of confusions about what is really happening, I could never manage any real confidence. That said, [[ being guaranteed to be built-in certainly had its purpose at ages where shell script performance had any kind of relevance, and that was no so long ago.
- kqr 3y ago[[ has more to do with trying to build an intuitive shell scripting environment than performance. [[ makes conditionals behave much more like you'd expect from other programming languages. I think it's a great idea, but then again, if I don't have to care for POSIX portability, I'd rather use something that's not a shell language for scripting.
- DonHopkins 3y agoWhile they were at it, just to be consistent, they should have added syntax for easy-to-use non-fucked-up less-arbitrarily-punctuated versions of control structures, too: ifif [[ x == 1 ]] thenthen echo "x is one" elseelse echo "x is not one" fifi forfor x in 1 2 3 dodo echo "x is $x" donedone whilewhile [[ x == 1 ]] dodo echo "x is one" x=$((x + 1)) donedone untiluntil [[ x != 1 ]] dodo echo "x is not one" donedone The whole [[ ]] $(( )) ifif fifi dodo thing just seems like they're just doubling down instead of admitting they made a mistake. And if they really wanted [[ ]] to seem like syntax instead of a shell command, they could at least allow it to be used without spaces on each side of it like $(( )) or parens or brackets in any other language. And every other language lets you use as many redundant parens as you like for clarity, without running twice as many commands or producing a syntax error or weird unexpected behavior. But I don't think clarity was ever a design goal with Unix shell scripting languages.
- a1369209993 3y ago> arbitrarily-punctuated versions of control structures Ahem: if [ x = 1 ] then echo "x is one" else echo "x is not one" echo "namely, it's $x" fi `if [ ] ; then` should only ever be used in one-liners, where there is not a newline after `then`; I'm not sure how that ended up being taught as a way to write multi-line commands (I'd tenatively blame Pascal, but that's probably unfair).
- paiute 3y agoI’ll probably just use test after reading this, I write bash scripts infrequently enough that if statements always get me (whitespace). Now that i see the why it’s super obvious, and using test helps communicate that it’s just args