Devin.KR
로그인

리눅스 chgrp 명령어 사용법 - 그룹 소유권 변경과 setgid 공유 디렉터리 만들기

개발자 조회 1

이 명령어를 언제 쓰는가

파일의 그룹 소유자만 바꿔야 할 때 쓴다. 배포 계정이 만든 로그 디렉터리를 웹서버 그룹도 읽게 해 주거나, 여러 개발자가 같이 쓰는 작업 디렉터리를 공용 그룹으로 통일하는 상황이다.

chown으로도 그룹을 바꿀 수 있지만, chown은 root 권한이 필요한 경우가 대부분인 반면 chgrp는 자기가 소유한 파일을 자기가 속한 그룹으로 바꾸는 한 일반 사용자도 쓸 수 있다. 소유자 변경 권한 없이 그룹만 정리하면 되는 상황에서 더 안전하다.

기본 형식

chgrp [옵션] 그룹 파일...

그룹은 이름(www-data)으로도 gid 숫자(33)로도 지정할 수 있다. 숫자로만 된 그룹 이름이 존재할 수도 있어서, 확실히 gid로 해석시키려면 숫자 앞에 +를 붙여 chgrp +1001 파일처럼 쓴다. 이 + 표기는 GNU 전용이고, macOS/BSD에서는 -n 옵션이 같은 역할을 한다.

자주 쓰는 옵션

옵션의미예시
-R디렉터리 아래를 재귀적으로chgrp -R devs /srv/project
-v바꾼 파일을 모두 출력chgrp -Rv devs /srv/project
-c실제로 바뀐 것만 출력(GNU 전용)chgrp -Rc devs /srv/project
-h심볼릭 링크가 가리키는 대상이 아니라 링크 자체를chgrp -h devs link
--reference=파일기준 파일과 같은 그룹으로(GNU 전용)chgrp --reference=a.conf b.conf
-f오류 메시지를 숨김chgrp -Rf devs /srv/project
-L / -P-R 중 심볼릭 링크를 따라감 / 따라가지 않음(기본 -P)chgrp -RL devs /srv

-c--reference는 GNU coreutils 전용이라 macOS/BSD의 chgrp에는 없다. 반대로 macOS에는 -x(파일시스템 경계를 넘지 않음)가 있다. 스크립트를 두 환경에서 같이 돌린다면 -R, -h, -f 정도만 쓰는 것이 안전하다.

실전 예제

1) 웹서버가 읽어야 하는 업로드 디렉터리의 그룹을 바꾼다.

sudo chgrp www-data /var/www/html/uploads
sudo chmod 775 /var/www/html/uploads
ls -ld /var/www/html/uploads
drwxrwxr-x 2 deploy www-data 4096 Aug 25 21:10 /var/www/html/uploads

2) 프로젝트 디렉터리 전체를 공용 그룹으로 통일한다.

sudo chgrp -R developers /srv/project
sudo chmod -R g+rwX /srv/project

g+rwX의 대문자 X는 디렉터리와 이미 실행 권한이 있는 파일에만 실행 비트를 준다. 소문자 x를 쓰면 모든 텍스트 파일이 실행 파일이 되어 버리므로 재귀 작업에서는 대문자 X를 쓴다.

3) 새로 만드는 파일도 자동으로 그 그룹이 되게 한다(setgid). 실무에서 이게 핵심이다.

sudo chgrp -R developers /srv/shared
sudo chmod 2775 /srv/shared
ls -ld /srv/shared
drwxrwsr-x 5 root developers 4096 Aug 25 21:12 /srv/shared

권한 문자열의 s가 setgid다. 이 비트가 붙은 디렉터리 안에서는 누가 파일을 만들든 그 파일의 그룹이 디렉터리 그룹을 따라간다. setgid가 없으면 사용자마다 자기 기본 그룹으로 파일이 생겨서, 며칠에 한 번씩 chgrp -R을 다시 돌리는 처지가 된다. 공유 디렉터리를 만든다면 chgrp와 setgid는 한 세트다.

