티스토리 뷰

 

 

책 「모두의 리눅스」를 읽고 정리한 내용입니다.

 

 

원래 「모두의 리눅스」 챕터 별 글 하나로 정리할 생각이었는데 하다보니 너무 그냥 책 내용을 그대로 옮겨놓은 듯하게 되어버렸다. 따라서 그냥 책 전체 내용을 '명령어 위주로' 해서 글 하나로 정리해보려고 한다. 시간이 될 때마다 책 내용에 더해서 개인적으로 공부한 것들을 업데이트해나갈 것이다.

 

 


2장 셸이란 무엇인가

셸(shell): 사용자와 커널 사이에서 명령어를 받아들이고 커널의 실행 결과를 출력하는 소프트웨어, 커널의 인터페이스 역할

 

리눅스 커널의 동작 방식

1. 사용자가 셸에 명령어 입력

2. 셸은 명령어 찾아서 리눅스 커널에게 실행 의뢰

3. 리눅스 커널이 명령어 실행

4. 셸은 실행 결과를 전달받아 사용자 화면에 출력

 

셸 종류

sh 표준 셸, 주로 셸 스크립트 작성 시 사용

csh 대화형 조작에 편리한 기능, 뒤를 잇는 tcsh 등장

bash sh 바탕으로 기능이 추가된 셸, 리눅스의 기본 로그인 셸

tcsh C셸 계열의 셸, C셸 계열에서는 일반 사용자 프롬프트가 $이 아닌 %

zsh 비교적 최근에 개발된 셸, bash + tcsh 기능에 독자적인 기능 추가 

 

일시적으로 셸 바꾸기

<셸 이름> 기존 셸 위에 새로운 셸(비로그인 셸) 실행

logout 로그인 셸 종료

exit 로그인, 비로그인 셸 종료 

로그인 셸: 로그인 후 처음으로 시작되는 셸 

 

 


3장 셸을 능숙하게 다루는 방법

커맨드 라인 커서 이동 

Ctrl + b, 커서를 한 문자씩 뒤로 이동

Ctrl + f, 커서를 한 문자씩 앞으로 이동 

Ctrl + a, Home 커서를 맨 앞으로 이동 

Ctrl + e, End 커서를 맨 뒤로 이동 

Esc + b, Alt + b 커서를 한 단어씩 뒤로 이동 

Esc + f, Alt + f 커서를 한 단어씩 앞으로 이동 

Esc는 누른 채 조작하는 것이 아닌 누르고 뗀 뒤에 조작하는 방식 

 

커맨드 라인 문자 삭제 

Backspace, Ctrl + h 커서 위치 기준으로 뒤에 있는 한 문자 삭제

Delete, Ctrl + d 커서 위치의 한 문자 삭제, 커맨드 라인에서 아무것도 입력하지 않은 상태에서 Ctrl + d 입력 시 배시 셸 로그아웃

Ctrl + w 커서 뒤에 공백이 나오기 전까지 있는 문자열 삭제 

 

커맨드 라인 자르기 및 붙여넣기 

Ctrl + k 커서의 위치에서 끝까지 자르기

Ctrl + u 커서의 위치에서 커맨드 라인의 첫 문자까지 자르기 

Ctrl + y 자른 내용 붙여넣기 

- 배시에서는 붙이기(paste)를 양크(yank)라고 함 ⇒ 텍스트 에디터 vim에서는 붙여넣기에 p 사용 

 

셸, 터미널 관련 명령어

Ctrl + s 화면 표시를 잠금 (출력을 잠금, but 입력은 잠기지 않음)

Ctrl + q 화면 표시 잠금을 해제 

Ctrl + c 실행 중인 명령어 강제 종료, 커맨드 라인에서 명령어 입력 중에는 새로운 커맨드 라인으로 넘어감

Ctrl + l, clear 화면에 표시되는 내용 모두 지우고 커서 화면 좌측 상단으로 이동 

reset 터미널 초기화 

 

자동 완성 기능 

Tab 지금까지 입력한 문자열에 매칭되는 고유한 명령어 있다면 해당 명령어 자동 완성 

Tab 2번 지금까지 입력한 문자열에 매칭되는 고유한 명령어 여러 개라면 해당 명령어 목록 출력 

 

명령어 이력 확인 

Ctrl + p, 바로 이전 명령어 불러옴 

Ctrl + n, 바로 다음 명령어 불러옴

Ctrl + r 증분 검색 모드(문자 하나 입력 시마다 이력 검색 발생)로 명령어 이력 검색 

증분 검색 모드에서 Ctrl + r 이전의 검색 결과로 하나씩 이동

증분 검색 모드에서 Enter 현재 검색 결과를 실행 

증분 검색 모드에서 Esc 현재 검색 결과를 실행하지 않은 채 커맨드 라인으로 복귀 (보통 검색 결과를 수정하기 위해 사용)

증분 검색 모드에서 Ctrl + g 검색 결과를 지우고 커맨드 라인으로 복귀 

 

 


4장 파일과 디렉터리

리눅스에서는 모든 것을 파일로 다룸 ex. 문서, 이미지, 영상, 프로그램, 입출력 장치, 리눅스 커널, 시스템 설정

 

리눅스의 디렉터리  

- 루트 디렉터리: 리눅스의 디렉터리 구조에서 맨 위에 있는 / 디렉터리

- (디렉터리) 트리: 루트 디렉터리 아래에 디렉터리와 파일이 있는 계층 구조

- 리눅스에서는 언제나 시스템 전체에 단 하나의 트리를 가짐

 

리눅스의 각 디렉터리 역할 

/bin 일반 사용자 및 관리자가 사용하는 명령어의 실행 파일 배치

/dev 디바이스 파일 배치

/etc 리눅스에서 돌아가는 다양한 애플리케이션의 설정 파일 배치 

/home 사용자 별로 할당되는 홈 디렉터리 배치 

/temp 임시 파일 배치 

/usr 설치한 애플리케이션의 실행 파일, 문서, 라이브러리 등이 배치, 루트 디렉터리와 구조 비슷 

/var 변화하는 데이터(ex. 로그)를 저장하기 위한 디렉터리 

 

디렉터리 관련 명령어 

pwd 현재 위치한 디렉터리 경로 출력 print working directory

cd 지정한 디렉터리로 이동 change directory

cd ~(틸드) 현재 로그인한 사용자의 홈 디렉터리로 이동

ls 지정한 디렉터리 내 파일, 디렉터리 목록 출력(인자 지정하지 않으면 현재 디렉터리) list

ls -l 파일 이름, 파일의 속성, 상세 정보 출력

ls -a 숨겨진 파일(.로 시작하는 파일)도 함께 출력

ls -F 파일 이름 뒤에 파일 종류 의미하는 기호를 추가해 출력 (/ 디렉터리, * 실행 가능 파일, @ 심볼릭 링크)

ls -w 30, ls -w30, ls --width 30, ls --width=30 출력 너비 설정

ls --quote-name, ls --quote 파일, 디렉터리 이름을 "로 묶어서 출력

- 커맨드 라인 인자: 명령어 뒤에 스페이스로 구분하여 전달하는 문자열

 

경로 확장 

- 경로 확장은 셸의 기능으로, 셸은 명령어에 인자를 전달하기 전 경로 확장 수행

* 임의의 문자열 

$ ls he* #이름이 he-로 시작하는 파일이나 디렉터리
$ ls *.txt #이름이 -.txt로 끝나는 파일이나 디렉터리

 

? 임의의 한 문자 

$ ls a?? #이름이 3글자이고 a-로 시작하는 파일이나 디렉터리
$ ls te?.py #이름이 6글자이고 te-로 시작하며 -.py로 끝나는 파일이나 디렉터리

 

 


5장 파일 조작의 기본 

디렉터리 생성

mkdir [옵션] <생성할 디렉터리 이름>... 해당 이름의 파일이나 디렉터리 이미 있는 경우 오류 발생 

mkdir -p dir/sub/sub2 중첩된 디렉터리 생성 시 중간 경로의 디렉터리가 없다면 모두 생성 

 

파일 생성 

touch <생성할 파일 이름>... 해당 파일 없다면 내용 없는 빈 파일 생성

touch 파일의 타임스탬프 갱신하는 명령어 (이미 존재하는 파일 지정 시 내용 유지)

 

파일, 디렉터리 삭제 

rm [옵션] <삭제할 파일 이름>... 파일, 디렉터리 삭제 

rm -r <삭제할 디렉터리 이름> 재귀적으로 디렉터리 트리를 삭제, 대상 디렉터리와 그 내부 디렉터리 및 파일 전부 삭제 recursive

rmdir <삭제할 디렉터리 이름>... 빈 디렉터리 삭제, 대상 디렉터리가 비어있지 않으면 오류 발생

 

파일 내용 출력 

