2

我想在创建新用户之前预测下一个 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. 这让我很困惑,我认为问题出在循环上,所以我添加了echo $biggestID下面fi的内容来检查它的值是否真的在变化,结果证明循环没有问题,因为我得到了很多高达 1000 的值。那么为什么是循环后biggestID返回的值吗?0

4

3 回答 3

2

这是因为这条线:

cat /etc/passwd | while read line

这在子外壳中运行while循环,因此biggestID在子外壳中设置,而不是在父外壳中。

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

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

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

于 2016-02-28T12:50:23.233 回答
1

你可以把程序改成这样:

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 中
于 2016-02-28T12:59:17.760 回答
1

使用 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
于 2016-02-28T13:59:29.040 回答