TIL 11. Linux & Terminal(1)

seod0209·2021년 3월 24일
0

운영체제

우선 리눅스를 알아보기전에 사전에 운영체제(OS)에 대한 개념에 대해 알아야 한다.

0-1. 운영체제, OS(Operating System)?

컴퓨터는 기계이다. 이 컴퓨터라는 기계는 2진법밖에 알지 못한다.
사용자가 컴퓨터를 통해서 어떤 기능을 수행하고 싶으면
컴퓨터가 이해할 수 있게 이진법으로 명령을 내려서 작동을 시켜야하는데
이러한 과정은 매우 어렵고 복잡하고 효율적이지 못하며
소수의 전문가들만 컴퓨터를 사용할 수 있는 문제가 있다.

=>>
따라서 사용자가 명령을 내리면, 관련된 명령을 이해하고 그것을 하드웨어에 전달하여 사용자가 원하는대로 하드웨어를 조작하는 일을 대신 수행해주는 프로그램을 운영체제라고 한다.

이러한 하드웨어를 조작하는 소프트웨어를 운영체제라고 하는데
통상 이러한 운영체제 기계들이 출고될 때 내장되어서 그 위에 다른 소프트웨어를 추가해서 사용할 수 없고 단일 소프트웨어로서 하드웨어를 조작하는 것을 펌웨어라고 한다.
예를 들면 에어컨, 스마트선풍기, mp3플레이어들 또한 하나의 기계인데 이러한 것들을 조작해주는 운영체제는 펌웨어(Firmware)라고 부른다.

우리가 일반적으로 OS라고 부르는 것들은 컴퓨터 위에서 동작하는 운영체제
윈도우, Mac OS, Linux, UNIX등이 있다.

0-2. 운영체제의 동작원리

https://lh3.googleusercontent.com/nB5xJAIqgfxJmhcv869U4iEw1Xtw78hQwXP7QNMAwTLz1zyg5G4sBrMN0zEjwz9xoXNSUMRv8hjzZzxEqDHHyv69Cxxwozm4P7MewkpejaLO86rR1XMc0PB-nD-5nGytNMPQqvQ

::운영체제는 크게 하드웨어를 조작하는 커널
커널과 사용자 사이에서 Interface역할을 하며 사용자가 내린 명령을 커널에 전달해주고(input), 커널이 명령을 실행한 결과를 다시 사용자에게 보여주는(output)역할을 해주는 것을 쉘(Shell)이라고 한다.

::운영체제의 역사
대중적인 OS가 개발되기 전의 초창기 컴퓨터는 각자의 작동방식이 달랐기에 한 컴퓨터에서 돌아가는 소프트웨어를 만들면, 다른 컴퓨터에서 사용할 수 없고 다시 그 컴퓨터에 맞춘 소프트웨어를 짜야 한다.
이러한 환경에서 1969년 AT&T의 Bell 연구소의 데니스리치를 포함한 기술자 팀이 이러한 호환성 문제를 해결하기 위해서 하나의 운영체제를 만들기 위한 시도를 하며 이 프로젝트를 UNIX프로젝트라고 했다.
이 유닉스 운영체제는 초기에는 어셈블리어로 만들어졌다가, 어셈블리어는 해당 컴퓨터가 사용하는 기계어에 따라서 다 다르게 작성되어야 된다는 단점으로 인해 범용성이 떨어지기에 호환성을 위해서 C언어라는 프로그래밍언어를 만들어서 C언어로 재작성되어 탄생하여 그 범용성으로 인해 여러곳에서 사용되기 시작했다.
유닉스는 초기에는 무료로 배포하고, 소스코드도 공개되어 있었지만, 추후에 상업화가 되면서 유료로 사용해야되기 시작했고 이러한 풍토에 반감을 느낀 사람들이 모여서 자유로운 운영체제를 만들겠다는 일념하에 GNU프로젝트를 시작하였습니다.
이러한 GNU프로젝트는 거의 다 완성되어 가는 상태였지만 핵심이 되는 커널이 빠진상태였고 이러한 커널의 개발은 기존 유닉스체제에서 돌아가는 소프트웨어와의 호환성 문제로 개발이 지지부진 해지고 있었습니다.
그 때 핀란드의 헬싱키에서 리누스토발즈라는 대학생이 유닉스와 호환되는 커널을 만들었고
GNU에서 이 커널을 정식으로 GNU프로젝트의 커널로 사용하면서 널리 퍼지기 시작했다.
이러한 리눅스는 오픈소스의 취지에 따라서 누구나 가져가서 사용할 수 있고 소스코드도 개방되어 있기에 많은 곳에서 사용되고 있습니다.

