쉘 스크립트에서 arrUsers라는 배열을 선언했습니다. 마지막 명령을 사용하여 모든 사용자가 Linux 서버에 로그인하도록 하려고 합니다. 나는 이런 일을하고 싶다 :
declare -a arrUsers=()
for user in `last | awk '{print $1}'
do
if $user not in arrUsers()
do arrUsers += users
이 작업을 수행하는 데 올바른 구문이 무엇인지 잘 모르겠습니다. 어떤 도움이라도 대단히 감사하겠습니다.
답변1
여기서는 두 가지 다른 점을 볼 수 있습니다. 성공적으로 로그인한 사용자 목록을 가져오는 것(1)과 해당 목록을 Bash 배열에 추가하는 것(2)입니다.
구문 분석된
last
출력은 사용자 이름으로 시작하지 않는 줄도 포함하므로 간단하지 않습니다. Linux에는 몇 가지 대안이 있습니다.lslogins -r | awk -F '[ ]' 'NR > 1 && $6 { print $2 }'
lslogins
사용자에 대한 정보(로그인 이벤트 아님)를 표시하므로 사용자당 한 줄만 출력됩니다. 이-r
옵션은 출력을 열로 구분하지 않도록 지시하여 단일 공백을 열 구분 기호로 가정하고 단일 공백이 아닌 경우 공백 문자가 압착되는 것을awk
방지하는 기능 (기본값)을 활용할 수 있도록 합니다. 그러나 출력 필드의 내용에 공백 문자가 나타나는지FS
확실하지 않습니다 .lslogins
또는:
utmpdump /var/log/wtmp 2>/dev/null | gawk -v FPAT='\\[[^][]*\\]' ' $1 == "[7]" { gsub(/[][]/,"",$4); sub(/ +$/,"",$4); users[$4] } END { for (user in users) print user }'
이는 비표준 GNU AWK 기능을 사용하여
FPAT
필드 내용을 설명하는 정규식( 에 저장됨)을 기반으로 레코드를 분할합니다. 출력에서utmpdump
필드는 대괄호로 묶이고 공백으로 구분됩니다. 첫 번째 필드에 저장된 유형을 기준으로 레코드를 필터링합니다(man 5 wtmp
자세한 내용은 참고자료 참조).그러한 이름을 만드는 것은 확실히 현명한 선택은 아니지만 Linux에서는 다음을 따르지 않는 사용자 이름을 허용합니다.기준에 없는 문자가 포함되어 있습니다.이식 가능한 파일 이름 문자 집합--공백을 포함합니다. 공백 문자는 문제가 되지 않습니다
lslogins -r
. 공백 문자는 이스케이프 처리되지만(예 : ) 후행 공백은 출력에 명시적으로 표시\x20
되지 않으며 위의 스니펫에서 공백 문자를 제거합니다.utmpdump
다음을 사용하여 고유한 사용자 이름 목록을 배열에 넣을 수 있습니다.
readarray -t users \ < <(lslogins -r | awk -F '[ ]' 'NR > 1 && $6 { print $2 }')
또는 재설정하지 않고 기존 배열에 요소를 추가합니다.
readarray -t -O "${#users[@]}" users \ < <(lslogins -r | awk -F '[ ]' 'NR > 1 && $6 { print $2 }')
그러나 이것이 요소의 고유성을 보장하지는 않습니다. 이를 달성하려면 여러 루프가 필요할 수 있습니다.
while IFS= read -r user do for el in "${users[@]}" do if [ "$el" = "$user" ] then continue 2 fi done users+=( "$user" ) done < <(lslogins -r | awk -F '[ ]' 'NR > 1 && $6 { print $2 }')
대안으로(Bash 버전이 지원하는 경우) 연관 배열을 사용하고 사용자 이름을 키로 저장하여 각 사용자 이름이 한 번만 나타나도록 할 수 있습니다.
declare -A users while IFS= read -r user do users["$user"]='' done < <(lslogins -r | awk -F '[ ]' 'NR > 1 && $6 { print $2 }')
그런 다음 다음 구문을 사용하여 반복할 수 있습니다
"${!array[@]}"
.for username in "${!users[@]}" do printf '%s\n' "$username" done