저는 나만의 대본을 만들기 위해 많은 노력을 기울인 학생입니다. 일반적으로 말하면, 제공된 정보와 규칙을 따르면 폭발적인 스크립트 키디잉을 수행하고 다른 사람들이 수행하는 작업에 추가할 수 있습니다(예, 제 자신이 부끄럽다는 것을 압니다). 그러나 bash/python을 사용하려고 할 때는 몇 년 동안 제 생명을 구하기 위해 처음부터 무언가를 창조하는 데 필요한 두뇌 능력이 없다는 것이 분명해졌습니다. 그래서 저는 여기 있습니다. 4년 전에 비슷한 주제에 대한 게시물이 있었고 그것은 내가 달성하고 싶은 것에 대한 올바른 길을 따라 가고 있는 것 같습니다. 그러나 내 인생에서는 내가 어디로 잘못 가고 있는지 알 수 없는 것 같습니다. 다음은 jesse_b에게 감사를 표하고 싶은 스크립트입니다. 사용해야 하는 매개변수를 만지작거렸지만 불행하게도 스크립트를 실행할 때 스크립트에 있다고 생각되는 항목에 대한 매뉴얼 페이지가 계속 표시됩니다( 어쩌면 useradd?). 누구든지 나를 보호하고 건설적인 피드백을 제공할 수 있다면 매우 감사하겠습니다.
#! /usr/bin/bash
MY_INPUT='Newbies.csv'
declare -a A_SURNAME
declare -a A_FIRST
declare -a A_USERNAME
declare -a A_GROUP
declare -a A_SECGROUP
declare -a A_COMMENTS
while IFS=, read -r COL1 COL2 COL3 COL4 COL5 COL6 TRASH; do
A_SURNAME+=("$COL1")
A_FIRST+=("$COL2")
A_USERNAME+=("$COL3")
A_GROUP+=("$COL4")
A_SECGROUP+=("$COL5")
A_COMMENTS+=("$COL6")
done <"$MY_INPUT"
for index in "${!A_USERNAME[@]}"; do
useradd -g "${A_GROUP[$index]}" -G "${A_SECGROUP[$index]}" -c "${A_COMMENTS[$index]}"
done
매개변수 예:성, 이름, 사용자 이름, 그룹, secgroup, 설명:
Esche,Adlai,aesche,Accounting,Emp,5326,
West,Kaila,kwest,Accounting,Emp,0699,
July,Markos,mjuly,MArketing,Emp,7208,
참고 포스팅 링크:.csv 파일에서 사용자 생성
답변1
useradd 줄 끝에 사용자 이름을 추가하는 것을 잊어버린 것 외에도 상황을 필요 이상으로 복잡하게 만들었습니다.
여러 배열 변수가 필요하지 않습니다(CSV 데이터로 더 많은 작업을 수행하려는 경우 제외).뒤쪽에for
계정이 이미 생성되었습니다. 그래도 기존 루프 내에서 이 작업을 수행하는 것이 더 좋습니다 . 또한 bash
실제로 텍스트 처리에 능숙한 언어(예: awk
또는 ) 대신 (텍스트 처리에 형편없는 언어)을 사용하고 있습니다 perl
.
perl
한 줄로 원하는 것을 달성하는 방법은 다음과 같습니다 .
$ perl -lne '($surname,$first,$username,$group,$secgroup,$comments) = split /\s*,\s*/;
system("echo","useradd","-g",$group,"-G",$secgroup,"-c",$comments,$username)' Newbies.csv
출력 예:
useradd -g Accounting -G Emp -c 5326 aesche
useradd -g Accounting -G Emp -c 0699 kwest
useradd -g MArketing -G Emp -c 7208 mjuly
이것은 테스트 실행으로 작성되었으며 내용만 인쇄합니다.회의실제로 사용자 계정을 추가하지 않고 이 작업을 수행합니다. 명령이 올바르게 생성되었는지 확인한 후 "echo"
명령에서 제거하십시오.system()
useradd
Bash와 달리 Perl 함수를 사용할 때 변수를 참조할 필요가 없습니다. system()
주어진 목록의 각 요소는 시스템이 실행 중인 프로그램에 별도의 별도 인수로 전달됩니다(이 경우 프로그램은 echo
, 또는 )을 useradd
제거한 후의 목록 "echo"
(공백 문자가 포함된 경우에도). 와일드카드나 기타 셸 메타 문자를 전달하지 않으면 셸은 사용되지 않으며 system()
셸의 토큰화 또는 확장의 영향을 받지 않습니다. Perl에는 glob을 확장하거나 파일 이름으로 가득 찬 배열을 구성하기 위한 자체 내장 메서드가 있으므로 와일드카드 전달을 피하는 것은 쉽습니다.
변수를 인용해야 하는 유일한 경우는 변수를 문자열로 결합하는 것입니다. 예를 들어 다음 명령을 사용하여 GECOS 필드에 이름과 성을 추가할 수 있습니다.
$ perl -lne '($surname,$first,$username,$group,$secgroup,$comments) = split /\s*,\s*/;
system("echo","useradd","-g",$group,"-G",$secgroup,"-c","$first $surname - $comments",$username)' Newbies.csv
그럼에도 불구하고 이를 수행하는 다른 방법이 많이 있습니다. 예를 들어 .
연결 연산자를 사용하는 경우입니다.
$first . " " . $surname . " - " . $comments
또는 다음을 사용하십시오 join()
.
join(" ",$first,$surname,"-",$comments)
출력 예:
useradd -g Accounting -G Emp -c Adlai Esche - 5326 aesche
useradd -g Accounting -G Emp -c Kaila West - 0699 kwest
useradd -g MArketing -G Emp -c Markos July - 7208 mjuly
여기에 표시된 출력에서는 명확하지 않지만 주석은 실제로 다음과 같이 작성됩니다.하나의useradd
옵션 매개변수 -c
. 예를 들어 Adlai Esche - 5326
, 옵션의 단일 매개변수 -c
,아니요4개의 별도 인수, 정확히 공백 문자를 포함하는 문자열입니다.
"echo",
각 매개변수가 별도의 줄에 인쇄되도록 바꾸면 "printf","%s\n",
이를 볼 수 있습니다 .
$ perl -lne '($surname,$first,$username,$group,$secgroup,$comments) = split /\s*,\s*/;
system("printf","%s\n","useradd","-g",$group,"-G",$secgroup,"-c","$first $surname - $comments",$username)' Newbies.csv
useradd
-g
Accounting
-G
Emp
-c
Adlai Esche 5326
aesche
...
버전은 awk
매우 유사합니다. 주요 차이점은 입력을 awk
필드 구분 기호( FS
변수, 기본값은 공백이지만 쉼표로 설정할 수 있음 -F,
)를 기반으로 입력을 열($1, $2, $3....)로 자동 분할한다는 점입니다. 반면 awk의 시스템 기능에는 다음이 필요합니다. 문자열 인수이므로 sh 또는 bash 요구 사항과 유사하게 직접 인용해야 합니다.
Perl에는 입력을 자동으로 열로 분할하는 유사한 옵션이 있지만 (이름이 지정된 배열로 분할) -F
의미 있는 변수 이름(예: 대신 )을 사용하여 @F
코드를 읽는 것이 더 쉽습니다 .$group
$F[2]
배쉬 버전:
#!/bin/bash
MY_INPUT='Newbies.csv'
while IFS=, read -r surname first username group secgroup comments; do
echo useradd -g "$group" -G "$secgroup" -c "$comments" "$username"
#echo useradd -g "$group" -G "$secgroup" -c "$first $surname - $comments" "$username"
#printf "%s\n" useradd -g "$group" -G "$secgroup" -c "$first $surname - $comments" "$username"
done < "$MY_INPUT"
다시 말하지만, 이것은 연습으로 작성되었습니다. echo
실제로 사용자 계정을 생성하려면 제거하세요 . 또한 GECOS 필드에 이름과 성을 추가하는 방법을 보여주는 참고 사항도 포함되어 있습니다.
출력은 Perl 버전과 동일합니다.
useradd -g Accounting -G Emp -c Adlai Esche - 5326 aesche
useradd -g Accounting -G Emp -c Kaila West - 0699 kwest
useradd -g MArketing -G Emp -c Markos July - 7208 mjuly
또는:
useradd -g Accounting -G Emp -c Adlai Esche - 5326 aesche
useradd -g Accounting -G Emp -c Kaila West - 0699 kwest
useradd -g MArketing -G Emp -c Markos July - 7208 mjuly
Bash와 Perl의 결합:
#!/bin/bash
MY_INPUT='Newbies.csv'
perl -lne '($surname,$first,$username,$group,$secgroup,$comments) = split /\s*,\s*/;
system("echo","useradd","-g",$group,"-G",$secgroup,"-c",$comments,$username)' "$MY_INPUT"
이것은 텍스트 처리에 awk나 Perl 또는 거의 모든 것(bash 제외)을 사용하는 것이 더 나은 이유에 대한 좋은 예를 실제로 제공하지 않는 매우 간단한 작업입니다. 바라보다쉘 루프를 사용하여 텍스트를 처리하는 것이 왜 나쁜 습관으로 간주됩니까?
그러나 여기에서도 Perl 버전이 더 빠릅니다(만들어야 할 계정이 수천 개가 아니면 그다지 중요하지 않습니다).그리고split /\s*,\s*/
쉼표로 구분된 필드에서 모든 선행 및 후행 공백을 제거합니다. Perl에서는 사소한 작업이고 bash에서는 더 많은 작업을 수행합니다. 즉, 입력 데이터를 "정리"하여 우리가 사용하려는 목적에 맞게 적절하게 서비스할 수 있도록 합니다. 유닉스의 사용자 이름과 그룹 이름은 공백으로 시작할 수 없습니다.