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

时间:2016-02-28 12:33:54

标签: shell ubuntu uid etcpasswd

我想在创建新用户之前预测下一个UID。 由于新的ID值将获得最大的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

3 个答案:

答案 0 :(得分:2)

这是因为这一行:

cat /etc/passwd | while read line

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

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

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

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

答案 1 :(得分:1)

您可以将程序更改为以下内容:

    module ActionController
        module ParamsWrapper

            Options.class_eval do
                def include
                    return super if @include_set

                    m = model
                    synchronize do
                        return super if @include_set
                        @include_set = true
                        unless super || exclude
                            if m.respond_to?(:attribute_names) && m.attribute_names.any?
                                self.include = m.attribute_names + nested_attributes_names_array_of(m)
                            end
                        end
                    end
                end

                private 
                    # added method. by default code was equivalent to this equaling to []
                    def nested_attributes_names_array_of model
                        model.nested_attributes_options.keys.map { |nested_attribute_name| 
                            nested_attribute_name.to_s + '_attributes' 
                        }
                    end
            end

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

答案 2 :(得分: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