missing-semester 의 두 번째 주제인 Shell Tools and Scripting의 문제들을 해결하던 중 여러 가지 난관에 봉착했다.
그 중 가장 핵심이 되는 sourcing 과 executing의 차이를 짚고 넘어가는 것이 좋을 것 같아,
따로 정리한다.
문제를 같이 풀면서 해결하면 이해를 돕는 데에 더 좋을 것 같아 문제부터 보고가자.
marco.sh 와 polo.sh 라는 두 가지 함수를 만들 것이다.
marco.sh 에서는 현재 디렉토리를 저장하는 함수를,
polo.sh 에서는 marco.sh 에서 저장된 현재 디렉토리의 경로로 이동하는 함수를 정의할 것이다.
- marco.sh
#!/usr/bin/env sh
marco () {
bar=$(pwd)
}
marco 라는 함수는 bar 라는 변수를 선언하고, 현재 디렉토리를 알려주는 pwd 프로그램의 출력값을 그대로 갖는다.
- polo.sh
#!/usr/bin/env sh
polo () {
cd "$bar"
}
polo 라는 함수는 marco 에서 선언한 bar 라는 변수에 저장된 경로로 이동하는 역할을 수행한다.
단순히 쉬운 문제 같지만, sourcing과 executing의 차이를 모른다면 해결하기 어렵다.
sourcing 부터 알아보자.
sourcing 은 말 그대로 현재 쉘 안에서 스크립트를 실행하는 것이다.
그러면 executing은 무엇일까?
흔히 executing의 예로 sh 와 ./가 있는데, sh는 sh 라는 프로그램을 실행시키고 인자로 스크립트를 넘겨주는 것이다. (스크립트를 실행시키는 것과 같은 뜻)
./ 도 비슷한데, 위 marco.sh와 polo.sh 상단에 전 포스트에서 다뤘던 shebang과 함께 어떤 인터프리터로 이 스크립트를 실행해야 하는지 명시되어 있기 때문에, sh marco.sh 나 ./marco.sh(with #!/usr/bin/env sh) 나 다를 바가 없다.
executing은 새로운 subshell(현재 쉘 안에서 실행되는 또 다른 작은 쉘)을 열어 거기서 파일을 실행한다.
따라서, subshell 에서 선언된 변수는 파일 실행이 끝나고, 현재 쉘로 돌아왔을 때는 없는 변수가 된다.
아래 실행 예시를 보자.
분명 marco.sh 라는 스크립트 안에서 bar라는 변수를 선언했고, bar에는 현재 디렉토리의 경로가 값으로 할당되어 있어야 한다.
그런데, 보다시피 echo $bar를 하면 아무것도 출력이 되지 않는다.
그 이유는 바로 executing은 marco.sh를 현재 쉘이 아니라 subshell에서 실행했기 때문에 marco.sh 실행이 끝나는 순간, 즉 subshell이 닫히는 순간 bar 라는 변수는 사라지는 것이다. bar은 'subshell 안에서만' 유효했다.
그렇다면 sourcing을 하면 어떨까?
marco 라는 함수도 현재 쉘에서 잘 정의되어 있고, 함수를 실행하면 bar 라는 변수도 잘 선언되어 있는 것을 볼 수 있다.
현재 실행되고 있는 쉘 안에서 그대로 스크립트를 실행했기 때문에 파일 실행이 끝나도 그대로 변수와 함수가 유효한 것이다.
Q: 그러면 현재 쉘에서 변수와 함수는 언제까지 유효한 것인가요?
A: 지금 실행하고 있는 쉘을 닫고 다시 켜보시면 echo $bar를 했을 때 아무것도 출력되지 않을 것입니다. (직관적인 이해를 돕기 좋은 방법)
혹은, unset -f marco 와 unset bar를 통해 함수와 변수를 해제해주시면 됩니다.
마치면서, 궁금증을 해결하는 것은 마치 지독하게 가렵던 곳을 시원하게 긁는 느낌같다.
최근에 missing-semester를 따라가며 shell을 배우고 있는데, 부딪치고 해결해가는 과정이 재밌고 유익하다.
더 많이 쩔쩔매고 고민할수록, 내 머릿속에 남는 것은 더 많아지는 것같다.
계속해서 이런 방식으로 공부해야겠다.
'Dev > Shell' 카테고리의 다른 글
[missing-semester] Shell Tools and Shell Scripting (셸 스크립팅) (0) | 2023.01.08 |
---|---|
SpaceVim 에 플러그인 적용하기 (0) | 2022.12.31 |
[missing-semester] 간단한 셸(Shell) 사용기 (2) | 2022.12.26 |