温馨提示:本文翻译自stackoverflow.com,查看原文请点击:linux - Combining two negated file check conditions (-f and -s) seems to return incorrect result
bash linux

linux - 结合两个否定的文件检查条件(-f和-s)似乎返回错误的结果

发布于 2020-03-27 10:17:43

我想检查一个文件是否是一个文件并且存在并且是否不为空,所以最终使用了-f的组合检查-s如果文件不存在或为空,我想提前返回,所以我同时取消了这两项检查。

为了测试我的文件名返回空字符串并且将路径传递到目录的情况,我正在尝试这样做:

if [[ ! -f "/path/to/dir/" ]] && [[ ! -s "/path/to/dir/" ]]; 
then  echo "Does not exists"; else echo "Exists"; fi

存在

以上返回“存在”,这似乎不正确。

-f 单独检查是否正确:

if [[ ! -f "/path/to/dir/" ]]; then  echo "Does not exists"; 
else echo "Exists"; fi

不存在

合并检查但不排除每个检查也是正确的:

if [[ -f "/path/to/dir/" ]] && [[ -s "/path/to/dir/" ]]; 
then  echo "Exists"; else echo "Does not exists"; fi

不存在

不知道将逻辑和与否定条件组合在一起时,Bash是否做错了&&什么?

Edit 1: As suggested tried with notation where both conditions are in the same set of brackets:

if [[ ! -f "/opt/gmdemea/smartmap_V2/maps/" && ! -s "/opt/gmdemea/smartmap_V2/maps/" ]]; then  echo "Does not exists"; else echo "Exists"; fi

Exists

But that does not change the behavior.

Edit 2: From man page it seems that in this situation -s should be enough but when passed existing directory path it returns true (Bash version: 4.1.2(1)-release):

if [[ -s "/opt/gmdemea/smartmap_V2/maps/" ]]; then echo "Exists"; else echo "Does not exists"; fi 

Exists

It returns 'Exists' while it is not a file so should be going to else clause returning 'Does not exists'

查看更多

查看更多

提问者
Piotr Panczyk
被浏览
270
KamilCuk 2019-07-03 22:08

Having x AND y, then nagating it you get: NOT (x AND y). This is equal to (NOT a) OR (NOT b). It is not equal to (NOT x) AND (NOT y).

I want to check if a file is a file and exists and if it is not empty

If you want to check if a file is a regular file and if it is not empty, then you do:

[[ -f path ]] && [[ -s path ]]

否定将是(每行相等)(请注意De Morgan定律):

! ( [[ -f path ]] && [[ -s path ]] )
[[ ! -f path || ! -s path ]]

您也可以这样写(每行相等):

! [[ -f path && -s path ]]
[[ ! ( -f path && -s path ) ]]
[[ ! -f path ]] || [[ ! -s path ]]
# or using `[` test and `-a` and `-o`:
! [ -f path -a -s path ]
[ ! -f path -o ! -s path ]
[ ! \( -f path -a -s path \) ]

所以就:

if [[ ! -f "/path/to/dir/" || ! -s "/path/to/dir/" ]]; then
     echo "The /path/to/dir is not a regular file or size is nonzero"
else
     echo "The path /path/to/dir is a regular file and it's size is zero"
fi