我想检查一个文件是否是一个文件并且存在并且是否不为空,所以最终使用了-f
和-s
的组合检查。如果文件不存在或为空,我想提前返回,所以我同时取消了这两项检查。
要测试我的文件名返回空字符串并且我将路径传递到目录的情况,我正在尝试这样做:
if [[ ! -f "/path/to/dir/" ]] && [[ ! -s "/path/to/dir/" ]];
then echo "Does not exists"; else echo "Exists"; fi
存在
以上返回“ Exist”,这似乎不正确。
-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中是否有些奇怪?
编辑1: 如建议的那样,使用两种情况都放在同一括号中的符号进行尝试:
if [[ ! -f "/opt/gmdemea/smartmap_V2/maps/" && ! -s "/opt/gmdemea/smartmap_V2/maps/" ]]; then echo "Does not exists"; else echo "Exists"; fi
存在
但这不会改变行为。
编辑2:
从手册页看来,在这种情况下,-s
应该足够了,但是当传递现有目录路径时,它返回true(Bash版本:4.1.2(1)-release):
if [[ -s "/opt/gmdemea/smartmap_V2/maps/" ]]; then echo "Exists"; else echo "Does not exists"; fi
存在
它不是文件时返回“ Exists”,因此应该转到else子句,返回“不存在”
答案 0 :(得分:4)
拥有x AND y
,然后将其命名为NOT (x AND y)
。这等于(NOT a) OR (NOT b)
。 不等于(NOT x) AND (NOT y)
。
我要检查文件是否为文件且存在并且是否为空
如果要检查文件是否为常规文件,并且不为空,请执行以下操作:
[[ -f path ]] && [[ -s path ]]
取反(每行相等)(注意De Morgan's law):
! ( [[ -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
答案 1 :(得分:4)
@KamilCuk已经解释了逻辑缺陷,但总的来说-始终避免在代码中使用负数,例如!
在这种情况下,因为它们使代码比使用正数更难于阅读(正确)。代替:
if [[ ! -f "/path/to/dir/" ]] && [[ ! -s "/path/to/dir" ]]
then
echo "Does not exists"
else
echo "Exists"
fi
如果您应用布尔代数分解出!
,那么您将得到:
if ! ( [[ -f "/path/to/dir/" ]] || [[ -s "/path/to/dir" ]] )
then
echo "Does not exists"
else
echo "Exists"
fi
然后您可以将if / else翻转以摆脱最后的!
:
if [[ -f "/path/to/dir/" ]] || [[ -s "/path/to/dir" ]]
then
echo "Exists"
else
echo "Does not exists"
fi
一眼就能看到的不是您要进行的测试。相反,您想要:
if [[ -f "/path/to/dir/" ]] && [[ -s "/path/to/dir" ]]
then
echo "Exists"
else
echo "Does not exists"
fi