목록으로
디렉터리 이름에 사용할 수 없는 문자
파일 시스템 차원에서 사용할 수 없는 문자
맥OS에서는 디렉터리 이름에 두 가지 문자를 사용할 수 없어요.
-
콜론(:) : 맥OS는 예전 파일 시스템(HFS)에서 경로 구분자로 콜론을 사용했어요. 현재 사용하는 APFS와 APFS 직전에 사용되던 HFS+에서는 슬래시(/) 기호를 구분자로 사용하지만, 여전히 : 문자를 사용할 수 없는 문자로 다루지요. 예전 맥OS의 파일 시스템에 대한 하위 호환성을 고려한 정책으로 보입니다.
-
널(null 문자 \0) : 문자열을 다룰 때 널 문자는 문자열이 끝났다는 표식으로 사용합니다. 디렉터리 이름도 문자열인데, 사용자가 디렉터리 이름에 널 문자를 사용하여 혼란이나 오작동을 예방하기 위해 널 문자를 사용할 수 없지요. 참고로 \0 문자열 자체가 아니라 널 문자를 표현하는 \0입니다.
리눅스도 맥OS와 동일합니다. 한 가지를 제외하면요. 바로 슬래시(/) 문자를 사용할 수 없는데, 이 문자는 경로 구분자로 사용되기 때문이지요.
윈도우에서 디렉터리 이름에 사용할 수 없는 문자나 텍스트는 더 많습니다.
-
< (미만)
-
> (초과)
-
: (콜론)
-
" (따옴표)
-
/ (슬래시)
-
\ (백슬래시)
-
| (파이프라인)
-
? (물음표)
-
* (별표)
이 문자들은 파일 이름에도 사용할 수 없지요.
파일 이름에는 윈도우에 이미 예약어로 사용되는 텍스트도 사용할 수 없어요.
-
CON
-
PRN
-
AUX
-
NUL
-
COM1, COM2, ..., COM9
-
LPT1, LPT2, ..., LPT9
파일 확장자 여부와 무관한데, 다른 이름은 그렇다쳐도 CON은 이름으로 쓸 가능성이 있어서, 당황하는 일이 생길지도 모르겠어요.
Shell 환경에서 있는 그대로 사용할 수 없는 문자
Shell에서 몇몇 문자는 역할이 정해져있습니다. 파일 시스템에서는 이름에 사용할 수 있지만, Shell에서는 정해진 명령을 수행해야 하는 역할 표식으로써 문자인지 아니면 그런 역할 없이 문자 그대로 다뤄야 하는지 구분하기 위해 제약을 가하지요. 대신 역슬래시(\) 문자로 각 문자에 부여된 명령을 해석하지 않도록 표식을 남길 수 있어요. 이를 이스케이프(escape) 처리한다고 합니다.
맥OS와 리눅스
-
공백( ) : 이름에 공백이 포함되어 있을 때, 명령어에서 인자나 옵션을 구분하는 용도로 해석될 수 있으므로 공백 앞을 이스케이프 처리하여 사용합니다. 예: File\ Name.txt
-
괄호((, )) : 특정 스크립트에서 해석될 수 있는 문자입니다. 예: File\ \(Version\ 1\).txt
-
달러 기호($) : Shell에서 변수를 나타낼 때 사용되므로, 문자 그대로(literal) 사용하기 위해 이스케이프 처리가 필요합니다. 예: Price\ \$100.txt
-
큰따옴표("), 작은따옴표('), 역따옴표(백틱, `) : 문자열을 나타낼 때 사용되므로, 이 문자들도 escape 처리가 필요할 수 있습니다. 참고로 대부분 프로그래밍 언어에서도 따옴표나 역따옴표를 사용해 문자열 데이터로 다룹니다.
-
별표(*), 물음표(?), 세미콜론(;), 역슬래시(\) 등 : 와일드카드 문자 또는 명령어 구분자 등으로 해석될 수 있으므로, 해당 문자를 이름에 사용할 때는 escape 처리가 필요합니다.
윈도우
PowerShell에서는 역따옴표(backtick, `)가 이스케이프 문자로 사용됩니다. 유의할 점은 파일 시스템에서 허용하지 않는 문자는 대부분 이스케이프 처리를 해도 사용할 수 없다는 점이에요. 체감 상 공백, $ 문자 정도만 이스케이프 처리해서 다루는 것 같아요.
그런 측면에서 맥OS와 리눅스는 두어 가지 문자를 제외하면 이스케이프 처리하여 파일명으로 사용하지만, 윈도우에서는 이스케이프 처리로 기호 문자를 사용하는 경우는 한정하고 되도록 기호 문자 사용을 하지 않는 편이라는 인상을 받습니다.
디렉터리 만들기
디렉터리는 mkdir 명령어로 만듭니다. make directories를 줄인 이름이지요. 사용법은 아주 간단합니다. mkdir 명령어 뒤에 만들 디렉터리 이름을 인자로 나열하면 됩니다.
인자(argument)는 실행 주체에 실행 대상이 무엇인지 전달하는 변수입니다. 언어 문법으로 치면 명령어는 동사, 인자는 목적어에 해당하지요.
mkdir puddingcamp 명령 줄은 이름이 puddingcamp인 디렉터리를 만든다고 읽는 식이죠.
명령어가 명사 역할을 하면 인자는 보통 그 명사의 동사 역할을 하고요. 이런 경우, 명령어(command)나 보조 명령어(sub command)라고 하기도 합니다.
이 명령 줄은 Docker Compose는 컨테이너를 올린다(구동한다)고 읽는 식이죠.
명령어 뒤에 만들 디렉터리의 이름을 명시하면 돼요. make directory가 아니라 make directories, 즉 복수형이잖아요. 만들 이름을 공백으로 구분해서 여러 개 나열하면 디렉터리를 한 번에 여러 개 만듭니다.
맥OS, 리눅스에서 유용한 옵션(option)
mkdir 명령어에 사용하는 유용한 옵션이 있습니다.
-p 옵션은 크게 두 가지 상황에서 편리합니다. 첫 번째는 이미 존재하는 이름을 갖는 디렉터리가 존재해도 오류가 발생하지 않아요. 두 번째는 만드는 디렉터리의 경로 중에 디렉터리가 없으면 만들어줍니다. 이미 있으면 피해가고 없으면 만드는, 말 그대로 알아서 해주는 거죠.
명령어에 추가 지시사항을 명시하는 옵션은 - 또는 -- 문자로 식별합니다. --는 대개 옵션의 전체 이름을 사용하고, -는 옵션을 한 글자로 줄여쓸 때 사용하지요. 가령, 명령어에 대한 도움말을 출력할 때엔 관례처럼 --help 옵션을 제공하고 사용하는데, 이를 -h로 줄여 사용하는 거예요.
명령어를 개발한 개발자가 어떻게 구현했는지에 따라 옵션 형식이 다르긴 하지만, 이 설명은 관례처럼 두루 통용되니, 유닉스나 리눅스에서 명령어에 어떤 옵션이 있는지 확인하려면 명령어 --help를 실행해보세요. 대개는 도움말을 출력합니다.
모든 명령어가 --help 옵션을 제공하는 건 아닌데, 특히 Shell에 내장 명령어나 필수 명령어는 도움말 옵션이 대부분 없습니다. 이런 명령어는 man 명령어로 명령어에 대한 설명을 볼 수 있어요. manual을 줄인 이름으로 man ls처럼 사용하면 돼요.
man 명령어로 보는 명령어 설명서는 방향키나 j와 k키로 위, 아래 스크롤을 할 수 있어요. 그리고 설명서 보기를 종료하려면 q키를 누르면 되고요.
이게 대수냐, 생각이 들 수도 있는데, 컴퓨터 입장에서(?) 디렉터리를 만드는 상황을 상상하면 사용자에게 무척 편의를 제공하는 옵션입니다.
(1) mkdir -p realworldpudding/puddingcamp/shell 명령어를 실행한다.
(2) 현 경로에 realworldpudding라는 이름을 갖는 디렉터리가 존재하는지 확인한다.
-
없으면 realworldpudding라는 이름으로 디렉터리를 만든다.
-
있으면 realworldpudding 디렉터리를 만들지 않는다.
(3) 현 경로에 realworldpudding/puddingcamp 디렉터리가 존재하는지 확인한다.
-
없으면 realworldpudding 디렉터리 안에 puddingcamp 디렉터리를 만든다.
-
있으면 realworldpudding 디렉터리 안에 puddingcamp 디렉터리를 만들지 않는다.
(4) 현 경로에 realworldpudding/puddingcamp/shell 디렉터리가 존재하는지 확인한다.
-
없으면 realworldpudding 디렉터리 안에 있는 puddingcamp 디렉터리 안에 shell 디렉터리를 만든다.
-
있으면 realworldpudding 디렉터리 안에 있는 puddingcamp 디렉터리 안에 shell 디렉터리를 만들지 않는다.
옵션은 명령어에 보다 구체적인 사항을 명시하는 요소이며, 언어 문법으로 보자면 보어나 부사, 서술어와 비슷합니다. 목적어를 꾸미거나 보충하는데, 명령 줄에서 목적어는 대개 인자입니다.
윈도우 PowerShell에서 유용한 옵션(option)
윈도우 PoewrShell의 mkdir은 New-Item이라는 명령어(cmdlet)에 대한 별칭인데요. 이 명령어를 사용하며 유용한 옵션이 있어요.
-ea 0은 이미 존재하는 이름을 갖는 디렉터리가 존재해도 오류가 발생하지 않게 조용히 실행되게 해줘요. 만드는 경로 중에 이미 존재하는 경로가 있어도 조용히 지나가죠. 맥OS, 리눅스의 mkdir 명령어에 있는 -p 옵션과 동일한 기능을 합니다.
-ea 0은 ErrorAction SilentlyContinue를 줄여쓴 거예요.
이름이 동일한 디렉터리와 파일이 동일 경로에 공존하지 못하는 제약
동일 경로에 이미 존재하는 디렉터리의 이름으로 새 디렉터리를 만들지 못하죠. 이름 중복을 허용하지 않거든요. 이미 존재하는 대상이 파일이어도 마찬가지입니다.
파일 시스템은 파일과 디렉터리를 포함한 모든 객체를 관리하는 체계예요. 특히 유닉스 계열이나 리눅스는 모든 객체를 파일로 취급하고, 따라서 디렉터리도 사실상 파일의 한 종류라고 볼 수 있습니다. 각 객체는 고유한 식별자를 갖는데, 사람이 인식하고 다루는 식별자는 절대경로입니다.
/tmp 경로에 hello라는 이름을 갖는 파일과 디렉터리가 각각 존재한다고 가정할게요. 사용자가 /tmp/hello 경로에 접근하는 경우, 파일 시스템 차원에서 두 객체엔 고유한 식별자가 있어 구분이 가능하지만, 사용자가 접근하는 절대경로인 /tmp/hello만으로는 파일인 /tmp/hello에 접근하는 것인지 디렉터리인 /tmp/hello에 접근하는 것인지 구분할 수 없습니다.
그래서 명확하고 간결한 파일 시스템의 객체 관리 차원에서 한 경로에 이름이 같은 파일과 디렉터리는 공존하지 못하게 제한돼요.
물론, 대개는 이 제약을 경험하진 않을 거예요. 맥OS의 파인더나 윈도우의 탐색기에서 보기엔 파일명과 폴더명이 같아보여도, 실제로는 파일명의 파일 확장자를 생략해 표시하는 것이고, 대부분의 파일은 파일 확장자가 있기 때문에 완전히 이름이 동일하여 발생하는 상황은 드문 편이거든요.
하지만, Shell을 다루다보면 파일 확장자가 없는 파일을 다루는 일이 있어요. 특히 Python같은 언어로 스크립트를 작성해 파일명이나 디렉터리명을 다루는 경우엔 이름이 충돌하는 코드를 작성할지도 모르고요. 그럴 때를 대비해 이런 제약을 알아두시면 좋습니다.
디렉터리 지우기
remove directories를 줄인 이름인 rmdir 명령어로 디렉터리를 삭제합니다. 사용법은 mkdir과 동일합니다. 명령어 뒤에 삭제할 디렉터리 이름을 공백을 기준으로 나열하는 것이지요.
또한, 디렉터리를 만들 때와 마찬가지로 이름에 이스케이프 처리가 필요한 문자가 있으면 삭제할 때에도 이스케이프 처리를 해야합니다. Hello World 디렉터리 이름을 예를 들면, rmdir Hello\ World와 같이 이스케이프 처리하는 것이지요.
맥OS에서는 디렉터리 안에 파일이나 디렉터리가 있으면 디렉터리를 삭제하지 못합니다. 먼저 디렉터리를 비워야 하지요. 그에 반해 윈도우에서는 삭제할 수 있어요. 대신 정말 하위 항목도 제거할 것인지 사용자에게 물어보고요.
푸딩캠프 뉴스레터를 구독하면 학습과 성장, 기술에 관해 요약된 컨텐츠를 매주 편하게 받아보실 수 있습니다.
목차