即使结果为真,Shell 脚本仍会继续执行

即使结果为真,Shell 脚本仍会继续执行

我有一个简单的 shell 脚本来检查用户是否存在,如果不存在,则添加该用户

#!/usr/bin/bash
echo "Enter user"
read -r user
if [ "$(id -u "$user" &>/dev/null)" = 1 ]; then
  echo "user existed"
else
  useradd "$user"
  echo "add password"
  passwd "$user"
  echo "$user" &>>text.txt
  echo "saved"
fi

但它不显示"echo user exist"。而是显示如下内容:

Enter user

abcdef

useradd: user 'abcdef' already exists

add password

New password: 

在这种情况下abcdef是现有用户

请让我知道这里出了什么问题,非常感谢。

答案1

您的脚本中存在以下条件:

if [ "$(id -u "$user" &>/dev/null)" = 1 ]; then

永远不会是真的。仅有的如果输出命令的id -u "$user" &>/dev/null将是一个数字 1,但是由于该命令的任何输出都被重定向到/dev/null,所以这种情况永远不会发生。

将该行替换为

if { id -u "$user" &>/dev/null ; } then

此条件检查退出状态命令(而不是其输出就像$(...)这样做),并且如果命令id -u "$user" &>/dev/null 成功(即用户存在)并且如果失败(即用户不存在)。

答案2

@raj 的回答对于简化代码来说是 100% 正确的。

这些只是使用退出代码的一些替代方法,也许可以更清楚地说明如何使用它们。

echo $?可以通过在命令后立即执行来检查退出代码id -u $user &>/dev/null,该命令不需要被包裹$(..)或类似的东西。

只需尝试id -u <username> &>/dev/null然后输入echo $?以检查退出代码。

例子:

terrance@terrance-ubuntu:~$ id -u terrance &>/dev/null
terrance@terrance-ubuntu:~$ echo $?
0
terrance@terrance-ubuntu:~$ id -u mark &>/dev/null
terrance@terrance-ubuntu:~$ echo $?
1

在上面的例子中,该用户mark在我的计算机上不存在,因此退出状态为 1。

使用退出代码,您可以将其放入case语句中而不是if..else语句中。

#!/bin/bash
echo "Enter username"
read -r user
id -u "$user" &>/dev/null
case $? in
    0) echo "User exists";;
    1) adduser $user
       echo "add password"
       passwd $user
       echo $user >> text.txt
       echo "saved";;
esac

有趣的是,if [ ]; then通过在 if 检查中添加 an,仍然可以使用an echo $?,但我确实注意到您正在检查 1 是否存在,但 1 表示代码以 1 表示未找到而退出。

添加它也会像这样工作。

#!/bin/bash
echo "Enter username"
read -r user
if [ $(id -u "$user" &>/dev/null; echo $?) == 0 ]; then
    echo "User exists"
else
    adduser $user
    echo "add password"
    passwd $user
    echo $user >> text.txt
    echo "saved"
fi

相关内容