::운영체제의 종류
운영체제는 윈도우 계열, UNIX계열 크게 두 부류로 나눠질 수 있습니다.
윈도우를 제외한 대부분의 OS는 유닉스를 기반으로 만들어진 OS입니다. 따라서 비슷한 구조와 쉘 명령어를 가지고 있습니다.

+ 추가: Shell(쉘)

: 쉘은 사용자가 명령을 내리면 해석해서 커널에 전달해주는 인터페이스 역할을 한다.
이러한 쉘을 크게 GUI, CLI로 나눌 수 있다
1. CLI(Command Line Interface) : CLI는 명령어 기반 인터페이스로 터미널 등의 프로그램을 통해서 문자열을 입력하고 문자로 반환된 결과를 확인하는 인터페이스

  1. GUI(Graphic User Interface) : GUI는 그래픽 유저 인터페이스로서 사용자가 편리하고 직관적으로 알아볼 수 있도록 그래픽으로 입출력등의 기능을 수행해서 보여주는 것.
    흔히 우리가 윈도우를 처음 키면 보는 아이콘들로 이루어진 화면이 GUI입니다.

GUI의 편리성과 쉬운 접근성으로 인해 대부분의 운영체제는 GUI기반으로 움직이지만, GUI가 필요없는 환경에서 또는 CLI로 더 간편하고 빠르고 자동화하여서 할 수 있는 일들이 존재하기에 CLI는 현재까지 많이 사용되고 있습니다.

맥에서는 이러한 CLI로 Terminal이란 프로그램을 내장하고 있고
윈도우에서는 cmd라는 프로그램이 있습니다.

맥과 리눅스는 둘다 유닉스 기반으로 만들어진 운영체제기에 CLI에서 사용되는 명령어가 대부분 비슷하거나 같습니다. 따라서 같은 명령어를 통해서 조작할 수 있습니다.

  • 추가: 터미널: 사람과 컴퓨터의 대화 중간역할 like 카카오채팅창같은 ,,

사람 -> 터미널-> 컴퓨터 -> 사람

1. Linux

1-1. 의의

Linux는 1991년 Linus Torvals(라이너스 토발즈)가 개발한 운영체제 이다.
Linux는 오픈소스 이며 누구나 코드를 볼 수 있다.

Linux는 시스템을 운영하는데 가장 널리 사용되는 운영체제 이다.
Windows 시스템이나 application이 아닌 이상
일반적으로 시스템 서버는 linux 기반으로 운영되고 있다.
그러므로 개발자는 linux에 대 잘 알아야 한다. Linux에 시스템을 실행하고 유지하고 관리하기 때문이다.

Linux는 윈도우스 처럼 일반인을 위한 운영체제는 아니기 때문에
익숙치 않으면 사용이 많이 어려울 수 있다.

  • Linux Directory Structure
  • PATH
  • Configs
  • Shell Commands

위의 단어들을 처음 들어봤다면 어렵게 느껴질 수 도 있다. 그러나 어렵게 생각하지 않아도 된다.

리눅스를 알야아 하는 이유?

  • 다중 사용자 및 다중 처리 시스템
  • 커널을 비롯하여 대부분의 응용 프로그램의 소스 코드가 공개된 시스템
  • 다양한 네트워크 및 프로토콜 및 환경지원
  • 대부분이 C언어로 이루어진 커널이라서 뛰어난 이식성을 보임
  • 유연성과 확장성
  • 뛰어난 안정성과 보안성(오픈소스의 특성 상 많은 이들이 참여하고 발전시킨 결과)
  • 다양한 배포판의 존재

