4 ms·
This problem isn't a Bash problem, nor is it a shell problem. '[' is a binary that takes a set of args terminates with a ']'. It's often just a symlink to the '
by yes_or_gnome 9y ago
This problem isn't a Bash problem, nor is it a shell problem. '[' is a binary that takes a set of args terminates with a ']'. It's often just a symlink to the 'test' binary.
The other "problem" is quoting. In which case what would you expect to happen? Most people avoid spaces in file paths for this very issue. Argument passing is whitespace separated, so an application has no idea that you meant two (or more) args to be just one. Simple solution, use quotes.
If you were to shun all CLI usage in favor of another programming language, then you would be doing the exact same thing with system calls; Using the example from the article for consistency (even though it wouldn't make much sense in a more expressive language):
var = "some value";
exec("[", "-z", var, "]");
- tedmiston 9y agoI was referring to replacing the logic with Python, ie: if var is not None: ... else: ... Or if not var: ... Or if var == '': ... Etc. Depending on what you want to achieve. That is a lot more readable to me than: [ -z $var ]
- yes_or_gnome 9y agoThere's no disagreement there. Let's remember that `test` is older than most programming languages. I can't find an exact date, but 1979 is the earliest mention of it being in `sh v7` and turned into a UNIX System III built-in in 1981. And, that it was created to solve a problem where there is no type system, so there can be no test for NULL The Bash-ism `[[` (Compound Conditional) is an attempt to reduce the unintuitiveness of `[` or `test`. However, you would still need to quote "$var". The biggest pain point of using an external application like `[` is that `&&` is a shell construct. As you may know, `&&` means "if the previous program succeeds, then execute this next statement. But, if you do `[ -z "$var" && ...`, then `[` will always fail because the command lacks the terminating arg `]`. To do conditionals with `[` you would have to use `-a` for "and" or `-o` for "or". You would want to do either `[ -z "$foo" ] && [ -z "$bar" ]` or `[ -z "$foo" -a "$bar" ]`. Conditional Expressions relieve those issues as `&&` and `||` will work between the braces. So, `[[ -z "$foo" && -z "$bar" ]]` is okay. (Some other pain points to `test` are `=` tests for string equality, not assignment; although, `==` is a synonym. For numerical equality testing, there are `-eq`, `-ne`, `-lt`, `-gt`, etc. Then, for those unfamiliar with the Unix way (and even, to some extend, to those who are), there are three cryptic sets of tests for File Type, Access Permission, and File Characteristics.) But, then, Conditional Expressions makes a few head scratching changes. Like `<` and `>` are for sorting strings; not numbers. And, instead of leaving `-a` and `-o` as-is, they were remapped so that `-a` is synonymous with `-e` (wat?) and that `-o` is for testing shell options. (Doing a little research tell me that `[[` comes from `ksh88`, so maybe they're there for parity.) Manpage for `test`, `[`: https://www.mankier.com/1/test https://www.mankier.com/1/test Conditional Expressions: http://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html http://www.gnu.org/software/bash/manual/html_node/Bash-Condi...