bash에서 exec와 eval의 차이는 무엇일까?
stackoverfloweval
과 exec
는 둘다 bash(1)
의 내장 명령어 입니다.exec
가 몇 가지 다른 옵션을 가지고 있는것은 알지만 둘의 차이점은 무엇인가요?
eval
과 exec
는 완전히 다른 명령어라고 보셔도 됩니다.
$ help exec
exec: exec [-cl] [-a name] [command [arguments ...]] [redirection ...]
Replace the shell with the given command.
exec cmd
가 하는 일은, 그냥 cmd
를 실행 했을때와 완전히 동일합니다.
다만, 다른 프로세스를 띄워서 명령어를 실행하는것이 아닌, 현재의 쉘을 명령어로 대체하게 됩니다.
내부적으로는, 예를들어 /bin/ls
를 실행 할 경우 fork()
를 호출하여서 자식 프로세스를 만든 후에 생성된 자식 프로세스 내에서 exec()
를 재호출해서 /bin/ls
를 실행하게 됩니다. exec /bin/ls
는 이 과정(fork()
호출)을 거치지 않고 명령어를 실행하게 됩니다.
아래의 두 예제를 봅시다.
1.
$ bash -c 'echo $$ ; ls -l /proc/self ; echo foo'
7218
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7219
foo
2.
$ bash -c 'echo $$ ; exec ls -l /proc/self ; echo foo'
7217
lrwxrwxrwx 1 root root 0 Jun 30 16:49 /proc/self -> 7217
echo $$
명령어는 처음에 명령어를 호출한 쉘의 PID값을 출력하게 됩니다. 그리고 /proc/self
를 대상으로 ls
명령어로 리스팅을 하게 되면 명령어를 실행하는 프로세스의 PID를 가져올 수 있습니다. 일반적으로, (1)에서 볼 수 있듯이 두 PID는 다른 값을 가지게 되지만, exec
를 통해 실행된 명령은 같은 PID를 갖는 것을 알 수 있습니다.
또한, exec
명령어가 현재의 쉘을 완전히 대체하였기 때문에, 뒤 따르는 echo foo
명령이 실행되지 않은 것도 확인할 수 있습니다.
한편,
$ help eval
eval: eval [arg ...]
Execute arguments as a shell command.
eval
명령어는 인자를 받아서 현재의 쉘에서 실행하게 됩니다. 쉽게 말하면 eval foo bar
과 foo bar
은 완전히 같다 볼 수 있습니다.
다만, 변수들이 명령어가 실행되기 전에 확장되어 변수에 담겨있는 명령어를 실행하는 것이 가능해집니다.
$ unset bar
$ cmd="bar=foo"
$ eval "$cmd"
$ echo "$bar"
foo
'stackoverflow' 카테고리의 다른 글
2>&-, 2>/dev/null, |&, &>/dev/null and >/dev/null 2>&1 의 차이점에 대해서 (0) | 2020.05.28 |
---|---|
실행 vs 읽기 비트, 리눅스폴더에서는 어떻게 동작하나요? (0) | 2020.03.28 |
XY problem이란? (0) | 2020.03.26 |
try/catch 구문에서 finally의 요점이 뭘까요? (0) | 2019.12.14 |