cat [옵션] <파일 이름>... 해당 파일 내용 출력

cat -n 행 번호 함께 출력 

- 명령어의 인자로 파일 지정하지 않으면 키보드 입력을 그대로 화면에 출력, Ctrl + c로 실행 종료

 

less [옵션] <파일 이름>... 파일을 화면 단위로 출력하여 위아래로 스크롤하며 파일을 볼 수 있게 함 

Space, f, Ctrl + v 한 화면 아래로 스크롤 

b, Esc + v, Alt + v 한 화면 위로 스크롤 

j, Ctrl + n, Enter 한 행 아래로 스크롤 

k, Ctrl + p 한 행 위로 스크롤 

q less 명령어 종료 

/ less로 열려 있는 파일에서 문자열 검색 

/문자열 문자열을 현재 커서 위치 기준 아래 방향으로 검색

?문자열 문자열을 현재 커서 위치 기준 위 방향으로 검색

n 다음 검색 결과로 이동 

N 이전 검색 결과로 이동 

q 검색 종료 

 

파일, 디렉터리 복사 

cp [옵션] <복사할 파일 이름>... <복사할 위치> 파일, 디렉터리 복사 

<복사할 위치>로 파일, 디렉터리 모두 가능

- 이미 같은 이름의 파일이 있으면 덮어씀

 

cp -r sourceDir destDir

- destDir이 없으면 sourceDir 내용이 모두 복사되어 destDir 생성

- destDir이 있으면 destDir 밑에 sourceDir 복사되어 생성 

 

파일, 디렉터리 이동

mv [옵션] <이동할 파일 이름>... <이동할 위치>

<이동할 위치>로 파일, 디렉터리 모두 가능

- 파일 이동 시 원래 있던 곳에는 더 이상 존재X

- 이동할 위치에 같은 이름의 파일이 있으면 덮어씀

 

링크 생성 

ln [옵션] <링크할 파일 이름> <링크 이름>

- 링크: 파일에 별명을 붙이는 것 

 

ln file1 file2 하드 링크 file2 생성 

- 한 파일 원본에 이름을 여러 개 붙이는 기능

- 하드 링크 중 하나를 삭제해도 모든 하드 링크를 삭제하지 않는 한 원본 파일은 삭제되지 않음 (원본 파일도 하드 링크 중 하나) ⇒ 원본 파일 삭제해도 하드 링크 깨지지 않음

 

ln -s file1 file2 file1에 대한 심볼릭 링크 file2 생성

- ls -l 명령어 실행 시 심볼릭 링크의 경우 어떤 파일에 연결되어 있는지 화살표(→)로 표시 

- 원본 파일에 대한 정보가 담긴 작은 특수 파일로, 하드 링크와 달리 원본과 구별됨

- 심볼릭 링크 삭제하지 않은 채 원본 파일 삭제하면 심볼릭 링크 깨짐

 

 


6장 파일 검색 및 명령어 사용법 

디렉터리 트리에서 검색 

find <검색할 디렉터리 이름> <검색 조건> <액션> 검색할 디렉터리를 기준으로 검색 조건을 만족하는 파일을 찾아 액션 실행

- 지정한 디렉터리 트리를 내려가면서 검색 조건에 일치하는 파일 검색

- 검색 조건 지정하지 않으면 지정한 디렉터리 내 모든 파일과 디렉터리 대상으로 액션 실행

- 액션 지정하지 않으면 -print가 기본적으로 실행

 

검색 조건

-name 대소문자 구별하여 파일 이름으로 검색 

-iname 대소문자 구별하지 않고 파일 이름으로 검색 

-type <파일 형식> 파일 형식으로 검색 (파일 형식: f 보통 파일, d 디렉터리, l 심볼릭 링크)

<검색 조건 1> -a <검색 조건 2> 검색 조건 AND 연산, 생략 가능

 

데이터베이스에서 검색 

locate [옵션] <검색 패턴> 경로의 일부를 지정하여 전용 데이터베이스에서 검색 ⇒ 디스크를 스캔해서 파일을 찾는 find보다 빠름

sudo updatedb 슈퍼 사용자 권한으로 파일 경로 목록을 데이터베이스에 등록

- 기본적으로 데이터베이스를 하루에 한 번 만들도록 설정됨

 

-i, --ignore-case 대소문자 구분하지 않고 검색

-b, --basename 패턴을 포함한 파일 또는 디렉터리만을 검색, 해당 옵션 사용하지 않으면 검색된 디렉터리의 하위 디렉터리와 파일까지 모두 출력

-A, --all AND 조건 검색, 지정한 패턴을 모두 만족하는 파일 또는 디렉터리 검색

locate <검색 패턴 여러개>; OR 조건 검색, 지정한 패턴 중 하나라도 일치하는 파일 또는 디렉터리 검색

 

명령어 사용법 확인 

<명령어> --help 해당 명령어에 대한 도움말 출력

man <명령어> 해당 명령어의 온라인 메뉴얼 출력, less 명령어가 내부적으로 사용되어 메뉴얼 표시 

man -k <키워드> 명령어 이름을 모르는 경우 키워드로 뉴얼 검색 가능, 명령어 이름 (섹션 번호) - 명령어 설명 형태로 출력

man <섹션 번호> <명령어> 해당 섹션 번호의 명령어 뉴얼 출력, 다른 섹션에 같은 이름의 명령어 존재할 수 있음 ex. crontab(1), crontab(5) → 섹션 번호 생략 시 섹션 번호 값이 가장 작은 뉴얼 출력

man -wa <명령어> 해당 명령어가 어떤 섹션에 포함되어 있는지 확인, 뉴얼 페이지의 실제 파일 경로가 출력  

 

섹션 

1: 명령어

2: 시스템콜

3: 라이브러리 함수

4: 디바이스 파일

5: 파일 서식

6: 게임

7: 기타

8: 시스템 관리 명령어

9: 커널 루틴

 

명령어 파일 검색 

- 리눅스 명령어의 실체파일 ex. cat 명령어의 실체는 /bin/cat 파일

- 셸이 PATH라는 환경 변수에 저장된 위치에서 명령어 파일을 찾도록 되어 있기 때문에, 전체 파일 경로가 아닌 명령어 이름만으로도 명령어 호출 가능 ⇒ PATH 설정해두면 명령어 파일이 실제로 어디에 있든 명령어 이름만으로 실행 가능

which [옵션] <명령어> 환경변수 PATH의 디렉터리를 검색하여 지정한 명령어의 전체 경로 출력 

which -a  <명령어> 같은 이름의 명령어 파일 모두 출력, which 명령어 기본적으로 같은 이름의 파일 여러 개 있어도 제일 먼저 발견된 것만 출력

 

 


7장 텍스트 에디터 

텍스트 에디터 vim

vim vim 기동

:q + Enter vim 종료

Esc 텍스트 입력 모드 → 명령어 입력 모드로 변경 

vim <파일 이름> 해당 파일 vim으로 열기, 해당 파일 없다면 파일 생성 

:w 파일 저장

:w <파일 이름>; 해당 이름으로 파일 저장

:q! 변경 내용 저장하지 않고 vim 종료 

 

커서 이동

h 왼쪽으로 이동

j 아래로 이동

k 위로 이동

l 오른쪽으로 이동

w 다음 단어의 첫 글자로 이동

b 이전 단어의 첫 글자로 이동

- Vim에서는 공백 이외의 쉼표나 괄호와 같은 기호도 단어 구분자로 사용 ex. can’t → cat, ‘, t 단어로 인식

W 공백을 기준으로 다음 단어의 첫 글자로 이동

B 공백을 기준으로 이전 단어의 첫 글자로 이동

0 행의 시작으로 이동

$ 행의 끝으로 이동

gg 첫 행의 시작으로 이동

G 마지막 행의 시작으로 이동

<숫자>G 행 번호가 <숫자>인 행의 시작으로 이동

 

문자 입력 및 삭제 

x 커서가 위치한 문자 1개 삭제

i, a 명령어 입력 모드 → 텍스트 입력 모드로 변경

i 입력 모드로 전환 후 입력 문자 커서의 왼쪽에 추가

a 입력 모드로 전환 후 입력 문자 커서의 오른쪽에 추가

 

자르기(delete), 복사하기(yank), 붙여넣기(put)

d$ 현재 행의 위치에서 마지막까지 자르기

d0 현재 행의 위치에서 시작까지 자르기

x, dl 문자 한 개 자르기

dw 단어 한 개 자르기

dgg 현재 위치 행에서 문서 시작 행까지 자르기

dG 현재 위치 행에서 문서 끝 행까지 자르기

dd 현재 커서가 위치한 행 전체 자르기

y$ 현재 행의 위치에서 마지막까지 복사

y0 현재 행의 위치에서 시작까지 복사

yl 문자 한 개 복사

yw 단어 한 개 복사

