如何从 /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
我想在创建新用户之前预测下一个 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 的第三个字段取最大值
$( ... )
代表命令的结果,这里是最大的idnewID=$(( ... + 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