Bash 参数问题

Bash 参数问题
#!/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 标准中。


进一步指出:

  1. 如果你想检查某个用户是否存在,你应该使用idgetent passwd(无论哪个更适合你想要的)。你可以也可以使用eval echo ~$name(如果$name包含用户名)。不,这不是错误。扩展到所述用户的主目录,但只能通过(或提示符上的制表符完成)~username的帮助。eval
  2. 您可能更愿意根据输出结果来判断某个用户(姓名),getent passwd而不是根据硬编码假设,比如主目录應該将在/home...

但这只是我的一点看法... ;)

相关内容