ygg 현재 위치 행에서 문서 시작 행까지 복사

yG 현재 위치 행에서 문서 끝 행까지 복사

yy 현재 커서가 위치한 행 전체 복사

p 커서가 위치한 곳에 자른 내용 붙여넣기

 

그 외 조작

J 커서가 위치한 현재 행과 다음 행이 한 행으로 연결

u 직전에 실행한 동작 취소 undo

Ctrl + r 취소한 동작 다시 실행 redo

 

검색과 치환 

/<검색 문자열> 현재 커서 위치에서 아래 방향으로 문자열 검색

?<검색 문자열> 현재 커서 위치에서 위 방향으로 문자열 검색

n 다음 검색 결과로 이동

N 이전 검색 결과로 이동

:%s/<검색할 문자열>/<치환할 문자열>/g 파일 내 <검색할 문자열>을 <치환할 문자열>로 모두 치환

 


8장 배시 설정 

별칭 설정 

alias <별칭>='<명령어>' 명령어에 별칭을 붙임, 보통 복잡한 옵션이 붙는 경우 사용 

type <명령어> 해당 명령어가 별칭인지 아닌지 확인

unalias <명령어 별칭> 해당 명령어 별칭 삭제

 

별칭을 일시적으로 무효화하는 방법

/bin/ls 명령어의 전체 경로 입력

command ls 별칭이 아닌 원래 명령어 실행

\ls command와 동일하게 동작

 

셸 옵션 설정 

set -o/+o <셸 옵션 이름>

-o 해당 옵션 기능 활성화

+o 해당 옵션 기능 비활성화

 

set 명령어로 설정할 수 있는 옵션 

ignoreeof Ctrl + d로 인한 셸 종료 방지 옵션

noclobber 이미 존재하는 파일을 리다이렉트로 덮어쓰지 않도록 하는 옵션

noglob 경로 확장을 무효로 하는 옵션, * 등을 셸에서 확장하지 않음

 

shopt -s/-u <셸 옵션 이름>

-s 해당 옵션 기능 활성화

-u 해당 옵션 기능 비활성화

 

shopt 명령어로 설정할 수 있는 옵션 

autocd 디렉터리 ‘이름’을 입력하면 해당 디렉터리로 이동하는 옵션

dotglob *?를 사용한 경로 확장 결과에 .로 시작되는 파일(숨긴 파일)도 포함시키는 옵션

cdspell cd 명령어 실행 시 디렉터리 이름 오타를 자동 교정해주는 옵션

globstar 경로 확장으로 ** 패턴 사용하면 서브 디렉터리까지 포함한 모든 파일에 매치되는 옵션

\histappend 배시를 종료할 때 히스토리 파일에 명령어 이력을 덮어쓰지 않고 추가(append)하는 옵션

 

셸 변수 

<변수명>=<값> 셸 변수 값 설정, 값이 공백 포함하는 경우 '"로 감싸줌

$<변수명> 셸 변수의 값 참조

- 셸 변수에 값 설정 시 = 양 옆에 공백 불가 (공백 있으면 변수명을 명령어로 인식)

 

PS1 셸 변수

- 프롬프트(커맨드 라인 앞부분에 표시되는 기호) 설정 

\d 현재 날짜(요일, 월, 일 형식)

\h 서버의 호스트 이름

\H 서버의 도메인 이름

\n 개행문자(줄바꿈)

\t HH:MM:SS 형식으로 24시간 단위의 현재 시각 표시

\u 현재 사용자 이름

\w 현재 디렉터리의 전체 경로 표시

\W 현재 디렉터리의 전체 경로 중 마지막 디렉터리만 표시

\$ 현재 사용자가 root 사용자이면 #, 그 외에는 $ 표시

\\ \ 문자 자체 표시

 

PATH 셸 변수

- 명령어의 실제 파일 위치를 찾는 디렉터리가 :로 구분되어 저장 

PATH="$PATH:~/bin" 명령어의 위치를 찾는 디렉터리로 ~/bin 경로 추가

 

LANG 셸 변수

- 언어, 나라, 지역을 특정하기 위한 식별자

locale -a 시스템에서 지원하는 전체 로케일 출력

 

그 외 셸 변수 

HISTFILE 커맨드 라인 이력을 저장할 파일 이름, 기본값은 ~/.bash_history

HISTFILESIZE 파일에 저장할 커맨드 라인 이력의 최대 개수

HISTSIZE 메모리에 저장할 커맨드 라인 이력의 최대 개수

HOME 홈 디렉터리 경로

SHELL 로그인 셸의 경로

PWD 현재 디렉터리 경로

 

환경 변수 

- 외부 명령어: 파일 시스템에서 실행 파일로 존재 ⇒ 셸 외부에서 실행 → 셸 변수 참고 불가

- 내장 명령어: 셸 자체에 포함

type <명령어> 해당 명령어가 외부 명령어인지 내장 명령어인지 확인

 

- 환경 변수: 외부 명령어에서도 값을 참조할 수 있는 변수

printenv 현재 셸에 설정된 환경 변수 출력 

export <셸 변수 이름> 환경 변수 설정 ex. export LESS='--no-init'

 

배시 설정 파일 

- 셸 변수나 alias는 셸이 종료되면 모두 초기화 → 다음 로그인 시에도 자동으로 적용하기 위해서는 배시 설정 파일을 수정해야 함

 

/etc/profile, ~/.profile, ~/.bashrc

- 로그인 셸로 기동 시: /etc/profile → ~/.profile → ~/.bashrc 읽음

- 비로그인 셸로 기동 시: ~/.bashrc 읽음

/etc/profile 시스템 전체에 적용되는 설정 파일, 모든 사용자에게 적용

~/.profile 사용자별 설정 파일, ~/.bashrc 실행하는 코드 포함, 로그인 시마다 읽힘

~/.bashrc 사용자별 배시 설정 파일, 배시 기동 시마다 읽힘

 

 


9장 퍼미션과 슈퍼 사용자

파일, 디렉터리 퍼미션 확인 

ls -l 명령어 실행 결과의 세번째 항목: 파일의 소유자(파일을 작성한 사용자), 네번째 항목: 파일의 소유 그룹 

 

그룹: 사용자들을 묶은 그룹

- 한 사용자는 여러 그룹에 소속 가능

- 어떤 사용자도 최소 한 그룹에는 소속

- 사용자 생성 시 소속 그룹 지정하지 않으면 사용자 이름과 동일한 그룹에 소속

groups 현재 로그인한 사용자가 소속된 그룹 확인 

 

파일 퍼미션 

첫번째 항목의 첫번째 글자: 파일의 타입

- 일반 파일

d 디렉터리

l 심볼릭 링크

첫번째 항목의 나머지 글자들: 파일 모드(퍼미션), 각 3글자씩 소유자, 소유 그룹, 그 외 사용자에 대한 퍼미션 의미

r 읽기 read

w 쓰기 write

x 실행 execute

rwxr-xr-- r, w, x 글자 표시는 해당 권한 있음, - 표시는 해당 권한 없음을 의미

 

디렉터리 퍼미션 

r 디렉터리 내 파일 목록 읽기 가능, ls 명령어 사용 가능

w 디렉터리 하위에 파일 및 디렉터리 생성 및 삭제 가능 ⇒ 파일을 지울 수 있는지 여부가 파일이 아닌 디렉터리 퍼미션에 의해 결정, touch, mkdir, rm, rmdir 명령어 등 사용 가능

x 디렉터리 안으로 이동 가능, cd 명령어 사용 가능

 

퍼미션 설정 

chmod [ugoa] [+-=] [rwx] <파일 이름> 파일이나 디렉터리의 퍼미션 설정 (해당 파일의 소유자 또는 슈퍼 사용자만 가능)

u 소유자

g 소유 그룹

o 기타 사용자

a ugo 모두 (사용자 지정하지 않을 때와 같음)

+ 퍼미션 추가

- 퍼미션 삭제

= 지정한 퍼미션으로 설정

⇒ 지정한 퍼미션 이외에는 변화X → 선택적으로 퍼미션 변경 

 

chmod <8진수의 수치> <파일 이름>

- 기존 퍼미션을 새로운 퍼미션으로 덮어씀

- 각 문자(rwx)에 해당하는 숫자를 더해서 퍼미션 지정 (r - 4, w - 2, x - 1)

chmod 755 file.txt #file.txt 퍼미션으로 rwxr-xr-x 설정

 

슈퍼 사용자 

- 슈퍼 사용자: 관리자 권한을 가지는 특별한 사용자(사용자 이름 root) 일반 사용자

su 일시적으로 다른 사용자로 전환 (로그아웃하지 않고 다른 사용자가 됨)

인자 없는 su 슈퍼 사용자로 전환, 프롬프트 $# 변경 (환경 변수나 현재 디렉터리는 일반 사용자 상태가 유지)

