如何从 /etc/passwd 中提取最大的 UID 值?

How do I extract the biggest UID value from /etc/passwd?

我想在创建新用户之前预测下一个 UID。 由于新的将采用最大的 ID 值并将其加 1,因此我想到了以下脚本:

biggestID=0
cat /etc/passwd | while read line
do
if test [$(echo $line | cut -d: -f3) > $biggestID]
then
biggestID=$(echo $line | cut -d: -f3)
fi
echo $biggestID
done
let biggestID=$biggestID+1
echo $biggestID

结果我得到 1。这让我很困惑,我认为问题出在循环上,所以我在 fi 下面添加了 echo $biggestID 来检查它的值是否真的在改变,结果发现循环没有问题,因为我有很多值直到 1000。那么为什么 biggestID 的值在循环后返回到 0

是因为这一行:

cat /etc/passwd | while read line

在子 shell 中运行 while 循环,因此 biggestID 在子 shell 中设置,而不是在父 [=26] 中设置=].

如果您将循环更改为以下内容,它将起作用:

while read line
...
done < /etc/passwd

这是因为 while 循环现在 运行 在与主脚本相同的 shell 中,而您只是将 /etc/passwd 的内容重定向到循环。

你可以把程序改成这样:

newID=$(( $(cut -d: -f3 /etc/passwd | sort -n | tail -n 1 ) +1 ))
echo $newID
  • cut -d: -f3 /etc/passwd| sort -n | tail -n 1从passwd
  • 的第三个字段取最大值
  • $( ... )代表命令的结果,这里是最大的id
  • newID=$(( ... + 1 )) 加 1 结果存入 newID

使用 awk,您可以在一个程序中完成所有计算:

awk -F: 'BEGIN {maxuid=0;} {if ( > maxuid) maxuid=;} END {print maxuid+1;}' /etc/passwd

如果您还不想开始使用 awk,请提供一些关于您的代码的反馈。

biggestID=0
# Do not use cat .. but while .. do .. done < input (do not open subshell)
# Use read -r line (so line is taken literally)
cat /etc/passwd | while read line
do
   # Do not calculate the uid twice (in test and assignment) but store in var
   # uid=$(cut -d: -f3 <<< "${line}")
   # Use space after "[" and before "]"
   # test is not needed, if [ .. ] already implicit says so
   # (I only use test for onelines like "test -f file || errorfunction")
   if test [$(echo $line | cut -d: -f3) > $biggestID]
   then
      biggestID=$(echo $line | cut -d: -f3)
   fi
   # Next line only for debugging
   echo $biggestID
done
# You can use (( biggestID = biggestID + 1 ))
# or (when adding one)
# (( ++biggestID ))
let biggestID=$biggestID+1
# Use double quotes to get the contents literally, and curly brackets
# for a nice style (nothing strang will happen if you add _happy right after the var)
# echo "${biggestID}" 
echo $biggestID