Skip to content

Instantly share code, notes, and snippets.

@bakyeono
Last active November 8, 2019 00:07
Show Gist options
  • Save bakyeono/868a6278360e1c4f503c to your computer and use it in GitHub Desktop.
Save bakyeono/868a6278360e1c4f503c to your computer and use it in GitHub Desktop.

리눅스 쉘 학습 노트

리눅스 쉘 학습하면서 남긴 노트다.

《리눅스 커맨드라인 완벽 입문서》 (BJ퍼블릭)로 학습했기 때문에 주로 >이 책에 나오는 내용이 많다. 명령어를 참고하기 위한 용도로 남긴 노트이므로 설명은 대부분 생략했다.

쉘을 학습하려는 분은 책을 한 번 읽어보는 것이 좋을 것이다. 이 책에는 쉘에 관한 설명 뿐 아니라 리눅스 와 해커들의 역사, 쉘에서 유의해야 할 점(압축을 두 번 세 번 씩 하지 말라거나) 등 흥미로운 읽을 거리도 많다. 쉘 입문용으로 매우 좋은 책인 듯하다.

주요 경로

경로 설명
/ 루트
/bin 시스템 부팅, 실행 바이너리
/boot 리눅스 커널, 시작 RAM 디스크 이미지, 부트로더
/dev 커널이 인식하는 모든 디바이스 노드
/etc 시스템 전반의 환경설정 파일
/etc/crontab 자동 실행 업무(job) 정의 파일
/etc/fstab 저장장치 테이블과 마운트 정보
/etc/passwd 사용자 계정 정보
/etc/shadow 사용자 비밀번호 정보
/etc/group 사용자 그룹 정보
/home 사용자 홈 디렉토리
/lib 시스템 프로그램이 사용하는 공유 라이브러리
/lost+found 파일시스템에 문제가 생겼을 때 파일이 복구되는 위치
/media CD-ROM, USB 저장장치 등 휴대용 장치 (자동) 마운트 포인트
/mnt 구식 리눅스 시스템의 휴대용 장치 (수동) 마운트 포인트
/opt (상업용) 추가 소프트웨어 설치 위치
/proc 커널 정보를 담은 가상 파일 시스템
/proc/cpuinfo cpu 정보
/proc/pid pid에 해당하는 프로세스의 정보
/root 루트 계정의 홈 디렉토리
/sbin 슈퍼유저의 시스템 작업을 위한 시스템 바이너리 파일
/tmp 임시 저장용 디렉토리
/usr 일반 사용자가 사용하는 모든 프로그램과 지원 파일
/usr/bin 리눅스 배포판이 설치한 실행 프로그램들
/usr/lib /usr/bin을 위한 공유 라이브러리
/usr/local 시스템 전반에 걸쳐 사용되는 프로그램, 주로 직접 컴파일한 프로그램
/usr/sbin 시스템 관리 프로그램
/usr/share /usr/bin의 공유 데이터 저장, 디폴트 설정 파일, 리소스 파일 등
/usr/share/dict/words 사전
/usr/share/doc 패키지 문서 파일
/var 가변 데이터. 데이터베이스, 스풀 파일, 사용자 메일, 로그 파일 등
/var/log 시스템 활동 기록하는 로그 파일
/var/log/auth.log 로그인 기록

명령

도움말

  • 명령어 찾기: whereis
  • 명령어 목록: apropos
  • 명령어 도움말: help
  • 명령어 메뉴얼: man
  • 명령어 정보 보기: info
  • 명령어 간단 설명: whatis
  • 명령어 전체경로 표시: which
  • 명령어 종류 확인: type
  • 핵심 유틸리티 안내: info coreutils

명령어의 종류

  1. 실행 프로그램 (binary or script)
  2. 쉘 내장 명령어
  3. 쉘 함수
  4. 별칭 (alias)
  • type: 명령어 종류 확인

man 페이지

man section search-term

  1. 사용자 명령어
  2. 커널 시스템 콜 API
  3. C 라이브러리 API
  4. 장치 노드 및 드라이버와 같은 특수 파일
  5. 파일 포맷
  6. 스크린세이버, 게임, 미디어 파일
  7. 그 외
  8. 시스템 관리용 명령어

apropos - man 페이지 목록 검색

명령어 찾기에 사용

info - 프로그램 정보 표시

GNU 프로젝트에서 제공하는, man 페이지의 대안. 하이퍼링크 지원.

alias

  • alias
  • which

파일 시스템

하드 링크와 아이노드(inode)

파일을 생성할 할 때,

  • 데이터 영역 (inode로 가리킴?)
  • 이름 영역

을 나누어 생성한다.

각 하드 링크는 파일 내용을 담은 각각의 아이노드를 참조한다.

심볼릭 링크

ln -s src dst

  • src는 dst의 위치를 기준으로 해야 함.
  • src는 절대 경로이어도 됨.
  • 디렉토리도 참조 가능. (하드 링크는 불가능)

쉘 사용

쉘 확장