su - 슈퍼 사용자 환경으로 초기화하면서 슈퍼 사용자로 전환

exit 일반 사용자로 복귀

⇒ su, su - 명령어 실행 시 슈퍼 사용자의 암호 입력 필요

 

sudo 명령어를 다른 사용자가 되어 실행, 보통 일반 사용자로 로그인한 뒤 슈퍼 사용자로만 실행할 수 있는 하나의 명령어만을 실행하기 위해 사용 

sudo <명령어> 슈퍼 사용자로 해당 명령어 실행, 현재 로그인한 사용자의 암호 입력 필요 

sudo visudo /etc/sudoers 파일(sudo 명령어 사용 가능한 사용자 목록 관리하는 파일)을 안전하게 편집 (직접 텍스트 에디터로 편집하는 것은 위험) → 파일 저장 전 문법상 오류 체크

 

 


10장 프로세스와 잡 

프로세스

- 프로세스: 메모리 위에 올린 프로그램, 리눅스 커널에서 바라본 처리 단위

- 같은 프로그램을 실행하더라도 각 프로세스는 별도의 메모리 영역 have

- 프로세스를 실행한 사용자 외에는 해당 프로세스 조작 권한 제한

- 리눅스 커널은 각 프로세스에게 프로세스 ID(프로세스 종료 전까지 바뀌지 않음)라는 고유한 번호 할당해서 관리

- 새로운 프로세스(자식 프로세스)는 이미 기존에 존재하는 별도의 프로세스(부모 프로세스) 기반으로 생성

 

프로세스 확인 

ps 현재 시스템에서 실행 중인 프로세스 목록 출력, 옵션 없으면 현재 접속한 터미널에서 실행한 프로세스만 (PID: 프로세스 ID, CMD: 실행한 명령어, TTY: 터미널)

x 옵션 현재 실행 중인 모든 프로세스 목록 출력 (다른 터미널에서 실행 중인 프로세스 + 터미널과 무관하게 돌아가는 프로세스데몬(demon) 포함), ps 명령어를 실행한 사용자의 프로세스만을 출력

ux 옵션 ps 명령어를 실행한 사용자의 프로세스를 상세하게 출력

f 옵션 프로세스 간 부모 자식 관계 표시

a 옵션 사용자가 실행한 프로세스 외에도 시스템을 위해 동작 중인 프로세스(대부분 슈퍼 사용자 권한으로 실행) 목록 출력

ax 옵션 모든 사용자의 프로세스를 출력

aux 옵션 모든 사용자의 프로세스를 상세하게 출력

auxww 옵션 aux 옵션의 출력 결과가 화면에 잘리지 않도록 출력

 

잡 

- : 에서 바라본 처리 단위 

- 셸의 커맨드 라인에 입력한 한 행 = 잡 하나

- 복수의 명령어 파이프로 연결 시 프로세스명령어마다 생성, 하나만 생성

Ctrl + z 잡 일시 정지

jobs 현재 잡 목록 확인

jobs -l 프로세스 ID도 표시

 

잡의 상태 

- 포그라운드(foreground): 사용자의 입력을 받아들일 수 있는 잡의 상태

fg 잡을 포그라운드로 전환

fg %<잡 번호> 해당 잡을 포그라운드로 전환, 일시 정지된 잡을 포그라운드로 재개, %<잡 번호> 생략 시 현재 잡(jobs 명령어에서 +로 표시된 잡)이 포그라운드로 전환

 

- 백그라운드(background): 사용자가 조작할 수 없는 잡의 상태

bg 잡을 백그라운드로 전환

bg %<잡 번호> 해당 잡을 백그라운드로 전환, 일시 정지된 잡을 백그라운드로 재개, %<잡 번호> 생략 시 현재 잡(jobs 명령어에서 &로 표시된 잡)이 백그라운드로 전환

<명령어> & 처음부터 잡을 백그라운드로 실행

 

잡과 프로세스의 종료 

Ctrl + c 포그라운드로 실행 중인 잡 종료

kill %<잡 번호> 백그라운드로 실행 중인 잡 종료

kill <프로세스 ID> 프로세스 종료, 다른 사용자가 실행한 프로세스 함부로 종료 불가, 슈퍼 사용자는 모든 사용자의 프로세스 강제 종료 가능

 

kill 명령어

kill -<시그널 이름 or 시그널 고유 번호> 해당 시그널을 프로세스에게 전송 → 프로세스는 전달받은 시그널의 종류에 따라 종료, 정지, 재기동 등의 처리 수행, <시그널 이름> 지정하지 않으면 기본적으로 TERM이라는 시그널 전송

kill -l 시그널 전체 목록 확인 (시그널 이름 앞에 SIG라는 문자열 붙어 표시)

- TERM 시그널: 종료 시그널 terminate

- KILL 시그널: 프로세스가 아닌 리눅스 커널에 전달되어 처리, TERM 시그널을 받아도 종료되지 않는 상태에 빠진 프로세스를 강제 종료하기 위한 시그널 (정상적인 종료 로직 수행X)

 

 


11장 표준 입출력과 파이프라인 

표준 입출력 

- 표준 입력(stdin): 프로그램에 데이터를 입력하는 채널 ex. 키보드를 통한 입력

- 표준 출력(stdout): 프로그램의 실행 결과가 출력되는 채널, 기본값으로 단말 디스플레이에 출력

- 표준 에러 출력(stderr): 프로그램 실행 중 발생하는 에러 메시지가 출력되는 채널, 보통 표준 출력과 동일하게 단말 디스플레이에 출력

- 리눅스 명령어는 표준 입출력이 실제 어디에 연결되어 있는지 신경X단순히 표준 입력을 읽어서 결과를 표준 출력으로 출력할 뿐

 

리다이렉션(redirection): 표준 입출력을 어디로 연결할지 변경

표준 입력의 리다이렉션 <

cat < /etc/crontab #/etc/crontab 파일 내용이 표준 입력으로 cat 명령어에 전달

 

표준 출력의 리다이렉션 > 보통 명령어의 실행 결과를 화면에 출력하는 것이 아닌 파일에 저장하는 방식으로 사용

ls -l / > list.txt #ls -l / 명령어 실행 결과를 list.txt 파일에 저장

- 이미 존재하는 파일로 표준 출력을 리다이렉션하면 기존 파일을 지우고 덮어씀

>> 표준 출력 리다이렉션 시 덮어쓰지 않고 파일 끝에 append

set -o noclobber 리다이렉션으로 덮어쓸 때 에러 발생하도록 셸 옵션 활성화

 

표준 에러 출력의 리다이렉션 2>

ls /xxxxx 2> error.txt #ls /xxxxx 명령어 실행 중 발생한 에러를 error.txt 파일에 저장
ls /xxxxx > list.txt 2> error.txt #ls /xxxxx 명령어 실행 결과는 list.txt 파일에, 에러 메시지는 error.txt 파일에 저장

 

표준 출력과 표준 에러 출력을 함께 리다이렉션 2>&1 표준 출력과 표준 에러 출력을 파일 하나로 리다이렉션

list /xxxxx > result.txt 2>&1 #list /xxxxx 명령어 실행 결과와 에러 메시지 모두 result.txt 파일에 저장
#>를 통해 표준 출력을 result.txt 파일로 리다이렉션
#2>를 통해 표준 에러 출력을 &1(표준 출력)으로 리다이렉션

0 표준 입력

1 표준 출력

2 표준 에러 출력

 

/dev/null 특수 파일

- 입력 파일로 지정해도 아무 내용도 입력되지 않음

- 출력 파일로 지정해도 어떤 내용도 출력되지 않음

⇒ 굳이 출력되는 메시지를 확인하지 않아도 되거나 명령어의 실행 시간 확인할 때 /dev/null 파일로 리다이렉션

 

파이프라인: 명령어의 표준 출력 다른 명령어의 표준 입력으로 연결

파이프라인 <명령어1> | <명령어2> [ | <명령어3> ] …

ls -l / | less #ls 명령어 실행 결과의 표준 출력이 less 명령어의 표준 입력으로 전달
ls -l /etc | cat -n | less #ls 명령어의 결과에 cat 명령어로 행 번호를 붙이고 less 명령어로 한 페이지씩 출력
ls -l / /xxxxx 2>&1 | less #ls 명령어의 표준 출력과 표준 에러 출력을 less 명령어의 표준 입력으로 전달

 

필터 명령어: 표준 입력을 받아들여 표준 출력으로 출력하는 명령어 

head 파일 앞부분을 출력, 출력할 행 수 지정하지 않으면 기본적으로 첫 10행 출력

cat 입력 내용을 그대로 출력

tail 파일 뒷부분을 출력

grep 검색 패턴에 일치하는 행을 출력

sort 정렬하여 출력

