#!/bin/bash
dir=/home/john
name="kate"
if [ -d $dir ] && [ -n $name ]; then
echo "The name exists and the folder $dir exists."
else
echo "Fail"
fi
我刚刚执行了这个命令,它根本不起作用。只有当两个测试都成功时,这个命令才应该返回 true,否则它将失败。但是没有失败。
为什么?
先感谢您。
答案1
如果$dir
或$name
为空,则[ -d $dir ]
或[ -n $name ]
将评估为 TRUE,因为它们变成[ -d ]
和,测试文字字符串和[ -n ]
的非零长度,正如在相关问题的答案中更详细地讨论的那样:-d
-n
前任。
$ name=
$ [ -n $name ] && echo true || echo false
true
$ [ -n "$name" ] && echo true || echo false
false
所以你应该使用
if [ -d "$dir" ] && [ -n "$name" ]; then
然而如果你想知道文件 $dir/$name
存在,你应该用一个测试来做到这一点
if [ -f "$dir/$name" ]
如上所述@bac0n 的评论
答案2
我也来试试吧。现有的答案是正确的,但由于这是一个 Bash 问题,我可以建议使用 Bashism 吗?
#!/usr/bin/env bash
# Using $HOME so it should exist whenever someone tests this code
# btw: dir is not the best name here ... (shadows /bin/dir from coreutils)
dir=$HOME
name="kate"
if [[ -d $dir ]] && [[ -n $name ]]; then
echo "The name exists and the folder $dir exists."
else
echo "Fail"
fi
您可以看到内联注释。我还删除了多余的空行。
重点是我使用的是[[
而不是[
(以及相应的对应部分]]
而不是]
)。
help [
作为参考,您可能希望阅读和的输出help [[
。简而言之,是一个扩展版本,它还提供正则表达式支持,并且在许多其他情况下更智能。每当我被允许放弃与普通 POSIX shell 的兼容性时,[[
我都会习惯使用它来代替。[ expression ]
我不确定这是否能正确地称为“错误”(缺陷)。我认为这很可能是由于向后兼容性造成的。但我不能 100% 确定所谓的“错误”行为是否真的被编入了 POSIX 标准中。
进一步指出:
- 如果你想检查某个用户是否存在,你应该使用
id
或getent passwd
(无论哪个更适合你想要的)。你可以也可以使用eval echo ~$name
(如果$name
包含用户名)。不,这不是错误。扩展到所述用户的主目录,但只能通过(或提示符上的制表符完成)~username
的帮助。eval
- 您可能更愿意根据输出结果来判断某个用户(姓名),
getent passwd
而不是根据硬编码假设,比如主目录應該将在/home
...
但这只是我的一点看法... ;)