종류 설명
경로명 확장 * 경로내 파일명들로 확장
틸드 확장 ~ 사용자 홈 디렉토리로 확장
산술 확장 $((expression)) 연산 결과로 치환
중괄호 확장 pre{opt1,opt2,...}post 텍스트 조합
중괄호 확장 pre{range1..range2}post 텍스트 조합(범위)
매개변수 확장 $var 변수를 평가
명령어 치환 $(command) 명령어를 실행한 출력 결과로 치환
명령어 치환 `command` 명령어를 실행한 출력 결과로 치환
쌍 따옴표 "command line" $, \, ` 기호를 제외한 인용
따옴표 'command line' 전체 인용
이스케이프 "\n"

히스토리

  • 자동 완성: tab
  • history: 히스토리 목록
  • !n: n번 히스토리로 치환
  • C-R: 히스토리에서 역순 증분 검색
  • C-J: 증분 검색중 선택
  • C-G: 증분 검색 종료

.gz 파일 보기

  • less 대신 zless를 사용.

권한

사용자 / 그룹

  • adduser: 사용자 계정 생성 (대화식)
  • useradd: 사용자 계정 생성
  • usermod: 사용자 계정 정보 변경
  • addgroup: 사용자 그룹 변경 (대화식)
  • groupadd: 사용자 그룹 변경
  • passwd: 사용자 비밀번호 변경

예)

  • usermod -a -G www-data user-a: 사용자 user-a를 그룹 www-data에 추가
  • TODO

권한

  • chown: 파일/디렉토리 소유자 변경
  • chmod: 파일/디렉토리 권한 변경

프로세스

프로세스 정보

  • ps: 실행 중인 프로세스 정보
  • ps -ef: 실행 중인 모든 프로세스 정보 (UNIX 스타일)
  • ps aux: 실행 중인 모든 프로세스 정보 (BSD 스타일)
  • pstree: 프로세스 부모/자식 관계 트리
  • vmstat: 메모리, 스왑, 디스크 I/O 등 시스템 자원 사용 현황
  • xload: 시스템 부하 그래프 GUI
  • tload: 시스템 부하 그래프 터미널

프로세스 제어

  • jobs: 작업 프로세스 보기
  • fs %n: %n번 job을 포어그라운드로 전환
  • bs %n: %n번 job을 백그라운드로 전환
  • kill pid: pid 프로세스에 TERM 신호
  • kill -9 pid: pid 프로세스를 KILL

환경

환경 변수 조작

  • set: 쉘 변수와 환경 변수 출력
  • env: 환경 변수 출력
  • printenv VAR: 환경 변수 VAR의 값 출력
  • echo $VAR: 환경 변수 VAR의 값 출력
  • export VAR: 쉘과 쉘에서 실행되는 프로세스들에 VAR를 정의
  • alias: 명령어 별칭 목록 / 생성

패키지 관리

작업 rpm dpkg
저장소 목록 업데이트 apt-get update
저장소 패키지 찾기 yum search [pkg] apt-cache search [pkg]
저장소 패키지 설치 yum install [pkg] apt-get install [pkg]
패키지 파일 설치 rpm -i [file] dpkg --install [file]
패키지 삭제 yum erase [pkg] apt-get remove [pkg]
저장소 패키지 업데이트 yum update apt-get upgrade
패키지 파일 업데이트 rpm -U [file] dpkg --install [pkg]
설치된 패키지 목록 rpm -qa dpkg --list
패키지 설치여부 rpm -q [pkg] dpkg --status [pkg]
설치된 패키지 정보 yum info [pkg] apt-cache show [pkg]
파일로 패키지 검색 rpm -qf [file] dpkg --search [file]

미디어

저장 장치 마운트

  • cat /etc/fstab: 부팅 시 마운트된 장치 목록
  • mount: 현재 마운트된 장치 목록
  • mount src dst: 장치 마운트
  • mount -t cdrom src dst: CD-ROM 마운트
  • umount target: 마운트 해제

미디어 이미지 복사

  • dd if=input_file of=output_file [bs=block_size [count=blocks]]

네트워크

네트워크 관리

  • ping host: ICMP ECHO_REQUEST 전송 / 확인
  • traceroute host: 패킷 경로 추적
  • netstat: 네트워크 설정 및 통계 정보 확인
  • netstat -ie: 네트워크 인터페이스 정보 확인 (ifconfig)
  • netstat -r: 네트워크 라우팅 테이블 정보 확인

네트워크 사용

  • wget url: 다운로드
  • curl url > dst: 데이터 다운로드
  • curl url < src: 데이터 업로드
  • ssh -p port id@host SSH 접속
  • ssh -p port id@host command SSH 접속, command 실행결과 반환
  • ssh [-X|-Y] port id@host SSH 터널링, X 클라이언트로 접속
  • sftp -P port id@host SSH 활용, FTP 에뮬레이트 접속

FTP 명령어

  • cd
  • ls
  • lcd: (local) cd
  • lls: (local) ls
  • get [-r] src [dst]: remote -> local
  • put [-r] src [dst]: local -> remote

파일 검색

  • locate: 파일 경로 찾기
  • find: 파일 검색 & 추가 작업
  • xargs: 표준 입력으로 인자 목록을 만들어 실행
  • grep: 표준 입력에서 정규표현식으로 검색

find

find 검색 옵션

다음 옵션으로 검색할 파일/디렉토리를 지정한다.

옵션 의미
-type c -type c c 형식의 파일 검색 (b, c, d, f, l)
-size n -size +200k 크기가 n과 같음
-name pattern -name foobar 이름이 와일드카드 패턴과 일치함
-iname pattern -iname foobar 대소문자 구별 없는 -name
-regex pattern -regex '[0-9]+' 경로명이 정규식 패턴과 일치함
-inum n -inum 1001 n번 inode에 해당 (하드 링크 검색)
-samefile name -samefile foo 이름이 foo인 파일과 inode가 같음
-empty -empty 비어 있음
-mmin n -mmin -10 n분 전에 내용 변경
-cmin n -cmin +10 n분 전에 내용/속성 변경
-mtime n -mtime 3 n*24시간 전에 내용 변경
-ctime n -ctime 3 n*24시간 전에 내용/속성 변경
-newer file -newer foo file보다 나중에 내용 변경
-cnewer file -cnewer foo file보다 나중에 내용/속성 변경
-user name -user foo name 사용자에 속함
-group name -group bar name 그룹에 속함
-nouser -nouser 유효한 사용자에 속하지 않음 (삭제된 계정 등)
-nogroup -nogroup 유효한 그룹에 속하지 않음
-perm mode -perm 755 권한이 mode와 같음
  • 시간을 나타내는 인자에는 + 또는 -를 넣어, n 이후 또는 n 이전의 의미를 나타낼 수 있다.
  • 크기를 나타내는 인자에는 + 또는 -를 넣어, n 이상 또는 n 이하의 의미를 나타낼 수 있다.

find 연산자 옵션

다음 연산자로 검색 옵션을 조합하는 방법을 지정한다. (lazy 평가)

연산자 약어 설명
-and -a and 연산 (기본값이므로 생략 가능)
-or -o or 연산
-not -! not 연산
\(, \) 우선순위 지정, 조건 그룹화

예) find ~ \( -type f -not -perm 0600 \) -o \( -type d -not -perm 0700 \)

~경로에서 권한이 0600이 아닌 파일 또는 권한이 0700이 아닌 디렉토리 검색

find 액션 옵션

find 액션 옵션으로 다음과 같은 액션을 지정할 수 있다.

액션 의미
-print 넘겨받은 파일들의 전체 경로명을 표준 출력 (기본 액션)
-ls 넘겨받은 파일들을 ls -dils 표준 출력
-delete 넘겨받은 파일들을 삭제
-quit 넘겨받은 파일이 하나라도 있을 경우 검색 종료
-exec command '{}' ';' 넘겨받은 파일들에 command 명령을 실행
-ok command '{}' ';' 넘겨받은 파일들에 command 명령을 실행 (실행여부 확인)
  • 특정 조건으로 검색된 파일에 대해 액션을 지정하려면 옵션 -and 액션으로 지정 (-and는 생략 가능)

검색된 파일에 명령을 각각 실행하는 것이 아니라, 파일 전체에 한 명령을 넘기려면 다음 중 한 방법을 쓰면 된다.

  • find 기능: find [...] -exec command '{}' +
  • xargs에 표준 출력 전달: find [...] -print | xargs command [params]

find 기타 옵션

find 액션 옵션으로 다음과 같은 액션을 지정할 수 있다.

액션 의미
-depth 디렉토리보다 디렉토리내 파일에 우선 실행 (-delete는 자동 적용)
-maxdepth levels 최대 탐색 깊이
-mindepth levels 최소 탐색 깊이
-mount 다른 파일시스템에 마운트도된 디렉토리 제외
-noleaf UNIX용 find 최적화 사용 안함 (DOS/Windows, CD-ROM 등)

grep

사용법

정규표현식 종류 명령
Posix 기본 정규표현식 grep [options] regex [file...]
확장 정규표현식 grep [options] -E regex [file...]
확장 정규표현식 egrep [options] regex [file...]

grep 옵션

옵션 설명
-i 대소문자 구별 안함
-v 반전 매치
-c 일치한 행의 수 출력
-l 일치한 행을 포함한 파일의 이름 출력
-L 일치한 행이 없는 파일의 이름 출력
-n 일치한 행 앞에 행 번호 표시
-h 파일명 출력 숨김

파일 관리

  • touch: 파일 생성 / 파일 수정시간 갱신
  • stat: 파일 메타 데이터 출력

파일 압축

  • gzip: .gz 압축
  • gunzip: .gz 압축 해제
  • bzip2: .bz2 압축 (블록 단위 고성능 압축)
  • bunzip2: .bz2 압축 해제
  • zip: .zip 압축 (비 UNIX 파일 압축)
  • unzip: .zip 압축 해제
  • tar: 테이프 아카이브

gzip

gzip 옵션

옵션 설명
-c 압축 결과를 표준 출력에 씀. 원본 파일 유지
-d 압축 해제 (gunzip과 동일)
-f 압축 파일이 이미 존재해도 압축을 실행
-h 도움말
-l 압축 파일별로 압축 정보 표시
-r 디렉토리 내 순환 압축
-t 무결성 검사
-v 압축 과정 자세히 표시
-1 ~ -9 압축률 설정. 기본값은 -6
--fast -1와 동일
--best -9와 동일

gzip 관련 유틸리티

  • zcat: gunzip -c file (.gz 압축 해제 결과를 표준 출력으로 보냄)
  • zless: zcat file | less (.gz 압축 해제 결과를 표준 출력으로 보내고 less)

bzip2

bzip2 관련 유틸리티

  • bzcat: bunzip2 -c file (.bz2 압축 해제 결과를 표준 출력으로 보냄)
  • bzip2recover: 손상된 .bz2 파일 복구

tar

tar 옵션

옵션 설명
f name 아카이브 이름 지정
c 아카이브 생성
x 아카이브 해제
r 아카이브 추가
t 아카이브 내용 보기
z gzip으로 압축 (GNU tar 최신버전)
j bzip2로 압축 (GNU tar 최신버전)

tar 옵션에는 -를 붙이지 않는다.

예)

  • tar cf files.tar .: 현재 디렉토리를 files.tar로 묶기
  • tar xf files.tar .: 현재 디렉토리에 files.tar를 풀기
  • tar tf files.tar: files.tar 아카이브 내용 보기
  • tar tvf files.tar: files.tar 아카이브 내용 자세히 보기

tar 아카이브 생성시 파일 스트림 지정 옵션

옵션 설명
--files-from=file 입력 스트림 지정
--files-from=- 입력 스트림을 표준 입력으로 지정
f file 출력 스트림 지정
f - 출력 스트림을 표준 출력으로 지정

파일 스트림에 -를 지정하면 표준 입출력으로 지정한다.

예)

  • find src -name '*.c' | tar czf src.tar.gz -T -: src 디렉토리의 *.src를 src.tar.gz로 압축
  • find src -name '*.c' | tar cjf src.tar.bz2 -T -: src 디렉토리의 *.src를 src.tar.bz2로 압축

파일 동기화

  • rsync: 원격 동기화

텍스트 조작

  • cat: 파일과 표준 출력을 연결
  • sort: 행 단위 정렬
  • uniq: 중복 행 제거
  • cut: 각 행의 부분 자르기
  • paste: 각 행의 부분 합치기
  • join: 공통 필드로 행 합치기 (RDB 관련 작업)
  • comm: 두 파일의 유일 행, 공통 행 비교 출력
  • diff: 두 파일을 행 단위 비교 (Git와 유사)
  • patch: diff 파일로 원본에 패치 (Git와 유사)
  • tr: 문자 집합 치환
  • sed: 텍스트 필터링, 치환 (Vim의 치환과 유사)
  • aspell: 맞춤법 검사
  • expand: 탭을 스페이스로 치환
  • unexpand 스페이스를 탭으로 치환

cat

cat 옵션

옵션 설명
-A 비출력 문자 표시
-n 줄 번호 표시
-s 공백 줄 제거

sort

sort 옵션

옵션 Long 옵션 설명
-b --ignore-leading-blanks 행 앞부분의 공백 문자 무시하고 비교
-f --ignore-case 대소문자 구분 무시
-n --numeric-sort 수치를 기준으로 정렬
-r --reverse 역순 정렬
-k --key= field1[,field2] 키 필드로 지정된 field1 ~ field2를 기준으로 정렬
-m --merge 정렬된 파일들을 다시 섞지 않고 묶어서 정렬하여 합침
-o --output= file 결과를 표준 출력이 아닌 file로 보냄
-t --field-separator= char 필드 구분 문자 정의 (기본값: 스페이스, 탭)

sort 복수 키 지정

  • 정렬을 위한 복수 키를 지정할 수 있다.
  • 정렬 방식을 나타내는 문자 옵션(-b, -n, -r 등)은 키 지정자 끝에 포함될 수 있다.

예)

sort -k 1,1 -k 2n

uniq

uniq 옵션

옵션 설명
-u 유일한 행 출력 (기본값)
-d 중복된 행 출력
-c 중복 발생 횟수, 중복 행 목록 출력
-i 대소문자 구별 무시
-f n 각 행에서 n개 필드까지 무시하고 비교 (필드 구분자 지정 불가)
-s n 각 행에서 n개 문자까지 무시하고 비교

cut

행에서 텍스트 일부를 추출해 표준 출력으로 출력

cut 옵션

옵션 설명
-c char_list char_list 정의 영역 추출 (콤마로 구분된 숫자 범위)
-f field_list field_list 정의 필드 추출 (필드 또는 콤마로 구분된 필드 범위)
-d delim_char delim_char를 필드 구분자로 사용 (기본값: 탭)
--complement -c 또는 -f로 지정된 영역을 제외한 모든 부분을 추출

diff

  • 소스코드 디렉토리에서 변경 사항을 재귀적으로 확인
  • diff 파일을 만들고 패치를 생성

diff 옵션

방식 옵션 추가 / 변경 / 삭제
기본 diff f1 f2 r1ar2 / r1cr2 / r1dr2
문백 방식 -c diff -c f1 f2 + / ! / -
통합 방식 -u diff -u f1 f2 + / / -

diff 파일 생성하기 (patch 용)

  • 생성: diff -Naur old-file new-file > diff-file
  • 패치: patch diff-file

tr

ROT13

  • tr a-zA-Z n-za-mN-ZA-M

연속문자 제거

  • tr -s a-z: 연속되는 a-z를 제거

sed (stream editor)

sed 주소 표기법

주소 설명
n n 번째 행
$ 마지막 행
/regexp/ POSIX 기본 정규식과 일치하는 행들
addr1, addr2 aadr ~ addr2 범위의 행들
first~ step first 일치 행과 그 후 step 간격마다 모든 행
addr1,+n addr1 일치 행과 다음 n개의 행
addr! addr을 제외한 모든 행

sed 기본 편집 명령어

명령어 설명
= 현재 행번호 출력
a 현재 행 뒤에 텍스트 추가
d 현재 행 삭제
i 현재 행 앞에 텍스트 삽입
p 현재 행 출력
q 더이상 처리할 행이 없으면 종료
Q 더이상 처리할 행이 없으면 종료
s/regexp/replace regexp와 일치하는 부분을 replace로 치환
y/set1/set2 set1의 문자를 set2의 문자로 치환

sed 옵션

옵션 설명
-i 파일 내 수정

텍스트 출력 포맷

  • nl: 줄 번호 매기기
  • fold: 각 줄을 지정된 길이로 나누기
  • fmt: 포맷 지정
  • pr: 인쇄용 포맷 지정
  • printf: 출력 및 포맷 지정
  • groff: 문서 포맷 시스템

컴파일

일반적인 c 프로젝트 컴파일 과정

  1. ./configure
  2. make
  3. sudo make install

objdump - 디스어셈블

objdump -d obj

쉘 스크립트

쉘 스크립트 작성 과정

  1. 스크립트 작성
  2. 실행 권한 설정
  3. 실행 경로에 저장

스크립트 파일 헤더

#!/bin/bash

스크립트를 실행할 인터프리터의 경로를 지정함

스크립트 저장 위치

다음 위치는 적합하다.

  • ~/bin: 개인 사용자용 실행 파일
  • /usr/local: 전체 사용자용
  • /usr/local/bin: 전체 사용자용 실행 파일
  • /usr/local/sbin: 시스템 관리자용 실행 파일

다음 위치는 부적합하다. 리눅스 배포자가 제공하고 관리하는 파일을 저장하는 곳이기 떄문이다.

  • /bin
  • /usr/bin

Here 문서

아래와 같은 형식으로 스크립트 파일의 텍스트 본문을 표준 입력으로 보냄.

#!/bin/bash

cat << _EOF_
Text to
put into
stdin
here.
_EOF_

쉘 함수

다음과 같은 형식으로 생성

function name {
  commands
  return
}
name () {
  commands
  return
}

두 형식의 결과는 동일하다.

지역 변수

쉘 함수 안에서 다음과 같이 선언한다.

local foo
foo=1

종료 상태 (exit status)

  • 0 ~ 255 사이의 값.
  • 일반적으로 0은 성공, 그 외의 값은 실패를 나타냄.
  • 프로그램 종료시 쉘 변수 $?에 저장
  • exit n: n값을 exit status로 반환하며 스크립트 종료. (n의 기본값은 0)

관련 프로그램

  • true: exit status 0을 반환하는 프로그램
  • false: exit status 1을 반환하는 프로그램
  • test expression: expression이 참이면 0, 거짓이면 1의 종료 상태를 반환하는 프로그램

분기

if

다음과 같은 구문으로 분기

if condition; then
  commands
[elif condition; then
  commands...]
[else
  commands]
fi

case

case word in
  [pattern [| pattern]...) commands ;;]...
esac

if 또는 test에서 사용할 수 있는 조건식

파일 표현식
표현식 의미
file1 -ef file2 file1file2는 동일한 inode 번호를 가진다.
file1 -nt file2 file1file2보다 최신이다.
file1 -ot file2 file1file2보다 오래됐다.
-e file file이 존재한다.
-f file file이 존재하고, 이 파일은 일반 파일이다.
-d file file이 존재하고, 이 파일은 디렉토리다.
-L file file이 존재하고, 이 파일은 심볼릭 링크다.
-b file file이 존재하고, 이 파일은 블록 특수 파일이다.
-c file file이 존재하고, 이 파일은 문자 특수 파일이다.
-s file file이 존재하고, 이 파일은 크기가 0보다 크다.
-u file file이 존재하고, 이 파일은 setuid가 설정되어 있다.
-g file file이 존재하고, 이 파일은 setgid가 설정되어 있다.
-G file file이 존재하고, 이 파일은 유효 그룹 ID의 소유다.
-r file file이 존재하고, 이 파일은 읽기가 가능하다.
-w file file이 존재하고, 이 파일은 쓰기가 가능하다.
-x file file이 존재하고, 이 파일은 실행이 가능하다.
-k file file이 존재하고, 이 파일은 sticky bit를 가지고 있다.
-O file file이 존재하고, 이 파일은 유효 사용자 ID의 소유다.
-p file file이 존재하고, 이 파일은 네임드 파이프다.
-S file file이 존재하고, 이 파일은 네트워크 소켓이다.
-t fd fd는 터미널이 지정된 파일 디스크립터다. (표준 입력/출력/오류의 재지정 여부 확인)
문자열 표현식
표현식 의미
string stringnull이 아니다.
-n string string의 길이는 0보다 크다.
-z string string의 길이는 0이다.
string1 == string2 string1string2는 같다.
string1 != string2 string1string2는 다르다.
string1 < string2 string1string2보다 앞에 정렬된다.
string1 > string2 string1string2보다 뒤에 정렬된다.
정수 표현식
표현식 의미
int1 -eq int2 int1int2와 같다.
int1 -ne int2 int1int2와 다르다.
int1 -lt int2 int1int2보다 작다.
int1 -le int2 int1int2보다 작거나 같다.
int1 -gt int2 int1int2보다 크다.
int1 -ge int2 int1int2보다 크거나 같다.

현대식 테스트

bash는 다음과 같은 구문을 지원한다.

[[ ]]

[[ expression ]]

expression에는 참/거짓을 판단하는 표현식을 입력한다. [[ ]]명령식은 test의 모든 표현식을 지원하고, 다음 문자열 표현식을 추가로 지원한다.

string1 =~ regex

이 표현식은 string1이 확장 정규 표현식인 regex에 부합하면 참을 반환한다.

예) N이 정수인지 확인

if [[ "$N" =~ ^-?[0-9]+$ ]]; then
  echo "$N is integer."
else
  echo "$N is not integer."
fi

또, [[ ]] 명령식은 == 연산자가 경로명 확장과 같은 방식의 패턴 찾기를 수행하도록 지원한다.

(( )) - 정수 테스트

산술식의 참 여부를 검사함: 산술식의 결과가 0이면 거짓, 0이 아니면 참을 반환.

표현식 조합

논리 연산 test [[ ]], (( ))
AND -a &&
OR -o
NOT ! !

read

다음 명령으로 표준 입력에서 값을 읽어온다.

read [-options] [variable...]

매개변수 개수

  • 매개변수가 지정되지 않았을 때: REPLY 환경 변수에 값이 저장됨
  • 매개변수보다 많은 개수의 입력이 주어졌을 때: 마지막 매개변수에 나머지 값이 모두 저장됨
  • 매개변수보다 적은 개수의 입력이 주어졌을 때: 나머지 매개변수에는 값이 주어지지 않음

read 옵션

옵션 설명
-a array 입력값을 array에 할당. (인덱스 0부터 시작)
-d delimiter 개행 문자 대신 delimiter를 EOF로 사용
-e Readline을 이용해 입력을 관리
-n num 입력된 행 전체 대신 num 개수만큼의 문자만을 읽음
-p prompt prompt를 입력 프롬프트로 출력
-r Raw 모드. \를 이스케이프로 인식하지 않음
-s 묵음 모드 (패스워드 등)
-t seconds 입력 시간 제한. 시간 초과시 0이 아닌 종료 상태 반환
-u fd 표준 입력 대신 fd 디스크립터를 입력으로 사용

IFS(입력 필드 구분자) 변경 기법

IFS는 입력 필드 구분자를 설정하는 환경 변수.

IFS=":" read

쉘은 명령어가 처리되기 직전에 하나 이상의 변수 할당을 허용한다. 이 할당은 뒤이어 나오는 명령어에 대한 환경을 변화시킨다. 이 변화는 일시적이고 명령어의 지속 시간 동안만 환경을 변경하는 것이다. 위 스크립트의 결과는 아래의 스크립트의 결과와 같다.

OLD_IFS="$IFS"
IFS=":"
read
IFS="$OLD_IFS"

read와 파이프라인

아래와 같이 파이프라인을 통해 read에 표준 입력을 전달할 수는 없다.

echo "foo" | read
  • 파이프라인은 서브쉘을 생성하며
  • 서브쉘은 부모 프로세스의 환경을 변경하지 않는다.
  • read가 읽어들인 값은 서브쉘 안에서만 존재한다.
  • read 종료시점에서 REPLY 값은 존재하지 않게 된다.

따라서, 아래와 같이 해야 한다.

read <<< foo

<<< [text...]는 here 문자열이다.

반복

for

쉘 형식

for variable [in words]; do
  commands
done
  • in words가 생략될 경우, 위치 매개변수를 words로 사용한다.

C 형식

for (( expression1; expression2; expression3 )); do
  commands
done

while

while condition; do
  [commands...]
done

until

until condition; do
  [commands...]
done

break

continue

위치 매개변수

커맨드라인 명령어에서 제공된 매개변수를 참조하는 방법.

변수 참조

변수 설명
$0 실행 프로그램 경로명
$i i번째 인자의 값 (i는 0~9)
${i} i번째 인자의 값 (i는 자연수)
$# 인자의 개수
  • basename : 경로명의 앞 부분을 제거하고 파일의 기본 이름만을 추출

shift

실행될 때마다 매개변수가 하나씩 다음으로 이동함.

예) 모든 인자값 출력

while [[ #$ -gt 0 ]]; do
  echo "Argument $i = "
  i=$((i + 1))
  shift
done

쉘 함수에서의 위치 매개변수

쉘 함수에 인자를 넘겨 호출할 수 있다.

  • $1 ~ $n은 함수에 넘겨진 인자의 값을 참조
  • $0은 쉘 함수명이 아닌 프로그램명을 참조
  • 쉘 함수명 참조: $FUNCNAME

위치 매개변수 전체 전달

네 가지 방법이 있다.

  • $*
  • $@: i번째 매개변수가 $i로 각각 바인딩된다. 이걸 써라.
  • "$*"
  • "$@"

변수 확장

기본

구문 설명
$v $foo v의 값
${v} ${foo} v의 값
$n $1 n번째 매개변수의 값
${n} ${32} n번째 매개변수의 값

빈 변수 관련

변수가 비었는지 아닌지에 따라 처리

구문 $v empty $v value 설명
{$v:-word} $v word v의 값이 없으면 word 반환
{$v:+word} word v의 값이 있으면 word 반환
{$v:=word} $v $v=word; word v의 값이 없으면 word 대입하고 반환
{$v:?error-msg} error-msg, error $v v의 값이 없으면 오류, error-msg 출력

변수명으로 확장

변수명을 조사, 반환하는 확장

구문 설명
${!prefix*} ${!BASH*} 이름이 prefix로 시작하는 모든 변수
${!prefix@} ${!BASH@} 이름이 prefix로 시작하는 모든 변수
  • 위의 두 구문은 동일하게 동작한다.

문자열 연산

변수에 저장된 문자열을 조작

구문 설명
${#v} ${#HOME} 문자열 $v의 길이
${v:offset} ${HOME:6} 문자열 $voffset 이후 추출
${v:offset:length} ${HOME:6:3} 문자열 $voffset 이후부터 length 길이 추출
${v#pattern} ${HOME#*/} 문자열 $vpattern 패턴 이후 추출 (게으름 모드)
${v##pattern} ${HOME##*/} 문자열 $vpattern 패턴 이후 추출 (탐욕 모드)
${v%pattern} ${HOME%/*} 문자열 $vpattern 패턴 이전 추출 (게으름 모드)
${v%%pattern} ${HOME%%/*} 문자열 $vpattern 패턴 이전 추출 (탐욕 모드)
${v/pattern/s} ${HOME/home/u} 문자열 $v의 첫번째 pattern 일치 항목을 s로 치환
${v//pattern/s} ${HOME/home/u} 문자열 $v의 모든 pattern 일치 항목을 s로 치환
${v/#pattern/s} ${HOME/#\/home/\~} 문자열 $v의 시작점의 pattern 일치 항목을 s로 치환
${v/%pattern/s} ${HOME/%foo\bar} 문자열 $v의 종료점의 pattern 일치 항목을 s로 치환
  • ${v:offset}, ${v:offset:length}에서 offset이 음수이면, 문자열의 뒤에서부터 시작한다. 이 떄, offset 앞에 빈칸을 한 칸 두어야 한다.
  • ${v/pattern/s}, ${v//pattern/s}, ${v/#pattern/s}, ${v/%pattern/s}에서 s를 생략하면, 해당 pattern 일치 항목을 삭제한다.
  • 문자열 조작 확장은 sed, cut 등의 외부 프로그램보다 처리성능이 좋다.

산술 연산 확장

아래 구문에 표현식을 넣어 확장한다.

$((expression))

기수

표현 설명
n 99 10진법 표현
0n 0777 8진법 표현
0xn 0xff 16진법 표현
base#n 2#1111 base진법 표현

단항 연산자

연산자 설명
+ 덧셈
- 뺄셈
* 곱셈
/ 정수 나눗셈
** 거듭제곱
% 나머지

대입

연산자 설명
v = value pv대입. [[ a = b ]] 와 혼동 주의
v += value 덧셈 대입
v -= value 뺄셈 대입
v *= value 곱셈 대입
v /= value 나눗셈 대입
v++ 후치 증가
v-- 후치 감소
++v 전치 증가
--v 전치 감소

비트 연산

연산자 설명
~ 비트 NOT. 모든 비트에 부정 연산
<< 비트 시프트. 모든 비트를 좌로 이동
>> 비트 시프트. 모든 비트를 우로 이동
& 비트 AND. 둘 모두가 참
` `
^ 비트 XOR. 둘 중 하나만 참
  • ~을 제외한 모든 비트 연산은 그에 상응하는 대입 연산자가 있음. (예: <<=, &= 등)

산술 논리 연산

연산자 설명
<= 보다 작거나 같다
>= 보다 크거나 같다
< 보다 작다
> 보다 크다
== 같다
!= 다르다
&& 논리 AND
`
c? a:b c가 참이면 a, 거짓이면 b
  • 산술 논리식에서는 0은 거짓, 다른 수는 참이다.