:: 이러한 특성으로 인해서 24시간 운영되어야 하며, 안정적이여야 하고, 특히 다중처리 시스템에 최적화 되어있다는 점으로 인해 서버를 돌리기에 최적화된 운영체제로 선택받고 있습니다.

이 중 유닉스는 상용화되어 사용되고 있기 때문에 아주 초기에 유닉스를 선택한 회사나 극도로 보수적인 성향이 요구되는 회사(은행 등 보안문제로 인해 시스템을 변경하기 쉽지 않은 회사들)을 제외하고는 라이센스 비용을 지불하면서 까지 유닉스를 사용하고 있지 않고
대부분은 리눅스를 서버용 운영체제로 사용하고 있습니다.

구글도 리눅스를 커스터마이징 한 운영체제로 운영하고 있으며 네이버또한 리눅스를 사용하고 있습니다.
또한, 최근에는 카카오뱅크가 리눅스를 서버운영체제로 선택하면서 금융권에 큰 충격을 가져다 주었습니다.

이처럼 대부분의 서버는 리눅스 환경 하에서 운영되고,
안드로이드, 기타 스마트TV등의 기기도 대부분은 리눅스 커널 기반으로 작동하고 있기 때문에
리눅스에 대해서 알아야 할 필요가 있다.

1-2. Linux File System Hierarchy (FHS)

:리눅스 파일 구조

1-2-1. Root 디렉토리 (directory): /
FHS의 가장 위에는 / 디렉토리가 있다. Tree 형태의 FHS의 뿌리가 된다는 뜻이다.
참고로 디렉토리 (directory)는 윈도우스의 폴더(folder)와 동일한 개념이다.

시작점인 root 디렉토리 안에 여러 하위 디렉토리들이 있고 각 하위 디렉토리들안에 또 하위 디렉토리 들이 있는 식이다. 그리고 각 디렉토리들은 slash (/) 로 구분한다.
참고로 윈도우스는 back slash (\) 로 구분한다.

예를 들어, root 디렉토리 안에 home 이라는 하위 디렉토리가 있고
그 안에 eun 이라는 하위 디렉토리가 있고 그 안에 bin 이라는 디렉토리가 있다면 해당 bin 디렉토리까지의 경로는 다음과 같이 표현한다.

/home/eun/bin

1-2-2. "change directory": cd /

  • cd 명령어 특정 디렉토리로 이동할때 사용된다. 
    cd 명령어 다음에 가고자 하는 디렉토리 경로를 입력하면 된다.
    여기서는 root 디렉토리로 가기 때문에 / 하나만 입력했다.
    만일 root 디렉토리의 하위 디렉토리인 home 디렉토리 의 하위 디렉토리인 eun 디렉토리의 하위 디렉토리인 bin 디렉토리로 가고자 한다면 /home/eun/bin 을 입력해야 한다.

1-2-3. list: ls
Root 디렉토리로 변경했으면 ls 명령어를 실행하자. 
해당 디렉토리의 내용물들을 나열해주는 역활을 한다.

짙은 파란색이 디렉토리 이며 하늘색은 파일을 나타낸다.

Mac 에서는 다를 수 있다. Mac에서는 /home 디렉토리가 아니라 /Users 디렉토리에 유저의 home 디렉토리가 있다.

1-3. Home Direcotry

유저의 공간이기 때문에 가장 중요하고 기본이 되는 디렉토리.
주로 home 디렉토리에서 많은 것을 하게 된다.

cf. system directory
: Home 디렉토리 이외의 다른 디렉토리들.
즉 리눅스의 운영과 관리에 관련한 파일들이 존재하는 디렉토리 들이다.

디렉토리 경로를 생략하고 cd 만 입력하면 자동으로 home 디렉토리로 이동한다.