uniq 중복된 행을 제거하여 출력

tac 역순으로 출력

wc 행 수, 단어 수, 바이트 수를 출력

du -b /bin/* | sort -n | tac | head -n 5 #/bin 디렉터리 안의 파일 크기가 큰 상위 5개 파일 목록 출력
du -b /bin/* #/bin 디렉터리 아래의 모든 파일 크기를 바이트 단위로 출력
sort -n 숫자를 기반으로 정렬

 

 


12장 텍스트 처리 

텍스트 처리 관련 명령어 

wc 입력 파일의 행 수, 단어 수, 바이트 수를 출력하는 명령어

-l 행 수만 출력

-w 단어 수만 출력

-c 바이트 수만 출력

ls / | wc -l - #루트 디렉터리 내 파일과 디렉터리 총 몇 개 있는지 확인
# wc 명령어가 표준 입력을 사용하도록 -를 통해 명시적으로 지정

 

sort 행 단위로 정렬하여 결과 출력, 아무 옵션 지정하지 않으면 알파벳순으로 정렬

-n 문자열을 숫자 값으로 인식하여 정렬하는 옵션

-r 역순으로 정렬하는 옵션

-u 중복 데이터를 한 번만 표시하는 옵션

ps x | sort -k 5 #ps 명령어 결과의 5번째 필드인 COMMAND 필드를 기준으로 정렬
ls -l /bin/* | sort -rn -k 5 #ls 명령어의 실행 결과를 파일 크기가 큰 순으로 정렬

 

uniq 연속된 중복 데이터를 하나만 출력하는 명령어, 같은 내용이 연속되어 있는 경우에만 중복 제거 

-c 중복된 데이터 개수 표시하는 옵션

sort file | uniq #파일 전체에서 중복 전부 제거
sort file | uniq -c | sort -rn #uniq -c 명령어의 실행 결과를 역순으로 정렬하여 중복이 많은 순으로 출력

 

cut -d <구분자> -f <필드 번호> [<파일 이름>] 입력의 일부를 추출하여 출력하는 명령어 

<구분자>로 지정한 문자를 기준으로 입력 데이터를 분할하여 그 중 <필드 번호>로 지정한 필드만 출력

<구분자> 지정하지 않으면 기본으로 탭 사용

- 주로 csv 파일의 특정 컬럼만 출력할 때 사용

cut -d : -f 7 /etc/passswd #/etc/passwd 파일의 로그인 셸 필드만을 출력
cut -d : -f 1,6,7 /etc/passwd #1번째 필드인 사용자 이름, 6번째 필드인 홈 디렉터리, 7번째 필드인 로그인 셸 출력

 

tr <치환 전 문자> <치환 후 문자> 문자를 치환하는 명령어 (문자 단위), 표준 입력만 받아들d파일 지정 불가 

cat /etc/passwd | tr abc ABC #/etc/passwd 파일의 a,b,c 각 문자를 A,B,C 각 문자로 치환
cat /etc/passwd | tr a-z A-Z #모든 소문자를 대문자로 치환

tr -d <삭제할 문자> 특정 문자 삭제

cat /etc/passwd | tr -d "\n" #개행문자 전부 지우고 한 행으로 출력

 

tail 파일의 마지막 부분을 출력하는 명령어, 옵션 지정하지 않으면 마지막 10행 출력

tail -n 1 /etc/passwd #/etc/passwd 파일의 마지막 한 행 출력

tail -f <파일 이름> 해당 파일에 내용이 추가될 때마다 실시간으로 추가된 내용을 출력하여 파일 모니터링 (주로 리눅스 운영 시 로그 파일을 실시간으로 모니터링하는 경우에 사용)

Ctrl + c 모니터링 상태 종료 

 

diff [옵션] <비교 파일1> <비교 파일2> 두 파일의 차이점을 출력하는 명령어

- 기본적으로 두 파일의 차이점만 표시O, 공통점은 표시X

- 헝크(hunk): 파일 내 각 변경 범위

- 패치(patch): 변경된 부분만 담은 파일, diff 명령어로 얻은 변경 사항을 patch 명령어로 적용

-u 통일 포맷으로 차이 출력 (Git에서 사용하는 포맷)

 

명령어 실행 결과 첫 번째 행 <변경 범위 1><변경 종류><변경 범위 2>

<범위 1>a<범위 2> 첫 번째 파일의 '범위 1' 뒤에 두 번째 파일의 '범위 2'의 내용이 추가 add

<범위 1>c<범위 2> 첫 번째 파일의 '범위 1' 부분이 두 번째 파일의 '범위 2'의 내용으로 변경 change

<범위 1>d<범위 2> 첫 번째 파일의 '범위 1' 부분이 삭제 delete

 

명령어 실행 결과 두 번째 행 이후는 실제 파일의 변경 내용 표시 

< 첫 번째 파일에만 있는 행, 지워진 행

> 두 번째 파일에만 있는 행, 추가된 행

 

 


13장 정규 표현식 

파일 내용 검색 명령어 

grep [옵션] <검색 패턴> <파일 이름> 해당 파일에서 검색 패턴에 일치하는 행 출력

-n 행 번호 출력

-i 대소문자 구별하지 않고 검색

-v 검색할 문자열이 나타나지 않는 행 출력

- 파일 지정하지 않으면 표준 입력을 읽음 ⇒ 다른 명령어의 실행 결과를 grep으로 검색하는 방식 자주 사용

grep bash /etc/passwd #/etc/passwd 파일에서 bash 문자열 검색
ls /etc | grep cron #/etc 디렉터리 내 파일 중 cron이라는 글자 포함하는 파일 검색

 

정규 표현식 

. 임의의 문자 하나

\(escape) 뒤에 오는 문자를 메타 문자로 인식하지 않도록 함

[] 괄호 안에 있는 문자 중 하나

[^] 괄호 안에 있는 문자 이외의 문자 하나

grep 't.st' example.txt #t-로 시작하고 -st로 끝나는 4글자 단어 검색
grep 't[ef]st' example.txt #test 또는 tfst 검색
grep 'mail[^13]' example.txt #mail-로 시작하는 5글자 단어 중 mail1, mail3는 제외하고 검색

 

^ 문자열의 시작 위치

$ 문자열의 마지막 위치

grep '^net' example.txt #net으로 시작하는 행 검색
grep 'net$' example.txt #net으로 끝나는 행 검색

 

* 직전 문자 0회 이상 반복 (해당 문자가 나타나지 않는 것도 포함)

.* 임의의 문자가 0회 이상 반복, 모든 문자열 의미

grep '^B[ea]*r$' drink.txt #Br, Beer, Baar, Bear, Beear 등 검색

 

확장 정규 표현식

- 사용할 수 있는 메타 문자가 확장

grep -E 지정한 정규 표현식을 확장 정규 표현식으로 해석

grep -E 'Be+r' drink.txt
grep 'Be\+r' drink.txt #위와 동일

 

+ 직전 문자 1회 이상 반복

? 직전 문자 0회 또는 1회

grep -E 'Be+r' drink.txt #Ber, Beer, Beeer 등 검색
grep -E 'Wine ?Wine' drink.txt #WineWine, Wine Wine 검색

 

{m,n} m회 이상 n회 이하 반복

{m} m회 반복

{m,} m회 이상 반복

grep -E 'Be{1,2}r' drink.txt #Ber, Beer 검색
grep -E 'Be{2}r' drink.txt #Beer 검색
grep -E 'Be{4,}r' drink.txt #Beeeer, Beeeeer, Beeeeeer 등 검색

 

() 정규 표현식을 그룹화

| 복수의 정규 표현식을 OR 조건으로 연결

grep -E '(Wine){2,}' drink.txt #Wine이라는 단어 2회 이상 반복되는 패턴 검색
grep -E 'My (Vodka|Wine)' drink.txt #My Vodka 또는 My Wine 단어 검색

 

 


14장 고도의 텍스트 처리 

텍스트 편집 명령어 

sed [옵션] <스크립트> <대상 파일 이름> 필터 명령어로 비대화형 에디터 

- 대화형 에디터: 파일을 열어 메모리상에서 편집하고 적절한 시점에 저장하는 형태로 파일 편집

- 비대화형 에디터: 셸에서 편집 내용을 인자로 지정하여 sed 명령어 실행 → sed가 편집 수행 → 편집 완료된 내용을 표준 출력으로 출력 (원래 파일 내용은 바뀌지 않음)

<스크립트> 주소명령어를 조합한 문자열, 주소 지정하지 않으면 입력으로 들어오는 모든 행에 대해 명령어 실행

 

행 삭제

d 행을 삭제하는 명령어

n,m n행에서 m행까지의 주소 지정

$ 마지막 행

- 주소에 정규 표현식 사용 가능, 정규 표현식은 /로 감쌈

sed 1d drink.txt #첫 번째 행 삭제
sed 2,5d drink.txt #2행에서 5행까지 삭제
sed '3,$d' drink.txt #3행에서 마지막 행까지 삭제
sed d drink.txt #모든 행 삭제
sed /^B/d drink.txt #B로 시작하는 행 삭제

 

행 출력

- sed는 한 행 읽으면 먼저 패턴 스페이스라는 장소에 복사 → 편집 명령어 실행 → 패턴 스페이스 내용 출력

p 행을 출력하는 명령어

-n 패턴 스페이스의 내용 출력하지 않음, -n 옵션과 p 명령어 함께 사용하면 특정 행만 출력 가능

sed 1p drink.txt #첫 번째 행 출력(1p 스크립트에 의해 출력) + 전체 행 출력(패턴 스페이스 내용 출력)
sed -n 1p drink.txt #첫 번째 행만을 출력

 

행 치환 

sed 's/치환 전 문자열/치환 후 문자열/옵션' <대상 파일 이름>

s 행을 치환하는 명령어, 옵션 생략 가능, 기본적으로 각 행에서 처음 발견된 문자열 1개만 치환

g 옵션 발견된 모든 문자열을 치환

sed 's/Beer/Whisky/g' drink.txt #모든 Beer를 Whisky로 치환
sed 's/B.*r/Whisky/g' drink.txt #B로 시작하고 r로 끝나는 문자열을 Whisky로 치환
sed -n 's/!//gp' drink.txt #패턴 스페이스를 출력하지 않는 -n 옵션과 치환이 발생한 경우에만 출력하는 p 옵션 지정하여 치환이 발생한 행만 출력

-E, -r sed에서 확장 정규 표현식 사용

sed -E 's/Be+r/Whisky/' drink.txt #확장 정규 표현식
sed -r 's/Be+r/Whisky/' drink.txt #확장 정규 표현식
sed 's/Be\+r/Whisky/' drink.txt #기본 정규 표현식, -E 또는 -r 옵션 필요X

 

후방 참조

- 검색된 문자열의 일부만을 치환하고 싶은 경우에 사용

()로 그룹화하여 \1 같이 참조

sed -r 's/My (.*)/--\1--/' drink.txt #해당 그룹 문자열을 '--그룹 문자열--'로 치환

 

주소 지정 

주소를 지정하여 치환할 행 한정 

sed '1,3s/Beer/Whisky/g' drink.txt #1행 ~ 3행 사이 문자열 중 Beer를 Whisky로 치환

 

구분자 변경 

- 치환할 문자열 안에서 / 문자 사용 시 \(escape)를 앞에 붙임

- s 명령어 바로 뒤에 나오는 문자를 구분자로 사용 ⇒ s 뒤에 /가 아닌 다른 문자 지정 시 해당 문자가 구분자로 사용
- 보통 구분자로 /, !, % 사용 

sed 's/Beer/\/Beer\//g' drink.txt #Beer를 /Beer/로 치환
sed 's!Beer!/Beer/!g' drink.txt #위와 동일

 

awk <스크립트> <대상 파일 이름>

- 텍스트 검색, 추출, 가공과 같은 편집 작업을 위한 명령어

- 대상 파일 지정하지 않으면 표준 입력을 읽음

- 입력 텍스트를 한 행씩 읽어 지정한 처리 수행

<스크립트> 패턴, 액션으로 구성 패턴 { 액션 }

- 패턴: 액션을 실행할지 여부를 결정하는 조건, 대상 텍스트의 행마다 조건 부합 여부 확인 (텍스트 한 행 = 레코드), 패턴 생략 시 모든 레코드에 대해 액션 실행

- 액션: 텍스트 추출, 치환, 삭제 등의 처리

awk '{print $2, $3}' score.txt #모든 행의 두 번째, 세 번째 필드만 출력
awk '$1 ~/^s/ {print NR, $0}' score.txt #첫 번째 필드가 s로 시작하는 레코드만 추출하여 행 번호와 함께 출력

 

print와 필드 변수

print 문자열을 출력하는 액션

NF 변수 레코드의 필드 개수

$NF 레코드의 마지막 필드

- awk는 각 레코드를 공백이나 을 구분자로, 필드로 자동 분할하여 각각 $1, $2, $3 … 변수에 대입, 레코드 전체는 $0에 대입 (공백 여러 개도 공백 하나로 간주)

- print 시 변수 여러 개를 쉼표로 구분하여 지정하면 각 값 사이에 공백 표시, 쉼표 대신 공백으로 구분하여 지정하면 각 값 사이에 공백 표시되지 않음

ls -l /usr/bin | awk '{print $(NF-1),$NF}' #ls 명령어 실행 결과의 모든 행의 마지막에서 첫 번째, 두 번째 필드 출력

 

패턴 지정

- 정규 표현식은 /로 감싸야 함

- 정규 표현식 확인할 필드 지정 위해 ~(틸드) 사용

- 정규 표현식 확인할 필드 지정하지 않으면 레코드 전체가 확인 대상

awk '$9 ~/^cp/ {print $5,$9}' #9번째 필드가 cp로 시작하는 레코드만 추출하여 5번째, 9번째 필드 출력 
ls -l /usr/bin | awk '/^l/ {print $5,$9}' #심볼릭 링크의 5번째, 9번째 필드 출력

 

액션 생략

- 액션 생략 시 단순히 레코드 전체 출력 즉 {print $0} 실행, 또한 print 액션 인자 지정하지 않아도 레코드 전체 출력

awk '$9 ~/^cp/' 
awk '$9 ~/^cp/ {print}'
awk '$9 ~/^cp/ {print $0}'
#위 3개 모두 동일 

 

예시 

-F 필드 구분자 지정

-f 파일로 저장된 awk 스크립트 실행

END 패턴 END 안에 있는 액션은 모든 입력 파일에 대한 처리 끝낸 뒤 마지막에 한 번 실행

NR 변수 지금까지 읽은 레코드 수

awk -F , '{sum += $NF} END{print "Average:",sum/NR}' score.csv
awk -F , -f average.awk score.csv

 

#average.awk 파일 
{sum += $NF} END{print "Average:",sum/NR} 

 

 


15장 셸 스크립트 작성 

셸 스크립트: 셸에서 실행될 커맨드 라인을 입력해 놓은 파일

 

셸 스크립트 작성

#!/bin/bash 셔뱅(shebang)

chmod +x homesize.sh로 실행 권한 부여 → ./homesize.sh로 셸 스크립트 실행

#!/bin/bash 

#du 디렉터리 내 파일 사용량 출력하는 명령어
du -h ~ | tail -n 1 #홈 디렉터리만 파일 사용량 출력 (기본적으로 서브 디렉터리 사용량도 출력)

 

셔뱅

- 셸의 실행 명령을 전달받은 리눅스 커널은 먼저 파일의 첫 부분 확인 → #!가 있으면 그 뒤 명령어 실행

- #!/bin/bash 해당 셸 스크립트는 /bin/bash를 사용한다고 명시적으로 선언한 것

- 리눅스 커널에 의해 ./homesize.sh/bin/bash ./homesize.sh로 실행 확장 ⇒ 현재 사용 중인 셸이 배시가 아니어도 자동으로 /bin/bash가 해당 스크립트를 실행

 

source 파일에서 명령어를 읽어서 실행

- 지정한 파일 안의 커맨드 라인을 마치 셸에 직접 입력한 것과 동일하게 실행

- 셔뱅으로 지정한 셸이 아닌 항상 현재 셸이 사용

- 파일을 직접 실행하는 것이 아니기 때문에 파일에 실행 권한 부여할 필요X

- 배시에서는 . 명령어가 source 명령어와 완전히 동일하게 동작

source ./homesize-noshebang.sh #셔뱅을 사용하지 않은 셸 스크립트 실행
. ./homesize-noshebang.sh #위와 동일 

 

셸 스크립트를 실행하는 3가지 방법

1. 파일 이름만으로 실행 ./homesize.sh

2. 셸의 인자로 지정하여 실행 bash ./homesize-noshebang.sh

서브 셸(현재 셸에서 새롭게 실행된 자식 프로세스로서의 셸)에서 실행

3. source 명령어를 사용하여 실행 source ./homesize-noshebang.sh현재 설정된 셸 환경에 영향을 받거나 줌 ex. 현재 셸에 설정한 별명 셸 스크립트 내에서도 사용 가능

 

셸 스크립트 배치

- 검색 경로: 셸에서 명령어 실행 시 명령어의 파일을 찾는 디렉터리, 환경 변수 PATH에 설정

- 검색 경로에 등록된 디렉터리에 있지 않는 이상 셸 스크립트를 이름만으로 실행 불가 ⇒ 상대 경로나 절대 경로로 파일 위치 지정

- 해당 셸 스크립트를 ~/bin 디렉터리로 옮김 → 검색 경로에 ~/bin 추가하기 위해 ~/.profile 파일 내에 PATH="$PATH:~/bin" 추가 ⇒ 어떤 디렉터리에서도 해당 셸 스크립트 이름만으로 실행 가능

shopt -u sourcepath source 명령어가 PATH에 지정된 디렉터리에서 파일 찾지 않도록 셸 설정 비활성화

 

 


16장 셸 스크립트의 기초 지식 

셸 스크립트의 기본

- 여러 명령어를 ;로 연결하면 한 행으로 입력 가능 echo "Hello World";cd /;ls -l

- 셸 스크립트에서 빈 행은 무시

- 행 끝에 \ 입력하면 여러 행에 걸쳐 입력 가능

#!/bin/bash 

echo \ 
    "Hello World"

# 주석 표시

 

변수

변수명=값 셸 변수에 값 대입

= 양옆에 공백 불가

- 변수값 참조하려면 변수명 앞에 $ 붙여야 함

- 변수명에 알파벳, 숫자, 언더스코어(_)만 사용 가능, 숫자는 첫 글자로 사용 불가

 

쿼팅

- 배시에서는 공백을 기준으로 명령어 인자 구분

- 작은따옴표나 큰따옴표로 감싸면 감싸준 문자열 안에 공백 있어도 한 단어로 인식

- 작은따옴표 안의 $는 특별한 의미 가지지 않는 일반 문자로 취급

- 큰따옴표 안에서는 $로 시작하는 변수가 값으로 치환

#!/bin/bash

country=Korea
echo 'I came from $country' #I came from $country 출력 
echo "I came from \$country" #I came from $country 출력 
echo "I came from $country" #I came from Korea 출력

 

명령어 치환

$(명령어) 해당 명령어 실행하고 출력된 결과 취득

- 명령어 치환 큰따옴표 안에서도 사용 가능 echo "Today is $(date '+%Y-%m-%d')."

- 백쿼트(`)로도 명령어 치환 사용 가능 echo "Today is `date '+%Y-%m-%d'`."

#!/bin/bash 

filename=$(date '+%Y-%m-%d') 
touch "$filename" #이름이 현재 날짜인 파일 생성

 

위치 파라미터

- 셸 스크립트에서 위치 파라미터라는 셸 변수로 전달받은 인자 처리 가능 ex. ./parameters.sh aaa bbb ccc

- 위치 파라미터 $1, $2, $3… 셸 스크립트 실행 시 지정한 인자 각각이 할당

$0 셸 스크립트 파일 이름 할당, 위치 파라미터가 아닌 특수 파라미터

$# 스크립트에 전달된 인자 개수 의미하는 특수 파라미터

$@, $* 인자를 분할하지 않은 채 전체 참조

$@ 인자 개수가 N이면 각 위치 파라미터가 N개의 문자열로 전개

$* 하나의 문자열로 전개

 

if 문: 주어진 조건을 평가하여 참인지 거짓인지에 따라 처리를 분기하는 제어 구조

#!/bin/bash

if [ "$1" = "bin" ]; then
	echo "OK"
else 
	echo "NG"
fi

- 조건식에 이어 세미콜론(;) 필수, then다음 행에 기재하면 세미콜론 생략 가능, [, ] 전후에 공백 필수

- if 뒤에 오는 것은 조건식이 아닌 명령어, if 뒤에 오는 명령어 결과가 참일 때 아래 명령어 실행

[ 배시의 내장 명령어, 뒤에 이어지는 "$1", =, "bin", ] 모두 [ 명령어의 인자로 전달

test [ 명령어와 유사한 기능, 마지막 인자로 ] 지정하지 않아도 됨

 

명령어의 종료 상태

- 모든 명령어는 종료 상태라 부르는 정수값 반환

$? 직전에 실행한 명령어의 종료 상태 의미하는 셸 변수, 일반적으로 명령어 정상 종료0, 에러 발생0 이외의 값 반환

[ 인자로 전달된 조건식을 판정하여 참이면 0, 그 외에는 0이 아닌 종료 상태 반환 → if 문은 지정된 명령어 실행 후 종료 상태가 0이면 참, 그 외에는 거짓으로 판단

#!/bin/bash 

#grep 지정한 패턴이 검색된 경우에만 종료 상태 0 반환, -q 옵션으로 검색 결과 출력X
if grep -q 'bash' /etc/passwd; then 
    echo 'bash found' 
fi

 

문자열 비교 연산자

str1 = str2 str1과 str2가 같음

str1 != str2 str1과 str2가 같지 않음

-n str1 str1이 빈 문자열이 아님

-z str1 str1이 빈 문자열임

 

정수 비교 연산자 (only 정수)

int1 -eq int2 int1과 int2가 같음

int1 -ne int2 int1과 int2가 같지 않음

int1 -lt int2 int1이 int2보다 작음

int1 -le int2 int1이 int2보다 작거나 같음

int1 -gt int2 int1이 int2보다 큼

int1 -ge int2 int1이 int2보다 크거나 같음

 

파일 속성 연산자

-e file file 존재함

-d file file 존재하며 디렉터리임

-h file file 존재하며 심볼릭 링크임

-L file file 존재하며 심볼릭 링크임 (-h와 동일)

-f file file 존재하며 일반 파일임

-r file file 존재하며 읽기 권한 부여됨

-w file file 존재하며 쓰기 권한 부여됨

-x file file 존재하며 실행 권한 부여됨

file1 -nt file2 file1 변경 시각이 file2보다 최근임

file1 -ot file2 file1 변경 시각이 file2보다 오래됨

 

연산자 결합

조건식1 -a 조건식2 조건식1과 조건식2가 모두 참이면 참 AND

조건식1 -o 조건식2 조건식1과 조건식2 중 하나라도 참이면 참 OR

! 조건식 조건식의 진위값을 반대로 함 NOT

() 조건식 그룹화

명령어1 && 명령어2 명령어1이 정상 종료하여 0이 반환된 경우에만 명령어2 실행

명령어1 || 명령어2 명령어1의 종료 상태가 0이 아닌 경우에만 명령어2 실행

 

셸 스크립트의 종료 상태 

- 셸 스크립트의 종료 상태 = 셸 스크립트 중 마지막으로 실행한 명령어의 종료 상태

exit <종료 상태> 명시적으로 종료 상태 지정, <종료 상태> 인자 없으면 셸 스크립트에서 마지막으로 실행한 명령어의 종료 상태 반환

 

for 문: 단어 리스트에 대해 반복 처리 수행

#!/bin/bash 

for name in aaa bbb ccc 
do 
    echo $name 
done

 

seq <시작 숫자> <마지막 숫자>

#!/bin/bash 

for i in $(seq 1 5) #명령어 치환 
do 
    touch "000${i}.txt" 
done

 

커맨드 라인 인자와 for

#!/bin/bash 

for parameter in "$@" #"$*"은 하나의 문자열로 불가 
do 
    echo "$parameter" 
done 

#위와 동일 
for parameter 
do 
    echo "$parameter" 
done

 

case 문: 지정한 문자열의 패턴에 따라 분기할 수 있는 제어 구조

case <문자열> in
    <패턴1>)
        처리1
        ;;
    <패턴2>)
        처리2
        ;;
esac

 

#!/bin/bash

case "$1" in
    start | stop)
        echo "OK"
        ;;
    *) #나머지 모든 경우
        echo "NG"
        ;;
esac

 

while 문: 지정한 조건이 참일 동안에만 반복하여 처리를 실행하는 제어 구문

#!/bin/bash

i=1
while [ "$i" -le 10 ] 
do 
    echo "$i" 
    i=$((i + 2))
done

 

산술 연산자

- sh 기반 셸 스크립트에서는 expr 외부 명령어를 사용하여 산술 연산 실행 i=`expr $i + 2` ⇒ 매번 외부 명령어를 호출하기 때문에 처리 속도가 느림

- bash 기반 셸 스크립트에서는 $(())를 사용하여 산술 연산 실행, 셸 변수에 추가로 $ 붙이지 않아도 됨

i=10 
echo $((i + 1)) #i에 1 더하기 
echo $((i / 2)) #i를 2로 나누기 
echo $((i * 3)) #i에 3 곱하기 
echo $((i ** 2)) #i의 2제곱

 

셸 함수

function <함수 이름> () { 처리 }

function이나 () 중 하나 생략 가능 (보통 function 생략)

- 셸 함수는 반드시 호출하기 전에 정의

- 셸 함수 안에서의 위치 파라미터 $1, $2, $3…에는 함수의 인자 값이 대입

- $0 함수 이름이 아닌 셸 스크립트 이름이 대입 (특수 파라미터)

#!/bin/bash 

print_parameters () 
{ 
    echo "\$1 = $1" 
    echo "\$2 = $2" 
    echo "\$3 = $3" 
    echo "\$4 = $4" 
    echo echo "$# arguments" 
    echo "script name = $0" 
} 

print_parameters aaa bbb ccc #셸 함수에 인자 지정하여 실행

 

셸 함수의 종료 상태 

- 셸 함수의 종료 상태 = 보통 셸 함수 안에서 마지막으로 실행한 명령어의 종료 상태

return <종료 상태> 명시적으로 셸 함수의 종료 상태 값 반환

#!/bin/bash 

checkparam () 
{ 
    if [ -z "$1" ]; then 
        return 1 
    fi 
    
    ls "$1" 
} 

checkparam

 

 


17장 셸 스크립트 활용하기 

셸 함수에서의 변수 유효 범위

local <셸 변수 이름> 해당 셸 변수를 로컬 변수로 선언

- 글로벌 변수: 스크립트 파일 전체에서 유효한 변수

- 로컬 변수: 함수 내에서만 유효한 변수

 

셸의 파라미터 확장

${변수명#패턴} 전방 최단 매치로 패턴에 일치하는 부분 제거

${변수명##패턴} 전방 최장 매치로 패턴에 일치하는 부분 제거

${변수명%패턴} 후방 최단 매치로 패턴에 일치하는 부분 제거

${변수명%%패턴} 후방 최장 매치로 패턴에 일치하는 부분 제거

$ filepath=/home/ubuntu/scripts/diary.sh
$ echo "${filepath##*/}"
diary.sh 
#filepath 변수에서 패턴에 일치하는 문자열 중 가장 긴 문자열 제거
#최단 매치 문자열: /
#최장 매치 문자열: /home/ubuntu/scripts/

 

