我想检查一个文件是否是一个文件并且存在并且是否不为空,所以最终使用了-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'
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
我对斜线结尾处的内容不屑一顾
/path/to/dir/
,认为值得一提,但今天早上很难说清楚。也许在底部添加一个注释,以澄清是否存在斜线,它是目录吗?@Kamil Cuk mybe您正在使用不同的Bash版本(我在4.1.2(1)-发行版上),并且-s是不够的。如果我这样传递现有的目录路径:
if [[ -s "/opt/gmdemea/smartmap_V2/maps/" ]]; then echo "Exists"; else echo "Does not exists"; fi
它不是文件时返回“ Exists”,因此应该转到else子句并返回“不存在”。@PiotrPanczyk你是对的。我认为将dir视为大小为零的文件...:/
@EdMorton我认为是因为理论上
[[ a ]] || [[ b ]]
将运行两个进程,而[[ a || b ]]
仅运行一个。请注意,b
如果a
在两种情况下为false,都不会处理。较少的进程通常会导致脚本更快。而且输入的次数更少。我承认,我没有给这种说法不够想法(不过我想我反正站在它,还是会使用&&
||
内部[[
在我的脚本)@KamilCuk我和您理解'-s',并且在代码中单独使用,这使我陷入麻烦。这就是为什么开始对此进行调查。