1

I'm using bash 5.0.7, and hope that I can expand the variable And="&&" and Or="||" in the double square brackets:

$ [[ 1 > 0 $And 1 < 0 ]] 
bash: syntax error in conditional expression
bash: syntax error near `$And`
$ [[ 1 > 0 ${And} 1 < 0 ]] 
bash: syntax error in conditional expression
bash: syntax error near `${And}`

I hope there's a way to do this because that will largely simplify one of my codes. And also, any explanations will be highly appreciated: I am really curious about how sh/bash works! Thank you very much in advance.

8
  • I don't think you can do that without eval (which might involve quoting hell with the other parts of your test). Can you show what you're trying to achieve in the end? Perhaps there might be some other way to do what you want.
    – ilkkachu
    Jul 22, 2019 at 13:24
  • I'm really skeptical that would simplify your code. But if you're curious how bash works, then please notice that [[ a > b ]] will do a lexicographical comparison on its operands: [[ 2 > 11 ]] && echo 2 is greater than 11 (and to add insult to injury, they'll do it using the current locale ;-)).
    – user313992
    Jul 22, 2019 at 15:08
  • Even though it will be more verbose code, you're going to be better off just using an if or case based on $And rather than trying to shoe-horn it into the [[ command. Jul 22, 2019 at 16:13
  • I want my script to run between certain time, for example between 10am to 9:30pm: start=100000; end=213000. The problem is when end is over midnight, e.g. end=020000, I want $now to be larger than $start OR smaller than $end instead of AND. Is there another nonverbose way to do it?
    – Student
    Jul 22, 2019 at 20:35
  • 1
    If end before start, add 24h to end. If now before start, add 24h to now. Then compare. Jul 23, 2019 at 1:06

1 Answer 1

1

It works with the test and [ builtin and -a (for &&) and -o (for ||):

$ and_or=-a
$ [ 1 -gt 0 $and_or 1 -lt 0 ] && echo yes || echo nope
nope
$ test 1 -gt 0 $and_or 1 -lt 0 && echo yes || echo nope
nope
$ and_or=-o
$ [ 1 -gt 0 $and_or 1 -lt 0 ] && echo yes || echo nope
yes
$ test 1 -gt 0 $and_or 1 -lt 0 && echo yes || echo nope
yes

(tested with bash 3.2.57 / 4.4.12 / 5.0.3)

As pointed out in the comments, I replaced the lexicographic comparison operators > and < with its arithmetic versions -gt and -lt.

But I would say this is quite a hack...

2
  • I always regard [ as a more primitive version of [[ so I did not expect that. Probably I should change my point of view..
    – Student
    Jul 22, 2019 at 20:37
  • 1
    @Student In some sense the approach works because [ is more primitive. In general it's a command or a builtin (the latter in Bash), so it gets its arguments like any other external command: they are processed in the shell before the command even runs and any of them can be taken from a variable. [[ is a keyword in Bash. It alters the parser: up to the next ]] the rules are somewhat different. This is obviously more complex. Jul 23, 2019 at 0:47

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .