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

Shell 如何从/etc/passwd中提取最大的UID值?,shell,ubuntu,uid,etcpasswd,Shell,Ubuntu,Uid,Etcpasswd,我想在创建新用户之前预测下一个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=$biggestI

我想在创建新用户之前预测下一个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 |读取行时

它在子shell中运行
while
循环,因此在子shell中设置
biggestID
,而不是在父shell中

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

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-n1
    从passwd中的第三个字段获取最大值
  • $(…)
    代表命令的结果,这里是最大的id
  • newID=$(…+1))
    add1并将结果存储在newID中

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

      awk -F: 'BEGIN {maxuid=0;} {if ($3 > maxuid) maxuid=$3;} 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
      
      biggestID=0
      #不要用猫。。但是。。做完成<输入(不打开子shell)
      #使用read-r行(所以这行是字面意思)
      cat/etc/passwd |读取行时
      做
      #不要计算uid两次(在测试和分配中),而是存储在var中
      
      #uid=$(cut-d:-f3 Prehaps的可能重复您有一行,如
      nobody:x:65534:65533:nobody:/var/lib/nobody:/bin/bash
      ,希望跳过这一行。无用地使用Cat被认为是有害的:-)