IFS: 내부 필드 구분 문자 (Internal Field Separater)

- 환경 변수 IFS: 단어 구분 시 사용될 문자 저장, 기본값은 공백, , 개행

- 배시에서 커맨드 라인 인자나 for 문 요소 다룰 때 IFS 변수에 저장된 문자 기준으로 단어 구분

- 파일 이름에 공백 있는 경우(ex. space file.txt) 요소 2개로 취급

#IFS 값에서 일시적으로 공백 제거

_IFS=$IFS #IFS 값 백업 
IFS=$'\n' #IFS에 개행만 설정 

for fname in $(ls "$filepath")
...

IFS=$_IFS #IFS 값 복원

 

- 문자 코드 출력하는 od 명령어에 문자 이름 출력하는 -a 옵션으로 IFS에 설정된 값 확인

$ echo -n "$IFS" | od -a #-n 개행 출력되지 않음
0000000 sp ht nl
#sp: 공백, ht: 탭, nl: 개행

 

xargs: 표준 입력으로부터 커맨드 라인을 만들어 실행

xargs <실행하고 싶은 명령어> 표준 입력으로 인자의 리스트를 받음

<실행하고 싶은 명령어>가 표준 입력으로 전달받은 리스트를 인자로 하여 실행

find . -type f -name '*.txt' | xargs ls -l #find 명령어로 출력된 파일에 대해 ls 명령어로 상세 정보 확인 
find . -type f | xargs grep -nH hello #현재 디렉터리 아래의 모든 파일에서 hello라는 문자열 검색 (검색 결과에 검색된 파일 이름, 검색된 행 번호, 검색된 행 전체 포함)

 

 


