简体   繁体   中英

Modifing users in Linux using a script

I trying to modify around 1000 users by removing the "_" from the comment and replacing it with a space. Here is an example about how one of the user would look:

af1571:x:3571:100:aleja _ fischer:/home/af1571:/bin/bash

I have written a script in bash but it is not working, i think is not going thorough the for loop also, i dont think my usermod command is good as well.

here is what i have so far:

#!usr/bin/bash

 FILENAME="/etc/passwd"
 while IFS=: read -r username password userid groupid comment homedir cmdshell
  do

    for i in "{$userid > 1000 && $userid < 2000}"
     do
      usermod $username -c $comment sed "s/_/ /g"

     done
  done< $FILENAME   

If you have GNU awk gawk installed and the inplace extension is available there's a fairly easy way to achieve this w/o any looping ...

gawk -i inplace -v inplace::suffix=.bak 'BEGIN{FS=OFS=":"}{if($3>=1000 && $3<2000){gsub(/_/, " ",$5)}; print }' /etc/passwd

If you have only a posix-awk available, this would do it:

awk 'BEGIN{FS=OFS=":"}{if($3>=1000 && $3<2000){gsub(/_/, " ",$5)}; print }' /etc/passwd > ~/passwd.new && mv ~/passwd.new /etc/passwd

Given the importance of the file you may want to experiment on a copy of it first to confirm that it works for you ;)

Try this Shellcheck -clean code:

#! /bin/bash -p

getent passwd   \
    |   while IFS=: read -r username _ userid _ comment _ _; do
            (( userid > 1000 ))     || continue
            (( userid < 2000 ))     || continue
            [[ $comment == *_* ]]   || continue

            usermod -c "${comment//_/ }" "$username"
        done
  • On modern systems /etc/passwd may not include all of the valid users. For instance, users may be configured via LDAP. The code uses getent passwd to get the full list of users. If you really only want to modify users listed in /etc/passwd , replace getent passwd | while ... done getent passwd | while ... done with while ... done </etc/passwd .
  • The _ characters in the read arguments cause the corresponding input fields to be discarded. There's no point putting them in variables because they aren't used. See BashFAQ/001 (How can I read a file (data stream, variable) line-by-line (and/or field-by-field)?) .
  • [[ $comment == *_* ]] || continue [[ $comment == *_* ]] || continue causes users whose comments don't contain underscores to be skipped. They don't need to be modified.
  • "${comment//_/ }" expands to the $comment string with all underscores replaced by spaces. See Parameter expansion [Bash Hackers Wiki] .

Using getent getent passwd {1001..1999} list users between 1000 and 2000

Calling cmd usermod from awk after modifying comment $5 for user $1 using delimiter :

getent passwd {1001..1999}|awk -F: '{gsub(/_/," ",$5);print|"usermod "$1" -c \""$5"\""}'

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM