Negating multiple conditions in Bash

不想你离开。 提交于 2019-12-20 04:15:39

问题


I realize this is a simple question, but I am finding a hard time getting an answer due to the finnicky syntax requirements in bash. I have the following script:

if ! [ [ -z "$1" ] || [ -z "$2" ] ]; then
  echo "both arguments are set!"
fi

I get the following output when I run it without arguments:

./test: line 3: [: -z: binary operator expected 
both arguments are set!

I am not expecting any output - neither argument is set. What am I doing wrong?


回答1:


The test shell builtin [ supports the arguments -a and -o which are logical AND and OR respectively.

#!/bin/sh 

if [ -n "$1" -a -n "$2" ]
then echo "both arguments are set!"
fi

Here I use -n to check that the strings are non-zero length instead of -z which shows that they are zero length and therefore had to be negated with a !.

" -n string True if the length of string is nonzero."

"-z string True if the length of string is zero."

If you are using bash it also supports a more powerful type of test [[]] which can use the boolean operators || and &&:

#!/bin/bash 

if [[ -n "$1" && -n "$2" ]]
then echo "both arguments are set!"
fi

In comments it was addressed that none of these samples show how to negate multiple tests in shell, here is an example which does:

#!/bin/sh 

if [ ! -z "$1" -a ! -z "$2" ]
then echo "both arguments are set!"
fi



回答2:


Square brackets are not a grouping construct in bash. [ is just an alias for the test command, the arguments are parsed normally. And || is a shell operator that separates commands.

If you want to group multiple commands, you can use the () subshell syntax.

if ! ([ -z "$1" ] || [ -z "$2" ]);

or the { } grouping syntax:

if ! { [ -z "$1" ] || [ -z "$2" ]; };

Or you could use a single call to test, with its built-in -o operator:

if ! [ -z "$1" -o -z "$2" ]



回答3:


Remember (or learn!) that [ is not part of shell syntax, it is a command.

If you want to group together multiple commands, then you should use { }

if ! { [ -z "$1" ] || [ -z "$2" ]; }

Note that the parser expects to see a line ending or semicolon before the closing }.

For the record, I'd avoid the negation and use && here:

if [ -n "$1" ] && [ -n "$2" ]

...and since you specified bash, you may as well take advantage of the enhanced test construct:

if [[ -n $1 && -n $2 ]]


来源:https://stackoverflow.com/questions/33010480/negating-multiple-conditions-in-bash

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!