그 뿐만이 아니다. Home 디렉토리 경로를 나타낼때 ~ (tilda) 를 사용해서 나타낼수 있기 까지 하다. 예를 들어, cd ~ 명령어를 사용하면 home 디렉토리로 간다.
또한 cd ~/bin 명령어를 사용하면 home 디렉토리의 하위 디렉토리 bin 디렉토리로 이동한다. 즉 ~ == /home 

1-4. Directory 경로

디렉토리 경로에는 2가지 유형이 있는데 absolute path와 relative path 이다.

1-4-1. Absolute Path: 절대적(완전한) 경로

: Absolute path는 root 디렉토리 부터 시작하는 경로를 뜻한다.

앞서 보았던 /home/eun/bin 가 absolute path 이다.
Root 디렉토리에서 부터 시작하기 때문에
현재 나의 위치와 상관 없이 항상 정확히 해당 경로로 이동 할 수 있다.

1-4-2 Relative Path: 상대적 경로

현재 내 위치를 기반으로 움직이는 경로이다.
. 과 .. .

  • 현재 디렉토리: . (single dot)
    예를 들어, 현재 /home/eun 디렉토리에 위치해 있는데 
    eun 디렉토리의 하위 디렉토리 인 bin 디렉토리로 가고 싶다면
    cd ./bin 명령어를 입력하면 된다.

여기서 . 은 현재 디렉토리를 뜻함으로 cd /home/eun/bin 과 동일하다.
디렉토리 경로가 길 경우 매번 긴 경로를 다 입력하기 귀찮음으로
편리하라고 만들어진 특별 심볼이다.

  • 현재 디렉토리의 상위 디렉토리: ..
    현재 디렉토리 바로 전 디렉토리
    예를 들어, 현재 디렉토리가 /home/eun/ 인데 /home/yerikim 디렉토리로 가고 싶다면 cd ../yerikim 명령어를 사용하면 된다. 
    /home/eun 디렉토리 에서 .. 는 상위 디렉토리 즉 /home 디렉토리를 뜻함으로 ../yerkim == /home/yerikim 이 된다.

1-5. File Path

파일로 가는 경로도 디렉토리 경로와 동일하다.
예를 들어, /home/eun/bin 디렉토리 안에 test.py 라는 파일을 열고 싶으면
`open /home/eun/bin/tesst.py` 라고 실행.

2. Configs

2-1. Config file:

리눅스에는 설정을 주로 파일을 통해서 한다.
그리고 여러 config file, 즉 여러 설정 파일들이 있다.

그 중 가장 중요한 설정 파일이 바로 shell 설정 파일이다.
각 shell 마다 고유 설정 파일이 있다.

Bash는 .bashrc 라는 설정파일을 사용하고
zsh는 .zshrc 라는 설정 파일을 사용한다.

난 Zsh를 이미 설치했으므로 Zsh 설정 파일을 보도록 하자.

먼저 zsh 설정 파일의 위치를 알아보도록 하자.
Shell 설정 파일을 비롯한 많은 설정 파일들이
대부분 유저의 home 디렉토리에 있다.
 Zsh 설정 파일도 마찬가지 이다.

하지만 ls 명령어를 사용하면 .zshrc 파일이 보이질 않는다.
.zshrc 파일은 숨겨져 있는 hidden file이기 때문이다.

.zshrc 파일 이름이 . 으로 시작하는것이 보일 것이다.
이렇게 . 으로 시작하는 파일이나 디렉토리는 자동으로 숨겨지게 된다.
그리고 이러한 파일을 "dot file" 이라고 한다.

dot file을 볼려면 ls 명령어에 a 옵션을 주어야 한다.
여기서 a는 all 의 약자인다.
숨겨진 파일이든 안숨겨진 파일이든 다 나열 하라는 뜻이다.

위의 경우 zsh이 설치 되어 있지 않고 bash 쉘을 사용하기 때문에 .bashrc 파일이 있는 것을 볼 수 있다.

그러면 이러한 설정 파일을 통해 무엇을 설정 할 것인가?
아주 많은 설정을 할 수 있지만 그 중 가장 중요한 것은 PATH 환경 변수 설정이다.

