bash脚本grep etc文件以获取用户信息

时间:2017-03-29 20:08:49

标签: bash scripting

我正在尝试用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

3 个答案:

答案 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/nullgrep的输出发送到废纸篓,因为我们只关心它是否成功,以便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。这将从名称服务交换机库支持的数据库中获取条目。如果您确实需要限制阅读文件数据库,可以告诉getentfiles数据库与-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