본문 바로가기
Dev/Shell

[missing-semester] 간단한 셸(Shell) 사용기

by 생귄맨 2022. 12. 26.

전역이 얼마 남지 않은 지금, '무엇을 하는게 좋을까?' 라는 생각이 문득 들었다.

그러던 와중, 나의 관심을 끌만한 사이트를 발견하게 되었다.

https://missing-semester-kr.github.io/

 

여러분의 CS 교육에서 누락된 학기

여러분의 CS 교육에서 누락된 학기 CS 교과과정은 운영체제에서 기계학습에 이르기까지 CS 내의 고급 주제에 대해 모두 가르쳐 주지만, 거의 다루지 않는 중요한 한 가지 과목이 있으며, 대신 학

missing-semester-kr.github.io

일반적인 컴퓨터 과학(CS) 교육에서는 거의 다루지 않는 '컴퓨터 생태계 활용 능력'을 길러주는 수업을 MIT에서 따로 제공하는 사이트다. 학교에서는 흔히 CS과목인 자료구조, 알고리즘, 운영체제, 그리고 네트워크 등의 고급 과목들은 가르치지만, 학생들에게 컴퓨터를 효율적으로 다루는 방법을 가르치지는 않는다. 이러한 공백을 채우기 위해 만든 강의인데, 들어보니 퀄리티도 좋고, 굉장히 유익해서, 복학 전까지는 한번 이 사이트에 있는 강의들을 따라가 볼 생각이다.

 

먼저, 첫 번째 주제인 쉘(Shell)이다. 

블로그에는 강의 내용을 요약하기보다도,

이 강의에서 나온 과제를 직접 해결해나가는 과정 및 깨달은 점을 기록하는 것이 좋을 것 같다.

 

일단 우리가 해결해야 할 연습문제부터 보자.  

1. 쉘에서 새로운 폴더를 만들기 위한 명령은 mkdir 이다.

mkdir missing

 

2. 우선 man 프로그램을 통해 touch 프로그램이 무엇을 하는지 살펴보자.

man은 manual의 약자로 쉘 내에 기본적으로 탑재된 명령 e.g. echo, mkdir 이 무슨 기능을 하는지 알려주는 프로그램이다.

man touch

touch는 파일에 액세스하거나 파일을 수정한 시간을 바꾸어주는 프로그램인데, 만약 파일이 해당 경로에 존재하지 않는다면, 파일을 만든다. 

 

3. 현재 위치가 missing이라고 가정하면,

touch semester

semester 라는 파일을 missing이라는 폴더 아래에 생성

 

4. 이 문제를 해결하기 위해 Quoting에 대해 알아야 한다. 

Quoting은 쉘에서 취급하는 특정한 문자들이나 단어들의 특별한 의미를 제거하는 것이다, 즉 문자들을 문자 그 자체로 사용하고 싶다는 얘기다.

Quoting의 방법은 총 세 가지: backslash(\), single quotes(' '), double quotes(" ").

간단 요약하자면,

1) backslash(\)는 \ 다음에 오는 문자를 그 문자 그대로 보존한다. 단, 개행 문자인 n 제외.

2) single quotes는 ' ' 안에 오는 문자열을 그대로 보존한다. 