2-2 PATH Enviroment Variable

2-2-1. environemnt variable(환경 변수)
: 현재 돌아가고 있는 shell의 어떠한 설정 값을 가지고 있는 변수를 뜻한다.
그리고 이러한 환경 변수들은 shell이 돌아가는 동안 계속 존재하며 사용된다.
그 증거로 echo $HOME 이라고 입력해보자. 
HOME 환경변수 값을 출력할 것이다
(그리고 이름에서 나오듯이 HOME 환경 변수는 유저의 홈 디렉토리 경로이다).

> echo $HOME
/home/eun

HOME 이라는 환경변수를 선언한 적이 없지만 이미 존재하고 있는것을 알 수 있다.
그 이유는 환경 변수들은 shell 이 시작할때 이미 자동으로 선언되었기 때문이다.
Shell은 이러한 환경변수 들을 통해 설정이 된다.

리눅스에는 여러 환경 변수들이 있는데 그 중 대표적인 환경 변수들은 다음과 같다.

  • HOME
    • 유저의 home 디렉토리 경로를 저장한 환경 변수
  • USER
    • 유저의 아이디를 저장한 환경 변수
  • PATH
    • PATH 값을 저장한 환경 번수

2-2-2. PATH 환경 변수
: 명령어들을 찾을 수 있는 경로들을 저장해놓은 환경 변수 이다.

예를 들어, 앞서 이미 실행해 본 ls 명령어를 보자. 실제 ls 명령어는 /bin 디렉토리 안에 위치해 있다. whereis 명령어를 사용하면 알 수 있다.

> whereis ls
/bin/ls

하지만 우리가 ls 명령어를 사용할때는 정확한 경로를 입력하지 않고 그냥 ls 만 입력한다. 그럼에도 불구하고 터미널에서 실행이 잘된다.

어디에 위치해 있는지 정확한 경로를 알아야 shell이 찾아서 실행할 수 있을것이다.
그러나 경로 없이도 실행이 되는 이유는 바로 PATH 환경 변수 때문이다.

명령어를 사용할때 만일 경로가 지정되지 않으면
shell이 PATH 환경 변수에 저장되어 있는 경로들을 하나 하나 보면서
실행 하고자 하는 프로그램이 위치해 있는지 찾는다. 그리고 찾으면 실행 시킨다.

PATH 값을 출력하면 다음과 같다.

> echo $PATH
/home/eun/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/snap/bin

하나의 긴 경로 처럼 보일 수 도 있지만 실은 여러 경로를 담고 있으며 각 경로들을 : 를 사용해서 구분한다.

  1. /home/eun/bin
  2. /usr/local/sbin
  3. /usr/local/bin
  4. /usr/sbin
  5. usr/bin
  6. /sbin
  7. /bin
  8. /usr/games
  9. /usr/local/games
  10. /snap/bin

그리하여 ls 명령어가 입력되면
shell이 PATH 환경 변수 값에 저장되어 있는 경로들을
맨 왼쪽 경로(1번) 부터 하나 하나 보면서 ls 라는 프로그램을 찾을 수 있는지 확인하고
찾으면 실행한다. 

ls 의 경우 /bin 에 위치해 있음으로 
PATH 값의 7번째 경로에서 찾게 되는것이다.
만일 못찾으면 못찾는다는 에러 메세지와 함께 실행 없이 종료된다.

  • PATH 가 중요한 이유는, 새로운 package를 설치하거나 시스템을 설정하거나 할때
    PATH가 설정이 제대로 안되면 실행이 제대로 안되는 경우가 많기 때문이다.

예를 들어, python 가상환경 매니저인 miniconda를 설치했는데 
conda가 실행이 안되는 경우 
conda의 경로가 PATH에 설정이 안되어있을 확률이 높다.

PATH 는 shell 설정 파일에서 설정한다.
Zsh의 경우 .zshrc 파일에서 설정하며 다음처럼 설정한다.

export PATH="/home/eun/bin/anaconda3/bin:$PATH"

