0

If i want to combine the -a and -o script operators in an if statement, how could I do that? For example:

if [ ( -e file.txt -a -r file.txt ) -o ( -e file2.txt -a -r file2.txt ) ]; then .... fi

Can I accomplish something like this? Right now I'm getting an error when I try to run this.

2
  • 1
    In general, instead of writing "I'm getting an error" please don't leave use guessing but state clearly and completely what the error message is. Same thing for "when I try to run this" please show us exactly how you run it Commented Sep 24, 2021 at 22:18
  • In this particular case, you could just drop the -e tests, since -r includes the test for existence. So just if [ -r file.txt ] && [ -r file2.txt ]; then ...
    – ilkkachu
    Commented Sep 25, 2021 at 7:49

1 Answer 1

2

Use double brackets (see Why does parameter expansion with spaces without quotes work inside double brackets "[[" but not inside single brackets "["?). Use the && and || double-bracket condition operators instead of the -a and -o test/single-bracket condition operators. This works in bash, also in ksh and zsh, but not in plain sh.

if [[ ( -e file.txt && -r file.txt ) || ( -e file2.txt && -r file2.txt ) ]]; then

Alternatively, with single brackets, use [ around single checks, use the && and || shell operators outside of brackets instead of using the -a and -o test operators inside brackets, and use { … } for grouping (see Difference between parentheses and braces in terminal?). This works in any sh-style shell.

if { [ -e file.txt ] && [ -r file.txt ]; } ||
   { [ -e file2.txt ] && [ -r file2.txt ]; }
then …

Alternatively, you can use \( and \) (or any other way of quoting the parentheses) inside single brackets (again, see Why does parameter expansion with spaces without quotes work inside double brackets "[[" but not inside single brackets "["? for an explanation). However this can cause the condition to be parsed incorrectly if a file name looks like a test operator ((, =, -e, …).

3
  • @zevzek For example, if the first file.txt is ) and the second file.txt is =, the first half of the command is [ \( -e \) -a -r = \) and that leads to a syntax error. I think with a little more work you can find an example that is accepted but parsed in an unintended way. Commented Sep 24, 2021 at 19:38
  • @zevzek I took ( -e file.txt -a -r file.txt ) and replaced the file names by ) and = respectively. The closing parenthesis that was intended to be recognized as one is present. Yes, it's a syntax error. That's the point. Commented Sep 24, 2021 at 19:57
  • @zevzek What statement are you talking about? The general wisdom around [ … ] is not to use it with compound conditions to avoid the risk of unintended parses: only use a single operator, don't use -a or -o. This isn't specifically about parentheses. Commented Sep 25, 2021 at 7:37

You must log in to answer this question.

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