3) double quotes는 " " 안에 오는 문자열을 보존하지만, $, `, \, ! 라는 예외가 존재한다. 또, " " 안에서는 변수를 삽입할 수 있다.

echo "#\!/bin/sh" > semester
echo "curl --head --silent https://missing.csail.mit.edu" >> semester

주의할 점은, !를 backslash로 이스케이프 처리를 해주었다는 점이다.

>>는 파일에 덧붙여 작성할 때 사용한다. (append)

또 다른 방법으로

echo '#!/bin/sh' > semester

single quotes 안에 문자열은 그대로 보존되기 때문에 이러한 방법도 가능하다.

 

만약

echo "#'!'/bin/sh" > semester

로 했다면, semester 파일 안에는 #'!'/bin/sh 라고 써져 있을 것이다. 

 

여기서 #!(shebang)에 대해서 알고 넘어가야 한다.

스크립트의 첫 번째 라인에 작성되는 것으로 어떤 인터프리터를 사용하여 해당 파일을 해석할지 정해주는 역할을 한다고 보면 된다.

#!/bin/sh는 root 폴더 안에 있는 bin 폴더 안에 있는 sh 라는 인터프리터를 사용해서 이 파일을 해석하라는 뜻이다. 

 

5.          ./semester 로 실행하면, Permission denied 에러가 뜬다. 

ls -l를 통해서 살펴보면, 

이렇게 파일에 대한 권한 범위를 볼 수 있다. 

권한은 총 세 종류: r(read), w(write), x(execute) 이다. 

맨 앞 -를 제외하고, 3칸씩 나누어서 해석하자면 다음과 같다.

순서대로 파일의 소유자의 권한, 소유 그룹의 권한, 그 외 다른 모든 사람들의 권한을 나타낸다. 

현재 파일을 실행하고자 하는 '나'의 권한은 rw-, 즉 파일을 읽거나 수정할 수 밖에 없다. 파일을 실행할 수는 없다.

그래서 에러가 뜬 것이다.

 

6. 

sh semester

sh 명령어를 통해 실행하면, 잘 된다.

일단 인터넷에 나와있는 sh./의 차이를 알아보기 전에, 알아야 할 중요한 사실이 있다.

sh semester은 sh 라는 프로그램이 semester를 인자로 받는 것이다, 즉 sh 라는 프로그램이 semester를 작동시킨다고 보면 된다. 우리는 sh 라는 프로그램을 실행시킨 것이고, 그 이후의 일은 sh가 하는 것이다. 주체가 sh 라는 프로그램.

 

하지만, ./semester는 현재 쉘 사용자가 직접 semester라는 파일을 현재 디렉토리에서 실행시키는 것이다. 따라서, 아까 위에서 봤듯이, Permission denied 라는 에러를 받았다. 주체가 사용자 나.

 

이러한 사실을 알고 나면, sh 와 ./ 의 근본적인 차이점을 이해하기 쉽다. 

sh는 새로운 쉘(이해를 돕기 위해 프로그램이라고 하죠)에서 파일을 실행하기 때문에 만약 파일에 변수를 사용했다면, 프로그램이 끝났을 때, 해당 변수는 의미가 없게 되지만, 

./는 현재 쉘에서 직접 실행하기 때문에 파일에 변수를 선언했어도, 해당 변수를 파일 실행이 끝나도 그대로 사용할 수 있다. 

 

7.

man chmod

 

8.

chmod는 파일의 mode(비트 권한 범위)를 change하는 프로그램이다. 

권한 부여 대상과 권한 종류에 따라 특정한 수가 매칭되어 있는데, 이를 모두 더한 수가 바로 해당 권한의 수라고 생각하면 된다.

예를 들어, 소유자에게 읽기 권한을 주는 수는 400이고, 사용자에게 쓰기 권한을 주는 수는 200, 그리고 사용자에게 실행 권한을 주는 수는 100이다. 만약 사용자에게 이 파일에 대한 세 가지 권한을 모두 주고자 한다면, 이를 모두 합산한 700을 chmod의 인자로 넘겨주면 된다.

chmod 700 semester

 

9. 현재 위치는 missing 폴더

./semester | grep -i last-modified | cut -d ' '  -f2- > ../last-modified.txt

이 문제는 머리 좀 싸맸다. 

이 문제를 해결하기 위해 알아야 할 개념은 파이프라인, grep, cut으로 크게 세 가지이다. 

간단히 설명하자면,

파이프라인은 파이프라인 앞의 프로그램의 output을 파이프라인 뒤의 프로그램의 input으로 전달하는 역할을 수행한다.

grep은 특정한 문자열 패턴을 파일(input stream) 안에서 찾는 프로그램이다. 

cut은 문자열을 파싱하는 프로그램이라고 생각하면 된다.

 

흐름

./semester의 실행 output이 파이프라인을 통해 grep의 input stream으로 들어 간다. 

grep 프로그램이 last-modified라는 항목을 ./semester의 output(=grep의 input)에서 찾는다.

해당 항목을 찾았다면 해당 output이 파이프라인을 통해 cut 프로그램의 input stream으로 들어 간다.

공백 문자를 기준으로 input을 파싱하고 파싱된 조각들 중에서 -f2- 두 번째 조각부터 끝까지를 output으로 last-modified.txt에 작성한다.

 


많은 사람들이 애플리케이션, GUI와 같은 비교적 사용하기 쉬운 비주얼 인터페이스를 사용하여 컴퓨터와 상호작용하고 있는데, 이러한 비주얼 인터페이스들은 제약이 많다. 만들어진 입력 칸과 버튼이 있는 곳에서만 상호작용할 수 있지, 비주얼 인터페이스들이 정의하고 있지 않은 의도에 대해서는 컴퓨터와 상호작용할 수 없다. 

 

따라서, 이러한 쉘을 통해서 좀 더 자유롭고, 방대한 범위에서 내가 원하는 의도대로 컴퓨터와 상호작용하는 것이 어쩌면 개발자에게 있어서는 강력한 도구가 될 수 있을 것 같다. 

 

참고 자료:

https://missing-semester-kr.github.io/2020/course-shell/