export 는 JavaScript의 var 키워드 처럼
변수를 선언할때 사용하는 키워드라고 생각하면 된다. 

<PATH에 추가하고자 하는 경로>:$PATH

여기서 $PATH 부분은 PATH 변수의 값이 치환된다.

즉 /home/eun/bin/anaconda3/bin 라는 경로는 PATH 에 추가 하고 싶으면
다음 처럼 추가하는 경로를 먼저 선언(export)하고
그 다음 :, 그리고 $PATH를 선언 하는것이다.
그럼 기존의 PATH 값의 맨 앞쪽에 새로운 경로가 추가가 된다.

Useful Shell Tips

  • Shell 에서 ⬆️(위방향 화살표 버튼): 이전에(previously) 입력했던 명령어를 다시 불러냄.

  • ⬆️ 를 또 누르면: 이전 그 이전에 입력했던 명령어가 나오면서 이전 명령어들을 계속해서 볼 수 있다.

  • Zsh에서 history-substring-search 플러그인을 설치 했으면 (이 전 과제를 했다면 설치가 됬을것이다) 입력하고자 하는 명령어중 일부분을 입력 후 ⬆️ 버튼을 눌르면
    입력된 string이 포함된 이전 입력된 명령어만 불러낼 수 있다.

  • Control + a 눌르면 커서가 해당 줄의 맨 앞으로 이동한다.

  • Control + e 눌르면 커서가 해당 줄의 맨 뒤로 이동한다.

  • Mac에서 Commnad + k : 화면이 reset 된다.
    화면에 출력된 것이 너무 많아서 복잡할때 사용하면 깔끔하다.

Basic Shell Commands

Shell 명령어들을 잘 알고 익숙해져야 linux를 잘 쓸수 있다. 다음은 기본적인 shell 명령어 들이다. 찾아보고 직접 실행해 봐서 익숙해지도록 하자.

  • cd
  • ls
  • mv
  • cp
  • cat
  • less
  • tail
  • nohup
  • rm
  • mkdir
  • clear
  • pwd
  • chown
  • chmod
  • grep
  • history
  • ps

✏️ 많이 쓰는 명령어


Untitled

Piping

  • |
    • Pipe 이라고 한다. 위에서 아래로 내려가는 줄이 꼭 파이프 기둥 처럼 생겨서 그렇게 이름이 붙어졌다.
    • Pipe는 일반적인 명령어가 아니라 2개의 명령어를 이어주는 역활을 한다.
    • command1 | command2
    • command1의 결과값을 command2의 input으로 넘겨준다.
    • 예를 들어, history 명령어는 이제까지 입력한 명령어들을 출력해주는 명령어다. history 만 실행하면 결과값이 화면에 출력 되지만 | 를 사용해 grep 과 같이 사용하면 history가 출력하는 값들 중 원하는 값만 필터링을 할 수 가 있다.
    • history | grep ls

Man page

  • Manual page를 줄여서 man page 라고 한다.
  • 명령어를 어떻게 쓰는지 설명해 주는 역활을 한다.
  • man ls
  • Man page의 단점은 너무 길다는 것이다. 글이 너무 많아서 읽기가 힘들다. 그래서 최근에 나온 유용한 package가 있다. 바로 tldr 이다 (Too Long Didn't Read). tldr 명령어는 자주 사용하는 옵션이나 사용법만 간략하게 알려준다.
  • tldr ls
  • 다만 default로 포함되어 나오는 package가 아님으로 package manager를 사용해서 설치 해야 한다.

Projects

  • tldr package를 설치하도록 하자.
  • 각자 home 디렉토리에 /bin 디렉토리를 만들고 PATH에 추가하지.
  • Miniconda 를 설치하고 PATH를 설정해서 conda 명령어를 PATH에 추가하도록 하자.
  • 앞으로 자주 사용하게 될 package인 httpie를 설치하자. 앞으로 추후 API 개발시 자주 사용하게 될것이다.
profile
오늘도 여전히 사고친걸 해결해본당,,

0개의 댓글