저는 쉘 스크립팅을 처음 접했고 제가 생각해낸 것보다 더 나은 솔루션이 있는지 궁금합니다.
사용자가 목록에 있는지 확인하고 싶습니다. 그렇다면 스크립트는 exit_program 함수를 사용하여 종료해야 합니다.
$USER는 시스템에 로그인한 사람으로 정의됩니다.
내 솔루션은 다음과 같습니다.
$IGNORE_USER="USER1 USER2 USER3"
if [ ! -z "$IGNORE_USER" ]; then
for usr in $IGNORE_USER
do
if $USER = $usr; then
exit_program "bye bye"
fi
done
fi
답변1
이 스크립트의 기능은 다음과 같습니다.아니요일하다.
쌍에 대한 할당은 IGNORE_USER
역참조된 변수를 사용해서는 안 되기 때문에 첫 번째 줄에 구문 오류가 있습니다 $
. 귀하의 명령문에 또 다른 구문 오류가 있습니다 if
. 문자열을 비교하는 데 사용됩니다 [ "string1" = "string2" ]
.
$IGNORE_USER
귀하의 코드는 따옴표 없이 사용하는 데 의존합니다 . 이렇게 하면 문자열이 공백으로 분할됩니다. 이는 원하는 작업입니다. 가장 일반적인 경우는 다음과 같습니다.아니요하지만 당신이 원하는 것은 목록의 항목이 유지되어야 하는 공백 문자를 포함할 가능성이 높다는 것입니다. 따옴표가 없는 문자열을 사용하는 경우 쉘은 문자열의 값에 대해 파일 이름 생성(와일드카드)도 수행합니다.
개별 항목(사용자 이름)을 처리할 때는 배열을 사용하는 것이 더 좋습니다. 별도의 항목을 다음과 같이 처리하고 싶을 때마다분리항목을 단일 문자열에 넣지 마세요. 그렇게 하면 한 항목을 다른 항목과 구별하기 어려울 수 있습니다.
제안:
ignore=( 'user1' 'user2' 'user3' )
for u in "${ignore[@]}"; do
if [ "$USER" = "$u" ]; then
exit_program 'bye bye'
fi
done
이는 exit_program
프로그램 종료에 대한 책임을 집니다. 그렇지 않은 경우 exit
통화 후에 추가하세요 exit_program
. ignore
배열이 비어 있으면 루프가 단일 반복을 실행하지 않으므로 배열이 비어 있는지 테스트할 필요가 없습니다 .
위 코드에서 "${ignore[@]}"
(큰따옴표 참고)는 사용자 이름 목록으로 확장되며, 각 사용자 이름은 개별적으로 인용되어 추가 토큰화 및 파일 이름 생성을 방지합니다.
관련된:
버전에 따라 다르지만 bash
POSIX와 유사한 셸에서 실행할 수 있습니다.
set -- 'user1' 'user2' 'user3'
for u do
if [ "$USER" = "$u" ]; then
exit_program 'bye bye'
fi
done
이는 무시할 사용자 이름 목록으로 배열이 아닌 위치 인수 목록을 사용합니다.
답변2
grep 솔루션
단어를 일치시키려면 의 "-w" 기능을 사용하십시오 grep
. grep
Solaris, AIX 등과 같은 이전 구현에서는 작동하지 않을 것이라고 말하고 싶습니다 .
echo $IGNORE_USER | grep -qw $USER && exit_program 'bye bye'
bash 내부 솔루션
bash를 완전히 사용하고 grep
.
bash
=~ regex
먼저 실행 하지 않으면 건설이 허용되지 않습니다 shopt -s compat31
. 따라서 =~ $(echo regex)
우리는 이 문제를 극복할 수 있습니다. 이 예에서는 확장을 용이하게 하기 위해 큰따옴표를 사용하고 있습니다 . $USER
이를 수행할 때 \b
be 로 이스케이프해야 합니다 \\b
.
[[ $IGNORE_USER =~ $(echo "\\b$USER\\b") ]] && exit_program 'bye bye'