我想创建一个脚本来检查用户是否存在。我使用的逻辑如下:
# getent passwd test > /dev/null 2&>1
# echo $?
0
# getent passwd test1 > /dev/null 2&>1
# echo $?
2
如果用户存在,我们就成功,否则用户不存在。我已经把上面的命令在bash脚本如下:
#!/bin/bash
getent passwd $1 > /dev/null 2&>1
if [ $? -eq 0 ]; then
echo "yes the user exists"
else
echo "No, the user does not exist"
fi
现在,我的脚本总是说用户存在,不管怎样:
# sh passwd.sh test
yes the user exists
# sh passwd.sh test1
yes the user exists
# sh passwd.sh test2
yes the user exists
为什么上面的条件总是评估为TRUE,并说用户存在?
我哪里说错了?
更新:
在阅读了所有的回复后,我在我的剧本中发现了问题。问题是我重定向get输出的方式。所以我删除了所有重定向的东西,并使get行看起来像这样:
getent passwd $user > /dev/null
现在我的脚本运行正常。
实际上我无法重现这个问题。问题中编写的脚本工作正常,除了$1为空的情况。
但是,脚本中有一个与stderr重定向相关的问题。虽然存在两种形式&>和>&,但在您的情况下,您希望使用>&。您已经重定向了stdout,这就是&>表单不起作用的原因。你可以用下面的方法验证:
getent /etc/passwd username >/dev/null 2&>1
ls
您将在当前目录中看到一个名为1的文件。你想使用2>&1代替,或者使用这个:
getent /etc/passwd username &>/dev/null
这也将stdout和stderr重定向到/dev/null.
将stderr重定向到/dev/null可能不是一个好主意。当事情出错时,你将不知道为什么。
也可以通过id命令查看user。
Id -u name提供该用户的Id。
如果用户不存在,你得到命令返回值($?
正如其他回答所指出的:如果您只想检查用户是否存在,则直接使用if和id,就好像已经检查了退出码一样。没有必要去摆弄琴弦,[,$?(美元):
if id "$1" &>/dev/null; then
echo 'user found'
else
echo 'user not found'
fi
(不需要使用-u,因为你正在丢弃输出)
另外,如果你把这个代码片段转换成一个函数或脚本,我建议你也适当地设置退出码:
#!/bin/bash
user_exists(){ id "$1" &>/dev/null; } # silent, it just sets the exit code
if user_exists "$1"; code=$?; then # use the function, save the code
echo 'user found'
else
echo 'user not found' >&2 # error messages should go to stderr
fi
exit $code # set the exit code, ultimately the same set by `id`
实际上我无法重现这个问题。问题中编写的脚本工作正常,除了$1为空的情况。
但是,脚本中有一个与stderr重定向相关的问题。虽然存在两种形式&>和>&,但在您的情况下,您希望使用>&。您已经重定向了stdout,这就是&>表单不起作用的原因。你可以用下面的方法验证:
getent /etc/passwd username >/dev/null 2&>1
ls
您将在当前目录中看到一个名为1的文件。你想使用2>&1代替,或者使用这个:
getent /etc/passwd username &>/dev/null
这也将stdout和stderr重定向到/dev/null.
将stderr重定向到/dev/null可能不是一个好主意。当事情出错时,你将不知道为什么。