사용자가 /etc/passwd에 있는지 확인하고, 존재하는 경우 접두사를 사용하여 새 사용자를 만듭니다.

사용자가 /etc/passwd에 있는지 확인하고, 존재하는 경우 접두사를 사용하여 새 사용자를 만듭니다.

여기에 갇혀 있고 해결책을 찾지 못했습니다.

사용자가 /etc/passwd에 있는지 확인하고 그렇다면 접두사 new_the_existed_one을 사용하여 새 사용자를 만듭니다.

#!/bin/bash

myuser="/home/yakyak/Desktop/Exercises/newusers.txt"

sed '/^[ \t]*$/d' $myuser | while read -r line
do
        name="$line"
        # adduser --disabled-login --gecos "" $name
        # check if user exist
        isthere=$(cut -d: -f1 /etc/passwd | grep "$name")

        # if user was added then make insert record into log file
        if [[ "$isthere" == "$name" ]]
        then
            echo "User already exist, creating new user.."
            adduser --disabled-login 
        # adduser --disabled-login --gecos " " $name
        fi   
done

답변1

#!/bin/bash

NAME_REGEX='^[a-z][-a-z0-9]*$'   # default value for adduser.conf
. /etc/adduser.conf              # "source" it in case local config is different

myuser='/home/yakyak/Desktop/Exercises/newusers.txt'

grep "$NAME_REGEX" "$myuser" | while read -r name; do
  while getent passwd "$name" > /dev/null; do
    name="new_$name"
  done

  # check if $name is > 32 characters
  if [ "${#name}" -gt 32 ] ; then
    echo "username '$name' is too long" > /dev/stderr
  else
    adduser --disabled-login --gecos '' "$name"
  fi
done

sed파일에서 빈 줄을 제거하는 데 사용되지 않지만 잘못된 사용자 이름을 제외하는 newusers.txt데 사용 됩니다.grep아니요라는 쉘 변수에 저장된 패턴과 일치합니다 $NAME_REGEX. adduser"유효함"을 정의하기 위해 자체와 동일한 변수 이름(및 정규식 패턴)을 사용합니다 . 보기 man adduser.confNAME_REGEX검색

$name이 더 이상 passwd 데이터베이스에 존재하지 않을 때까지 $name 앞에 "new_"가 계속 추가됩니다. "user"가 존재하면 "new_user"를 시도합니다. "new_user"가 존재하면 "new_new_user"를 시도합니다. 그런 다음 "new_new_new_user"가 있습니다. 등.

스크립트는 getent passwd종료 코드를 사용하지만 관심만 있습니다. 출력은 삭제됩니다(/dev/null로 리디렉션됨). getent가 0(true)으로 종료되면 사용자가 존재하므로 다시 시도하십시오.

getentfalse를 반환 하면 (즉, $name존재하지 않음) 이름이 너무 긴지 확인합니다. 그렇다면 오류 메시지를 인쇄합니다. 그렇지 않은 경우 를 실행하십시오 adduser.

그런데 getent에서 볼 것으로 예상되는 실제 종료 코드는 0사용자가 이미 존재하는 경우와 2사용자가 존재하지 않는 경우입니다. 어떤 경우에는 getent가 다른 종료 코드를 반환할 수 있지만(참고자료 참조), 이는 man getentgetent를 사용하는 방식(예: 데이터베이스 검색 및 사용자 이름 제공)으로는 불가능합니다.passwd


약간 더 나은 버전은 사용자 이름에 숫자 접미사를 사용하는 것입니다. 예를 들어 0으로 채워진 3자리 너비의 숫자 형식 문자열(예 : 등) printf과 함께 사용됩니다 . 0으로 채워지는 것을 원하지 않으면 대신 0을 사용하세요. 이 변수는 처리된 각 사용자 이름에 대해 외부 while 루프에서 0으로 재설정됩니다 .%03i001002%icount

#!/bin/bash

NAME_REGEX='^[a-z][-a-z0-9]*$'   # default value for adduser.conf
. /etc/adduser.conf              # "source" it in case local config is different

myuser='/home/yakyak/Desktop/Exercises/newusers.txt'

grep "$NAME_REGEX" "$myuser" | while read -r user; do
  name="$user"
  count=0

  while getent passwd "$name" > /dev/null; do
    let count+=1
    name="$(printf "%s%03i" "$user" "$count")"
  done

  # check if $user is > 32 characters
  if [ "${#name}" -gt 32 ] ; then
    echo "username '$name' is too long" > /dev/stderr
  else
    adduser --disabled-login --gecos '' "$name"
  fi
done

이 버전은 사용자 이름에 두 가지 변수를 사용합니다. 즉, $usernewusers.txt 파일에서 읽은 이름과 $name사용하려는 현재 사용자 이름에 대한 것입니다. $name은 처음에 $user에서 복사되고 내부 while 루프는 변수를 증가시키고 $count추가하여 true를 $user반환 함으로써 $name을 업데이트합니다 getent.


결국 위의 어느 것도 특별히 좋은 스크립트는 아닙니다. 그들이 하는 일은 최소한의 일뿐입니다. 개인적으로 나는 bash보다는 perl로 작성하는 것을 선호합니다.쉘에서의 텍스트 처리는 PITA입니다..

관련 정보