본문 바로가기

IT/리눅스 Linux

리눅스에서 왜 unzip * 하면 안될까?

반응형

 

 

리눅스/유닉스 환경에서 어떻게 보면 가장 남용되는 기능이 shell wildcard (*) 인것 같습니다.

저도 회사에서 어떤 분이 실수로 root 계정으로 rm -rf * 을 실행시켜서 (그것도 루트 디렉토리에서!) 시스템을 날려먹은 걸 본 적이 있으니까요.

경력이 쌓이고 내공이 있는 관리자일수록 wildcard의 무분별한 사용을 지양하는 것을 보면, 편리하지만 그만큼 위험할 수 있는 것이 와일드카드인것 같네요.

 

서문이 길었는데, 초보 시스템 관리자가 리눅스 환경에서 당황하는 경우 중 하나가 디렉토리에 zip 압축파일이 많은 경우 unzip * 아니면 unzip *.zip 했는데 다음과 같이 나올 때 입니다.

 

$ ls

a.zip

b.zip

 

$ unzip *.zip

Archive : a.zip

caution : filename not matched:  b.zip

 

사용자는 다만 a.zip , b.zip 파일 두 개를 압축해제 하고 싶었을 뿐인데, 이게 무슨 말인지 알 수 없는 문구만 나오고 파일은 압축된 채로 그대로 있습니다.

왜 이런 일이 생길까요? 정답은 bash가 wildcard를 해석하기 때문입니다.

사용자는 unzip *.zip 이라고 명령어를 입력하지만, bash가 *.zip을 해석해서 현재 디렉토리에 있는 zip확장자 파일들 전부를 찾아서, 실제 unzip 프로그램의 parameter 는 *.zip이 아니라 a.zip b.zip 이렇게 들어가는 것이죠.

따라서 unzip 입장에서는 a.zip파일을 풀어서, 그 안에 있는 b.zip 파일만을 압축해제 하라는 명령을 수행하려 하는데 당연히 a.zip안에 b.zip파일이 없으므로 아무런 일도 하지 않고, 그냥 끝나버리게 되는 것입니다.

 

그렇다고 일일이 unzip a.zip ; unzip b.zip 이렇게 손으로 하기에는 파일 숫자가 많을 때 손이 너무 고달프겠죠? 2가지 방법을 소개합니다.

 

  1. find 를 사용하는 방법
    find  명령어를 이용하면, 원하는 형식(확장자) 의 파일을 먼저 찾은 다음, 찾은 파일에 대해 원하는 명령어를 실행할 수 있습니다.
    이 방법은 unzip 뿐 아니라 다른 처리를 할 때도 유용하게 쓸 수 있으므로 기억해 두시면 좋습니다.
    find . -name "*.zip" -exec unzip {} \;

  2. 와일드카드를 unzip으로 바로 전달하는 방법
    unzip 프로그램 자체가 와일드카드를 인식하므로, bash에서 해석하지 않고 그대로 unzip의 파라메터로 보내주면 간단히 해결 됩니다.
    즉 이스케이프 문자 (\) 를 사용하는 거죠.
    unzip \*.zip

 

 

 

반응형