4) 기존 파일과 똑같은 그룹으로 맞춘다.

chgrp --reference=/etc/nginx/nginx.conf /etc/nginx/conf.d/app.conf

5) 잘못 만들어진 파일만 골라서 고친다(대량 변경 최소화).

find /srv/shared ! -group developers -print
sudo find /srv/shared ! -group developers -exec chgrp developers {} +

먼저 -print로 대상을 눈으로 확인한 뒤 실행하는 것이 안전하다.

6) 심볼릭 링크 자체의 그룹을 바꾼다.

chgrp -h developers /srv/current

-h 없이 실행하면 링크가 아니라 링크가 가리키는 원본의 그룹이 바뀐다. 배포 디렉터리에서 current 심볼릭 링크를 다루다가 실수하기 쉬운 지점이다.

함정과 주의점

자기가 속하지 않은 그룹으로는 바꿀 수 없다. root가 아닌 사용자는 자기가 소유한 파일자기가 속한 그룹으로만 바꿀 수 있다. chgrp: changing group of 'x': Operation not permitted가 뜬다면 소유자가 아니거나 그 그룹에 속하지 않은 것이다. id -nG로 내 그룹을 먼저 확인한다. 그룹에 방금 추가됐다면 재로그인 전까지는 적용되지 않는다는 점도 같이 기억한다.

-R을 심볼릭 링크가 있는 트리에 쓸 때 조심한다. GNU chgrp의 기본은 -P(링크를 따라가지 않음)라서 대체로 안전하지만, -L을 주면 링크를 따라가 디렉터리 밖의 파일까지 바꾼다. /srv/app/logs/var/log로 걸린 심볼릭 링크였다면 시스템 로그 디렉터리의 그룹이 통째로 바뀌는 사고가 난다. 재귀 변경 전에 find 경로 -type l로 링크가 있는지 확인하는 습관이 좋다.

chmod로 권한을 함께 손보지 않으면 효과가 없다. 그룹만 www-data로 바꿔 놓고 권한이 drwxr-x---가 아니라 drwx------라면 여전히 접근이 안 된다. chgrp는 "누구의 그룹인가"만 정하고 "그 그룹이 무엇을 할 수 있는가"는 chmod가 정한다. 항상 ls -ld로 두 가지를 같이 확인한다.

setuid/setgid 비트가 조용히 사라질 수 있다. 소유자나 그룹이 바뀌면 커널이 보안상 실행 파일의 setuid/setgid 비트를 떨어뜨린다. 실행 파일을 다루는 경우라면 chgrp 후 ls -ls 비트가 남아 있는지 확인해야 한다.

/ 에는 절대 재귀 실행하지 않는다. chgrp -R group /은 시스템을 못 쓰게 만든다. 여기서 흔한 오해가 하나 있다. rm과 달리 chgrp·chown·chmod는 --no-preserve-root가 기본값이라 /를 직접 지정해도 막아 주지 않는다(POSIX가 재귀 실행을 요구하기 때문이다). 안전장치를 원하면 --preserve-root를 명시적으로 붙여야 하고, 그마저도 -R과 같이 쓸 때만 효과가 있으며 /*처럼 셸 확장으로 넘기면 역시 막지 못한다. 경로 끝에 변수를 쓸 때는 chgrp -R g "$DIR"에서 $DIR이 비어 있지 않은지 먼저 검사한다.

함께 보면 좋은 명령어

  • chown - 소유자까지 함께 바꿔야 할 때 쓴다. chown :group 파일은 chgrp와 같은 동작이다.
  • chmod - 그룹에게 실제 권한을 부여하고 setgid 비트를 다는 것은 chmod의 몫이다.
  • id - 내가 어떤 그룹에 속했는지 확인해야 chgrp가 성공한다.