我正在尝试用bash编写一个脚本来读入参数(用户名),然后通过搜索/ etc / passwd文件返回有关该用户名的信息。我不是服务器上的根,我正在编写脚本,但我不需要。这是我到目前为止的代码,但我不认为我正在使用grep命令。
#!/bin/bash
if [ $# -eq 1 ]; then #if num of args =1; then continue on
UNAME=$1 #set arg to var UNAME
grep UNAME=$(grep $/etc/passwd)
if [ $UNAME == /etc/passwd ]; then #if UNAME exists then display info below
echo "-------------------------------------------"
echo "Username: $(grep UNAME/etc/passwd/ $f1) "
echo "User ID (UID): $(grep UNAME/etc/passwd/) "
echo "Group ID (GID): $(grep UNAME/etc/passwd/) "
echo "User info: $(grep UNAME/etc/passwd/) "
echo "Home directory: $(grep UNAME/etc/passwd/) "
echo "Command shell: $(grep UNAME/etc/passwd/) "
echo "-------------------------------------------"
else #if UNAME is nonexistant then display this error message
echo "-------------------------------------------"
echo ""$UNAME" does not exist."
echo "-------------------------------------------"
fi
fi
if [ $# -eq 0 ]; then #if num of args =0; then display this
echo "Not enough arguments provided."
echo "USAGE: $0 <user_name> [user_name] ..."
exit 1
fi
答案 0 :(得分:2)
你做得太多了。 grep是您尝试进行的解析类型的错误工具。这里给出的解决方案非常草率,因为它为您查询的每个用户读取一次passwd文件,而不是一次性报告所有内容,但这并非不合理:
#!/bin/sh
for UNAME; do
while IFS=: read login passwd uid gid name home shell; do
if test "$login" = "$UNAME"; then
echo "-------------------------------------------"
echo "Username: $login"
echo "User ID (UID): $uid"
echo "Group ID (GID): $gid"
echo "User info: $name"
echo "Home directory: $home"
echo "Command shell: $shell"
echo "-------------------------------------------"
continue 2
fi
done < /etc/passwd
echo "No entry for user $UNAME" >&2
done
答案 1 :(得分:0)
在我得到解释之前,我将编写你的剧本:
cat ./test.sh
#!/bin/bash
UNAME=${1} #set arg to var UNAME
if [ -z ${UNAME} ]; then #if no argument is provided; then display this
echo "Not enough arguments provided."
echo "USAGE: $0 <user_name>"
exit 1
fi
if grep ${UNAME} /etc/passwd >/dev/null; then #if UNAME exists then display info below
echo "-------------------------------------------"
echo "Username: $(awk -F ':' -v uname=${UNAME} '$0 ~ uname {print $1}' /etc/passwd)"
echo "User ID (UID): $(awk -F ':' -v uname=${UNAME} '$0 ~ uname {print $3}' /etc/passwd)"
echo "Group ID (GID): $(awk -F ':' -v uname=${UNAME} '$0 ~ uname {print $4}' /etc/passwd)"
echo "User info: $(awk -F ':' -v uname=${UNAME} '$0 ~ uname {print $5}' /etc/passwd)"
echo "Home directory: $(awk -F ':' -v uname=${UNAME} '$0 ~ uname {print $6}' /etc/passwd)"
echo "Command shell: $(awk -F ':' -v uname=${UNAME} '$0 ~ uname {print $7}' /etc/passwd)"
echo "-------------------------------------------"
else #if UNAME is nonexistant then display this error message
echo "-------------------------------------------"
echo "\"${UNAME}\" does not exist."
echo "-------------------------------------------"
fi
说明:
if
可以直接使用grep
来检查是否存在
你在passwd中的论点UNAME=
是如何分配参数的,而不是
调用 - 用$ - 调用它们 - 例如$UNAME
/etc/passwd
是绝对文件名,因此不是参数
$/etc/passwd
并不意味着要打击argument=$(any old bash command)
告诉bash你想要的
将“any old bash command”的输出分配给“argument”,所以$()
必须包含一个命令,其中包含要分配的“参数”的输出
任何东西。>/dev/null
将grep
的输出发送到废纸篓,因为我们只关心它是否成功,以便if
知道该怎么做grep
的工作方式如下:grep <the thing you want to find> <file>
(请注意,如果要在搜索中包含空格,空格很重要并使用“”)awk
更有用。 awk -F':'
告诉awk我希望:
定义我的字段分隔符; -v uname=${UNAME}
将我的论点传递给awk;在awk中,$0 ~ uname
检查我的参数行(如grep);并且{print $1}
打印第一个字段,依此类推还要考虑部分匹配的限制。例如,如果我有一个用户JSmith和Smith,搜索Smith将返回两者。这可以通过正则表达式来解决,但会给脚本增加很多复杂性。
这是一个使用更轻的awk的版本,可以使用多个参数:
#!/bin/bash
for username; do
if grep ${username} /etc/passwd >/dev/null; then #if username exists then display info below
echo "---------------------------------------"
awk -F':' -v uname="${username}" '\
$0 ~ uname \
{print " Username: "$1\
"\n User ID (UID): "$3\
"\n Group ID (GID): "$4\
"\n User info: "$5\
"\n Home directory: "$6\
"\n Command shell: "$7}' /etc/passwd
echo "---------------------------------------"
else #if username is nonexistant then display this error message
echo "---------------------------------------"
echo "\"${username}\" does not exist."
echo "---------------------------------------"
fi
done
if [ -z ${1} ]; then #if no argument is provided; then display this
echo " Not enough arguments provided."
echo " USAGE: $0 <user name>"
exit 1
fi
*感谢William Pursell解释for循环
答案 2 :(得分:0)
阅读passwd
等数据库的最佳工具是getent
。这将从名称服务交换机库支持的数据库中获取条目。如果您确实需要限制阅读文件数据库,可以告诉getent
将files
数据库与-s files
一起使用。
您的代码不必要很长。获取记录并将其解析为多个变量就足够了。
#!/bin/bash
if [ $# -eq 1 ]; then #if num of args =1; then continue on
if IFS=: read username ignore uid gid gecos home shell < <(getent -s files passwd $1); then
echo "-------------------------------------------"
echo "Username: $username"
echo "User ID (UID): $uid"
echo "Group ID (GID): $gid"
echo "User info: $gecos"
echo "Home directory: $home"
echo "Command shell: $shell"
echo "-------------------------------------------"
else #if $1 is nonexistant then display this error message
echo "-------------------------------------------"
echo "'$1' does not exist."
echo "-------------------------------------------"
fi
fi
if [ $# -eq 0 ]; then #if num of args =0; then display this
echo "Not enough arguments provided."
echo "USAGE: $0 <user_name> [user_name] ..."
exit 1
fi