Env
1. 개요
`env`는 환경 변수를 설정하고 실행하는 데 사용되는 유닉스 및 유닉스 계열 운영 체제의 명령어이다. 4.4BSD에 처음 등장했으며, 현재 환경 변수 집합을 출력하거나, 기존 환경 변수 없이 새로운 셸을 시작하는 데 사용될 수 있다. 또한 스크립트의 셔뱅 라인에서 인터프리터를 찾는 데 활용되어 이식성을 높이지만, 잘못된 인터프리터가 선택될 위험도 존재한다.
| 종류 | 유닉스 명령어 |
|---|---|
| 운영체제 | 유닉스, 유닉스 계열, Inferno |
| 플랫폼 | 크로스 플랫폼 |
| 장르 | 명령어 |
| 라이선스 | coreutils: GPLv3+ |
-
환경 변수 -
PATH (변수)
-
환경 변수 -
ComSpec
ComSpec은 도스, OS/2, 윈도우 등에서 사용되는 기본 명령줄 인터프리터의 경로를 가리키는 환경 변수이다. -
표준 유닉스 프로그램 -
AWK
AWK는 1977년에 개발된 텍스트 처리 및 프로그래밍 언어로, 유닉스 환경에서 텍스트 처리를 위해 설계되었으며 정규 표현식 처리 기능을 통해 텍스트 분석, 데이터 추출, 보고서 생성 등 다양한 작업을 수행한다. -
표준 유닉스 프로그램 -
Rm (유닉스)
유닉스 명령어 `rm`은 파일을 삭제하는 데 사용되며, 옵션을 통해 삭제 동작을 제어하고 디렉터리를 재귀적으로 삭제할 수 있지만, 잘못 사용하면 시스템에 심각한 손상을 초래할 수 있어 주의가 필요하며 안전 장치나 휴지통 기능 등의 대안이 존재한다.
2. 역사
GNU coreutils에 포함된 `env` 버전은 Richard Mlynarik, David MacKenzie, Assaf Gordon이 작성했다. 이는 최초로 4.4BSD에 등장했으며, POSIX.1의 일부이다(-i 옵션만).
GNU의 `env`는 신호와 현재 디렉토리를 처리하도록 확장되었다. FreeBSD의 `env`는 사용자 지정 검색 경로를 지원한다. 두 버전 모두에서 발견되는 확장 기능으로는 변수를 설정 해제하는 `-u`와 인수를 분할하는 `-S`가 있다(주로 shebang에서).
3. 사용 예시
`env` 명령어는 유닉스 계열 운영 체제에서 환경 변수를 설정하거나 확인하고, 지정된 환경에서 명령을 실행하는 데 사용된다.
일반적인 사용 예시
* 현재 환경 변수 목록을 보려면:
```bash
env
```
* 기존 환경 변수를 모두 지우고 새로운 셸을 실행하려면:
```bash
env -i /bin/sh
```
* `DISPLAY` 환경 변수를 설정하여 X 윈도 시스템 응용 프로그램인 xcalc를 다른 디스플레이에서 실행하려면:
```bash
env DISPLAY=foo.bar:1.0 xcalc
```
(대부분의 셸에서는 `env` 없이 `DISPLAY=foo.bar:1.0 xcalc`와 같이 사용해도 동일하게 동작한다.)
스크립트에서의 활용
`env`는 파이썬과 같은 인터프리터 언어 스크립트의 해시뱅(shebang) 라인에서 유용하게 사용된다.
```python
#!/usr/bin/env python
print("Hello World.")
```
위 예제에서 `#!/usr/bin/env python`는 파이썬 인터프리터의 전체 경로(`/usr/bin/python` 등)를 직접 쓰는 대신, 시스템의 `PATH` 환경 변수에서 `python` 인터프리터를 찾아 실행하도록 한다.
이렇게 하면 파이썬 인터프리터가 다른 위치에 설치된 시스템에서도 스크립트가 제대로 작동할 가능성이 커져 스크립트의 이식성이 높아진다.
3.1. 일반적인 사용법
`env` 명령은 새로운 셸을 위해 환경을 초기화하거나, 특정 환경 변수를 설정하여 프로그램을 실행하거나, 스크립트에서 인터프리터를 찾는 데 사용된다.
* 기존 환경 변수를 모두 지우고 새로운 셸을 시작하는 방법은 다음과 같다.
```bash
env -i /bin/sh
```
* X 윈도 시스템 응용 프로그램인 xcalc를 실행하고 이를 다른 디스플레이에 표시하는 방법은 다음과 같다.
```bash
env DISPLAY=foo.bar:1.0 xcalc
```
* 파이썬 스크립트에서 `env`를 사용하여 인터프리터를 찾을 수 있다. 다음은 파이썬 스크립트의 예시이다.
```bash
#!/usr/bin/env python3
print("Hello, World!")
```
이 예시에서 `/usr/bin/env`는 `env` 명령의 전체 경로이다. `env`를 사용하면 파이썬 인터프리터의 전체 경로를 지정하지 않아도 되므로 이식성이 향상된다. 하지만 잘못된 인터프리터가 선택될 위험도 있다.
3.2. 셔뱅(Shebang)에서의 활용
`env`는 스크립트의 해시뱅(shebang) 라인에서 사용되어 PATH를 통해 인터프리터를 찾도록 함으로써 스크립트의 이식성을 높이는 데 활용된다.
예를 들어, 파이썬 스크립트에서 다음과 같이 `env`를 사용할 수 있다.
```python
#!/usr/bin/env python3
print("Hello, World!")
```
위 예제에서 `#!/usr/bin/env python3`는 `python3` 인터프리터의 전체 경로를 직접 지정하는 대신, 시스템의 `PATH` 환경 변수에 따라 인터프리터를 검색하여 실행하도록 한다.
하지만, 이러한 `env` 활용에는 몇 가지 주의사항이 있으며, 이식성 문제가 발생할 수 있다. (자세한 내용은 하위 섹션 참고)
3.2.1. 이식성 문제와 해결
`env`를 사용하지 않고 `python` 인터프리터의 전체 경로를 지정하여 인터프리터를 지정할 수도 있다. 이 접근 방식의 문제는 컴퓨터 시스템에 따라 정확한 경로가 다를 수 있다는 것이다. 대신 `env`를 사용하면 스크립트가 실행될 때 인터프리터가 검색되어 위치가 파악된다(보다 정확하게는 `env`가 `execvp`에 대한 시스템 호출을 수행하며, 이는 인터프리터를 찾아 시작하는 작업을 수행한다). 이렇게 하면 스크립트의 이식성이 향상되지만, 실행 파일 검색 경로의 모든 디렉토리에서 일치하는 항목을 검색하기 때문에 잘못된 인터프리터가 선택될 위험도 증가한다. 또한 `env` 바이너리에 대한 경로도 시스템마다 다를 수 있다는 동일한 문제도 겪는다.
유닉스의 시뱅에서는 일반적으로 인터프리터의 전체 경로를 지정해야 한다. 하지만 유닉스 계열 운영체제에서는 표준 프로그램을 /usr/bin에, 관리자가 독자적으로 추가한 프로그램을 /usr/local/bin에 배치하여 구분하여 관리(FHS)하는 등의 이유로 인터프리터의 전체 경로가 시스템에 따라 다르다. 따라서 인터프리터의 전체 경로를 직접 기술하면 해당 셸 스크립트의 범용성이 떨어진다(다른 시스템에서는 동작하지 않을 수 있다). 그래서 (인터프리터 자체가 미리 환경 변수 PATH로 지정된 디렉터리에 있다는 전제하에) 전체 경로가 아닌 단순한 명령어를 기술하고 env로 실행하면 범용성을 유지할 수 있다.
```python
#!/usr/bin/env python
print "Hello World."
```
위 예시처럼 인터프리터 대신 `env`를 지정함으로써 스크립트 실행 시 PATH에서 인터프리터를 검색하여 실행한다. 이로 인해 동일한 스크립트가 더 많은 환경에서 작동할 가능성이 높아진다. 반면에, PATH에서 검색되기 때문에, 예를 들어 사용자의 홈 디렉터리 아래에 있는 동일한 이름의 프로그램이 실행되는 등, 동일한 이름의 다른 프로그램이 의도하지 않게 실행될 위험도 있다.
또한, `env`는 /usr/bin에 있을 수도 있고 /bin에 있을 수도 있지만, /usr/bin/env라고 적어도 /bin/env라고 적어도 실행되도록 보장하기 위해 심볼릭 링크를 거는 등의 방법으로 해결하는 경우가 많다.
3.2.2. 주의사항
`env`를 스크립트의 해시뱅 라인에서 사용하면 PATH를 통해 인터프리터(프로그래밍)를 찾을 수 있어 스크립트의 이식성을 높일 수 있다. 예를 들어 파이썬(프로그래밍 언어) 스크립트에서 `#!/usr/bin/env python3`와 같이 사용하면, `python3` 인터프리터의 전체 경로를 직접 지정하는 대신 시스템의 `PATH` 환경 변수에 따라 인터프리터를 검색하여 실행한다.
하지만 이 방식은 몇 가지 주의사항이 있다.
* 잘못된 인터프리터 선택 위험: 실행 파일 검색 경로의 모든 디렉터리에서 일치하는 항목을 검색하므로, 의도하지 않은 다른 프로그램이 실행될 수 있다.
* `env` 바이너리 경로 문제: `env` 명령어의 경로 자체도 시스템마다 다를 수 있다.
이러한 문제를 해결하기 위해 심볼릭 링크를 사용하여 `/usr/bin/env`와 `/bin/env` 모두에서 `env` 명령어가 실행되도록 보장하는 경우가 많다.