Linux / 명령어 / command - 명령어 검색과 별칭 우회 실행
command는 셸 함수 검색을 건너뛰고 내장 명령 또는 PATH에서 찾은 외부 명령을 실행하는 셸 내장 명령입니다. 같은 이름의 래퍼 함수를 만들었을 때 원래 명령을 호출하거나, command -v로 현재 셸이 명령을 찾을 수 있는지 확인할 때 주로 사용합니다.
Bash에서는 -v와 -V로 명령 해석 정보를 확인하고, -p로 표준 유틸리티를 찾을 수 있는 기본 검색 경로를 사용합니다. exec, env, builtin과 역할이 다르므로 목적에 맞게 구분해야 합니다.
command 명령어란?
셸 함수는 외부 명령과 같은 이름을 가질 수 있습니다. 이때 함수 안에서 이름을 그대로 호출하면 자기 자신을 다시 호출하여 재귀에 빠질 수 있습니다. command를 앞에 붙이면 같은 이름의 셸 함수를 건너뛰고 Bash 내장 명령이나 PATH에서 찾은 실행 파일을 선택합니다.
command 자체는 Bash를 비롯한 여러 셸이 제공하는 내장 기능입니다. POSIX에도 정의되어 있지만 세부 출력과 확장 동작은 셸마다 다를 수 있습니다.
기본 문법
command [-pVv] 명령 [인수...]
옵션 없이 사용하면 지정한 명령을 실행합니다.
command ls -la command printf '%s\n' 'hello'
대부분의 상황에서는 명령을 직접 실행한 것과 같아 보입니다. 차이는 같은 이름의 셸 함수가 있을 때 드러납니다.
셸 함수 안에서 원래 명령 호출하기
다음 함수는 ls 실행 전 메시지를 출력한 뒤 원래 ls를 호출합니다.
ls() {
printf '%s\n' '목록을 출력합니다.'
command ls --color=auto "$@"
}
함수 안에서 ls "$@"라고 쓰면 같은 함수가 다시 호출됩니다. command ls는 함수 검색을 건너뛰므로 Bash 내장 명령 또는 PATH의 외부 ls가 실행됩니다.
"$@"는 함수에 전달된 인수를 원래 경계를 유지해 넘깁니다. $*나 따옴표 없는 $@로 바꾸면 공백과 와일드카드가 포함된 인수가 깨질 수 있습니다.
command -v로 명령 존재 여부 확인하기
-v는 지정한 이름이 현재 셸에서 어떻게 해석되는지 간결한 형태로 출력합니다. 명령을 찾으면 성공 상태, 찾지 못하면 실패 상태를 반환하므로 스크립트에서 존재 여부를 검사하기 좋습니다.
command -v git command -v cd command -v printf
출력은 실행 파일 경로뿐 아니라 내장 명령 이름, 함수 또는 별칭에 대한 설명이 될 수 있습니다. 따라서 결과를 무조건 파일 경로라고 가정하면 안 됩니다.
if command -v curl >/dev/null 2>&1; then printf '%s\n' 'curl을 사용할 수 있습니다.' else printf '%s\n' 'curl을 찾지 못했습니다.' >&2 fi
command -V로 자세한 정보 확인하기
-V는 -v보다 사람이 읽기 좋은 자세한 설명을 출력합니다.
command -V ls command -V cd command -V deploy
자동화에서는 문장 형식이 셸과 로케일에 따라 달라질 수 있으므로 -V 출력을 파싱하지 않는 것이 좋습니다. 스크립트의 존재 여부 검사는 command -v의 종료 상태를 사용하세요.
command -p와 기본 검색 경로
-p는 표준 유틸리티를 찾을 수 있도록 셸이 제공하는 기본 PATH 값을 사용합니다. 사용자가 변경한 PATH가 신뢰하기 어렵거나 표준 명령을 찾아야 할 때 사용할 수 있습니다.
command -p getconf PATH command -p ls
기본 경로의 실제 값은 시스템에 따라 다릅니다. -p가 특정한 절대 경로나 특정 공급자의 프로그램을 보장하는 것은 아니므로 보안이 중요한 스크립트에서는 실행 환경과 신뢰 경계를 별도로 설계해야 합니다.
command 옵션 정리
| 옵션 | 설명 |
|---|---|
-v |
명령을 실행하지 않고 현재 셸의 해석 결과를 간결하게 출력합니다. |
-V |
명령이 어떻게 해석되는지 자세한 설명을 출력합니다. |
-p |
표준 유틸리티를 찾을 수 있는 기본 검색 경로를 사용해 명령을 실행합니다. |
별칭을 우회할 때 주의할 점
별칭 확장은 명령 실행보다 앞선 셸 구문 처리 단계에서 일어납니다. 대화형 Bash에서 command ls는 일반적으로 ls 별칭 대신 실제 명령을 실행하는 용도로 쓰이지만, 별칭 정의와 셸의 확장 문맥까지 모두 통제하는 범용 인용 도구로 생각해서는 안 됩니다.
현재 이름의 모든 후보는 먼저 type -a로 확인할 수 있습니다.
type -a ls command -V ls
단순히 현재 별칭을 적용하지 않으려면 백슬래시로 이름을 입력하거나 확인한 절대 경로를 실행하는 방법도 있습니다.
\ls /usr/bin/ls
절대 경로는 배포판과 시스템 구조에 따라 달라질 수 있으므로 하드코딩하기 전에 확인해야 합니다.
command, builtin, exec, env 비교
| 명령 | 주요 역할 |
|---|---|
command 이름 |
같은 이름의 셸 함수 검색을 건너뛰고 내장 명령 또는 PATH 명령을 실행합니다. |
builtin 이름 |
같은 이름의 Bash 내장 명령을 명시적으로 실행합니다. |
exec 이름 |
현재 셸 프로세스를 새 프로그램으로 교체합니다. 성공하면 원래 셸로 돌아오지 않습니다. |
env VAR=값 이름 |
환경 변수를 조정한 환경에서 외부 명령을 실행합니다. |
type 이름 |
명령을 실행하지 않고 현재 Bash가 이름을 어떻게 해석하는지 보여 줍니다. |
예를 들어 함수 안에서 같은 이름의 Bash 내장 명령을 반드시 호출하려면 builtin이 더 명확할 수 있고, 함수가 아닌 외부 프로그램까지 허용하려면 command가 적합합니다.
스크립트에서 command -v를 사용할 때의 원칙
출력을 버리고 종료 상태 확인하기
if ! command -v rsync >/dev/null 2>&1; then printf '%s\n' 'rsync가 필요합니다.' >&2 exit 1 fi
이 방식은 출력 형식에 의존하지 않습니다. 오류 메시지까지 숨기려면 표준 출력과 표준 오류를 모두 리디렉션해야 합니다.
실행 가능한 일반 파일이 필요한 경우 추가 검사하기
command -v가 성공해도 결과가 별칭, 함수 또는 내장 명령일 수 있습니다. 반드시 외부 실행 파일이 필요하면 결과가 경로인지와 실행 가능한 일반 파일인지 추가로 확인합니다.
path=$(command -v mytool) || exit 1 if [ -f "$path" ] && [ -x "$path" ]; then printf '실행 파일: %s\n' "$path" fi
상대 경로나 셸의 특수 출력이 반환될 수 있으므로 사용 목적에 맞게 조건을 설계하세요.
TOCTOU 문제 이해하기
명령 존재 여부를 검사한 뒤 나중에 실행하면 그 사이 PATH나 파일이 바뀔 수 있습니다. 단순한 사용자 안내에는 충분하지만, 보안이 중요한 환경에서는 검사 결과만 신뢰하지 말고 통제된 경로와 권한을 사용해야 합니다.
종료 상태
명령 실행 모드에서는 대상 명령을 찾지 못하거나 오류가 발생하면 일반적으로 127을 반환하고, 명령을 찾으면 그 명령의 종료 상태를 전달합니다. -v와 -V는 이름을 찾으면 성공하고 찾지 못하면 실패합니다.
command false printf 'status=%d\n' "$?" command does-not-exist printf 'status=%d\n' "$?"
종료 상태는 실행한 명령의 의미를 따르므로 단순히 0이 아닌 값이라고 해서 command 자체가 고장 난 것은 아닙니다.
자주 묻는 질문
command가 외부 명령만 실행하나요?
아닙니다. Bash에서는 셸 함수를 건너뛴 뒤 내장 명령 또는 PATH에서 찾은 외부 명령을 실행합니다. 외부 파일만 찾으려면 type -P와 같은 도구로 경로를 확인해야 합니다.
command -v 결과는 항상 절대 경로인가요?
아닙니다. 별칭, 함수, 예약어, 내장 명령 또는 실행 파일에 대한 결과가 나올 수 있습니다. 명령 존재 여부 검사에는 종료 상태를 사용하세요.
sudo command ... 형식으로 사용할 수 있나요?
command는 셸 내장 명령이므로 sudo가 별도의 실행 파일처럼 직접 실행하지 못할 수 있습니다. 보통은 필요한 외부 명령을 sudo에 직접 전달하거나, 꼭 셸 문법이 필요하다면 인용과 보안 영향을 이해한 상태에서 셸을 명시적으로 실행해야 합니다.
which보다 command -v가 좋은 이유는 무엇인가요?
command -v는 셸이 제공하며 현재 셸의 명령 해석을 반영합니다. which는 외부 프로그램인 경우가 많고 구현별 차이가 있어 별칭이나 함수를 정확히 처리하지 못할 수 있습니다.
함수를 무시하고 내장 명령만 실행하려면 어떻게 하나요?
Bash에서는 builtin 이름을 사용합니다. command 이름은 내장 명령뿐 아니라 PATH의 외부 명령도 실행할 수 있습니다.
다른 셸에서도 같은 옵션을 사용할 수 있나요?
-p, -v, -V의 핵심 동작은 POSIX에 정의되어 있지만 출력 문구와 확장 기능은 셸마다 다를 수 있습니다. 자동화에서는 대상 셸을 정하고 해당 문서를 확인하세요.
정리
command는 셸 함수로 가려진 원래 명령을 호출하고, 현재 셸에서 명령을 찾을 수 있는지 확인하는 데 유용합니다. 실행에는 command 이름, 존재 여부 검사에는 command -v 이름, 사람이 읽을 상세 설명에는 command -V 이름을 사용합니다.
명령의 모든 후보와 종류를 조사할 때는 type -a를 함께 사용하세요. 다른 기본 명령은 리눅스 명령어 목록과 개요에서 확인할 수 있습니다.









