以下是我被要求做的事情:
编写脚本以提示用户输入有效的uid。在脚本中验证以下内容并不断提示用户,直到他们提供有效输入(使用循环)。告诉我你的脚本,它工作,即你做了一些测试。在您的反馈中应满足以下要求并进行测试:
我不确定他的意思是数字小于65537或数字超过1000,但这是我迄今为止所拥有的。
#!bin/bash
read -p "Enter a username: " uname
users=`awk -F: '{print $1}' /etc/passwd | sort`
while [[ -z "$uname ]]; do
echo""
echo "Error: Must supply a username!"
echo ""
read -p "Enter a username: " uname
echo ""
for user in $users; do
if [[ "$user" == "$uname" ]]; then
echo "$uname exists"
break
else
echo "doen't exist"
fi
done
for user in $users; do
if [[ "$user" == "$uname" ]]; then
echo "$uname exists"
exit
else
echo "doesn't exist"
exit
fi
done
显然我对此非常荒谬,所以任何帮助都会令人难以置信
答案 0 :(得分:2)
#!/bin/bash
until (( uid < 65537 )) && (( uid > 1000 )) && ! getent -s files passwd $uid > /dev/null
do
read -p "Enter a UID: " uid
if(( uid > 65537 )) || (( uid < 1000 )); then
echo "UID must be within 1001 - 65536" >&2
elif getent -s files passwd $uid > /dev/null; then
echo "UID $uid is already in use" >&2
fi
done
虽然您的问题指定了/etc/passwd
文件,但建议您使用getent
实用程序。通过添加-s files
选项,它会告诉getent
从files
支持的密码读取。
答案 1 :(得分:0)
#!/usr/bin/env bash
declare -a uids_in_use=( )
while IFS=: read -r _ _ file_uid _; do
(( f )) && uids_in_use[$file_uid]=1 ||:
done </etc/passwd
while read -r -p "Enter a UID:" entered_uid; do
if (( entered_uid < 1000 )); then
echo "UIDs below 1000 are reserved for system use!" >&2
continue
fi
if (( entered_uid > 65536 )); then
echo "Maximum UID value is 65536!" >&2
continue
fi
if [[ ${uids_in_use[$entered_uid]} ]]; then
echo "UID $entered_uid is already in use!" >&2
continue
fi
echo "UID $entered_uid is acceptable!"
break
done
注意事项:
while read
循环,如BashFAQ #1中所述。在这种特殊情况下,IFS=: read -r _ _ uid _
将行的第三个字段读入变量uid
,通过将其结果分配给占位符变量{{1}来丢弃第一个,第二个字段和所有后续字段集。 }}。for
,关于_
是不良做法。 (这会扩展全局 - 从而用{}替换for user in $users
的条目,忽略引用并转换为拆分IFS中的空格或其他字符等等。*
创建算术上下文。请参阅http://wiki.bash-hackers.org/syntax/arith_expr - 在此上下文中,C样式语法可用于整数数学。 (对于需要浮点数学的其他情况,请参阅BashFAQ #22)。(( ))
声明一个数字索引数组。请参阅http://wiki.bash-hackers.org/syntax/arrays和BashFAQ #5。 bash中的数组是稀疏的 - 也就是说,你可以在它之前没有999个其他元素的情况下分配给元素1000,这是我们在这里使用的属性。 declare -a
分配给数组元素,而array[$idx]=value
执行查找。答案 2 :(得分:0)
我这样做
# validate the new uid is in the usable range or error
valid_range() {
local uid="$1"
if [[ $uid -lt 65537 && $uid -gt 1000 ]]; then
return 0
else
echo "Invalid range" >&2
return 1
fi
}
# make sure the uid is not in use
unused() {
local uid="$1"
awk -F: -v u=$uid '{if ($3 == u){print "Uid in use"; exit 1} }' /etc/passwd
}
declare -i new_uid=''
while sleep .5; do
read -rp "Enter a new uid: " new_uid;
if valid_range $new_uid && unused $new_uid; then
break # exit once we get a valid unused uid
fi
done
我只接受整数,我有一个小的内置睡眠以保持它的皮带,我有错误信息解释发生了什么,它相当小,很容易读取。