18장 아카이브와 압축 

- 아카이브: 여러 개의 파일이나 디렉터리를 모아서 하나의 파일로 만드는 것

- 압축: 파일 크기를 작게 만드는 것

 

tar: 파일 아카이브하기

{<시작 숫자>..<끝 숫자>} 배시의 괄호 확장

touch dir/file-{1..5}.txt #touch dir/file-1.txt dir/file-2.txt dir/file-3.txt dir/file-4.txt dir/file-5.txt로 확장되어 실행 
echo {a..e}.txt #echo a.txt b.txt c.txt d.txt e.txt로 확장되어 실행 
echo sample.{txt,log,dat} #echo sample.txt sample.log sample.dat로 확장되어 실행

 

tar cf <아카이브 파일 이름> <아카이브로 묶을 파일 경로>

c 새로운 아카이브 파일 생성 create

f 새롭게 만들 아카이브 파일 이름 지정 file

tar cf dir.tar dir #dir 디렉터리와 그 안의 파일이 dir.tar라는 아카이브 파일로 묶임

 

tar tf <아카이브 파일 이름>

t 해당 아카이브 파일 안에 포함된 파일 목록 출력 list

 

tar xf <아카이브 파일 이름>

x 아카이브 파일에 묶인 파일, 디렉터리를 원래대로 복원 extract, 아카이브가 해제되는 곳에 동일한 이름의 파일 있으면 덮어씀