기타 확장

표현 설명
$$ 프로세스 ID (PID)
$! 마지막으로 백그라운드에 실행된 작업의 PID
$RANDOM 1 ~ 32767 사이의 난수

bash 배열

배열 도움말 보기

$ man bash -g Arrays

배열 생성

배열 첨자 사용, 대입시 생성

예)

foo[1]=bar
echo ${foo[1]}

declare -a로도 생성 가능

예)

declare -a foo

배열에 값 할당

단일 값 할당

name[subscript]=value

복수 값 할당

name=( value1 value2 ... )

첨자 사용 할당

nane=([i1]=value1 [i2]=value2 ...)

배열 연산

모든 내용 출력
  • 첨자 *: 배열의 전체 내용을 한 행의 문자열로 반환
  • 첨자 @: 배열의 전체 내용을 각각의 행의 문자열로 반환 (추천)

예)

arr=("a cat" "a dog" "a tiger")
for e in ${arr[*]}; do
  echo $e
done
배열 원소 수 확인
  • ${#arr[*]}
  • ${#arr[@]}
배열에 할당된 첨자 검색
  • ${!array[*]}
  • ${!array[@]}
배열 끝에 원소 추가
  • += 할당 연산자를 배열에 사용

예)

arr=(a b c)
arr+=(d e f)
배열 정렬
  • bash는 지원 안함. 직접 구현할 것.

예)

arr=(e f a c b d)
sorted_arr=($(for e in "${arr[@]}"; do echo $e; done | sort))
배열 삭제

unset 사용.

  • 배열 전체 삭제: unset arr
  • 배열 원소 삭제: unset arr[subscript]

그룹 명령과 서브쉘

  • 그룹 명령: { command1; command2; [ command3; ...] }
  • 서브쉘: (command1; command2; [ command3;...])

그룹 명령은 현재 쉘에서, 서브쉘은 자식 쉘에서 실행됨. 따라서 그룹 명령이 선호됨.

주로 리다이렉션을 조절하기 위해 사용됨.

예)

{ ls -al; ps -ef; } > output1.txt
(ls -al; ps -ef) > output2.txt

프로세스 치환

  • 표준 출력 생성 프로세스: <(command_list)
  • 표준 입력 생성 프로세스: >(command_list)

예)

read < <(echo "foo")
echo $REPLY

트랩

시그널 처리 등록

  • trap command signal [signal...]: signal 신호를 받았을 때 command를 실행하도록 등록.

임시 파일

위치

  • 기본적으로 /tep 디렉토리에 생성.
  • 일반 사용자 실행 스크립트의 경우 /tmp 디렉토리보다 $Home/tmp 추천.

예) $HOME/tmp가 없으면 생성.