v 아카이브 대상 파일 목록 출력

tar cvf dir.tar dir #아카이브 파일 생성 시 대상 파일 목록 출력 
tar tvf dir.tar #아카이브 파일의 상세 정보 출력 (파일 이름, 권한, 소유자 등)
tar xvf dir.tar #아카이브 파일 해제 시 파일 내 목록 출력 
#아카이브 파일 생성 또는 해제 시 에러 메시지 확인을 위해 t 옵션에서만 v 옵션 사용 권장 

 

gzip: 파일 압축하기

gzip <압축할 파일 이름>

- 압축된 파일 이름은 원본 파일 이름 뒤에 .gz가 붙은 형태, 원본 파일 자동 삭제

-d 압축 파일 해제, 압축 파일 자동 삭제

gunzip 압축 파일 해제, 셸 스크립트로 내부적으로 gzip -d 실행

-c 압축 결과를 바이너리 형태로 표준 출력에 출력 → 해당 표준 출력 리다이렉션하여 임의의 이름의 압축 파일 생성 가능

gzip -d ps.txt.gz #압축 파일 해제 
gunzip ps.txt.gz #위와 동일 
gzip -c ps.txt > ps_test.txt.gz #ps_test.txt.gz라는 이름의 압축 파일 생성

 

tar와 gzip 조합하기

- tar로 아카이브하고 gzip으로 압축한 파일은 .tar.gz.tgz 확장자

tar 명령어의 z 옵션 tar에서 gzip으로 압축 

tar czf dir.tar.gz dir #아카이브 후 압축 수행 
tar xzf dir.tar.gz #tar + gz 파일 복원

 

파이프라인과 리다이렉션으로 tar + gz 파일 작성하기

tar cf - dir | gzip -c > dir.tar.gz #tar + gz 파일 생성
#아카이브 파일이 표준 출력으로 출력
#gzip 파일 지정하지 않으면 표준 입력 읽음

gzip -d -c dir.tar.gz | tar xf - #.tar.gz 파일 복원
#압축 해제한 결과를 -c 옵션과 파이프라인을 통해 tar 명령어에 전달
#tar 명령어의 x 옵션은 지정한 파일이 -이면 표준 입력을 읽음

 

bzip2: 파일 압축하기

bzip2 <압축할 파일 이름>

- gzip 보다 압축률 높음 → 압축 및 해제 시간 더 걸림

- bzip2로 압축한 파일은 .bz2 확장자

- gzip과 동일한 옵션으로 동작

bzip2 ps.txt #파일 압축
bzip2 -d ps.txt.bz2 #파일 압축 해제 
bunzip2 ps.txt.bz2 #파일 압축 해제 
bzip2 -c ps.txt > ps_test.txt.bz2 #압축 결과 표준 출력에 출력 

 

tar와 bzip2 조합하기

tar 명령어의 j 옵션 tar에서 bzip2로 압축

tar cjf dir.tar.bz2 dir #tar + bz2 파일 생성 

 

그 외 압축 형식

xz bz2 보다 압축률 더 좋음

tar 명령어의 J 옵션 tar에서 xz로 압축

tar cJf dir.tar.xz dir #tar + xz 파일 생성

 

zip: 파일 아카이브와 압축하기

zip -r <압축 결과의 파일 이름> <압축 대상의 경로> 아카이브, 압축 동시에 수행하는 명령어 (별도의 설치 필요)

-r 지정한 디렉터리 아래의 모든 파일 포함하는 옵션, 해당 옵션 지정하지 않으면 디렉터리만 대상이 되어 그 안의 파일은 포함X, 보통 zip 파일 만들 때는 항상 -r 옵션 지정

zip -r dir.zip dir

zipinfo 압축된 zip 파일 확인

unzip 압축된 zip 파일 복원

-q zip, unzip 명령어는 기본적으로 압축, 해제 수행 시 대상이 되는 파일 목록 출력, 파일 목록 출력하지 않는 옵션

-e 암호를 지정하여 zip 파일 생성 (해당 zip 파일 해제 시 암호 입력 필요)

 

 

 

와우 끝.

 

 

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/09   »
1 2 3 4 5 6 7
8 9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27 28
29 30
글 보관함