[[ -d $HOME/tmp ]] || mkdir $HOME/tmp

temp race attack을 방지하려면, 예측할 수 없는 이름을 만들어야 함.

  • temp=/tmp/$(basename $0).$$.$RANDOM: /tmp/프로그램명.PID.난수로 생성. 안전성 불충분.
  • temp=$(mktemp /tmp/$(basename $0).$$.XXXXXXXX): mktemp 프로그램 이용. X의 개수만큼 랜덤 문자 추가.

비동기 실행

wait

wait pid

비동기 실행중인 프로세스가 종료될 때까지 대기함.

예)

async-child-process &
pid=$!
wait $pid
  • $!: 마지막으로 백그라운드에 진입한 프로세스 ID

네임드 파이프

프로스세간 통신 수단

  • 네임드 파이프 생성: mkfifo named_pipe
  • 보내기: sending_process > named_pipe
  • 받기: recieving_process < named_pipe

예)

  • 터미널 1:
mkfifo pipe1
ls -l > pipe1
  • 터미널 2:
cat < pipe1

디버깅

에러 출력

echo "error" >&2 # DEBUG

트레이싱 (tracing)

  • /bin/bash -x: bash-x- 옵션을 주어 트레이싱
#!/bin/bash -x
...
  • set -x ~ set +x: 선택 영역 트레이싱
#!/bin/bash
...
set -x # turn on tracing
...
set +x # turn off tracing

기타

date

  • date +"format"

자주 쓰는 포맷

포맷 설명
%F 날짜, YYYY-MM-DD
%T 시각, HH:MM:SS
%R 시각, HH:MM
%H 시, 00 ~ 23
%I 시, 00 ~ 12
%M 분, 00 ~ 59
%S 초, 00 ~ 60
%N 나노초
%Z 시간 구역 약어
%a 요일 약어
%A 요일
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment