'OS/리눅스 & 유닉스'에 해당되는 글 130건

  1. 2014.11.03 SVN 명령어
  2. 2014.11.03 SVN 권한 설정
  3. 2014.11.03 SVN 서버 설정
  4. 2014.11.03 방화벽 오픈/해제
  5. 2014.09.18 mail 전송의 원리
  6. 2014.09.18 큐메일
  7. 2012.07.05 리눅스 명령어 모음
  8. 2012.06.01 POSIX Semaphore & System V Semaphore
  9. 2012.06.01 Speaking UNIX: 공유 메모리를 이용한 프로세스 간 통신(IPC)
  10. 2012.05.31 ibm aix polling

SVN 명령어

OS/리눅스 & 유닉스 2014. 11. 3. 16:25

본 문서는 위 참고자료에서 필요한 부분만 요약한 것입니다. 설치 과정과 용어는 참고 자료를 참조하세요.
동작 환경: CentOS 4.6, MS Windows XP


저장소 만들기(root)
$ mdir /home/svn; cd /home/svn
$ svnadmin create --fs-type bdb sample (버클리 DB)
또는
$ svnadmin create --fs-type fsfs sample (파일 시스템)


svnserv 설정(root)
$ svnserve -d -r /home/svn/
$ vi /home/svn/sample/conf/svnserve.conf (편집은 참고 자료 "4.3.1 svnserve에서 ID로 사용자 인증" 참조)
$ vi /home/svn/sample/conf/passwd (편집은 참고 자료 "4.3.1 svnserve에서 ID로 사용자 인증" 참조)


기본 디렉터리 만들기(root)
$ svn mkdir svn://localhost/sample/trunk
$ svn mkdir svn://localhost/sample/branches
$ svn mkdir svn://localhost/sample/tags


에디터 설정(user)
$ vi ~/.bash_profile 
SVN_EDITOR=/usr/bin/vim
export SVN_EDITOR


명령어(user)
import: 처음 저장소에 소스 저장            
$ svn import directory_root_name svn://localhost/sample/trunk
checkout(co): 소스 받기                       $ svn checkout svn://localhost/sample/trunk directory_root_name
update: 최근 내용으로 수정                      $ svn update
commit: checkout한 소스 수정 후 저장        $ svn commit
log: 저장소 변경 log 확인                          $ svn log
                                                            $ svn log -r n (n 로그 출력)
                                                            $ svn log -r n:m (n ~ m 로그 출력. 역순 가능)
                                                            $ svn log -r file_name (file_name 로그 출력)
                                                            $ svn log -v [-r n] [file_name(A(추가)/M(수정) 정보 출력)
                                                            $ svn log -v -r n file_name (A(추가)/M(수정) 정보 출력)
diff: 변경된 소스 비교                               $ svn diff
                                                            $ svn diff -r n file_name
                                                            $ svn diff -r n:m file_name
blem: 한 소스 파일에서 변경자 보기           $ svn blem file_name
                                                            $ svn blem -r n file_name
lock: 다른 사용자가 변경할 수 없도록 잠금   $ svn lock file_name
unlock: 잠금 파일 풀기                             $ svn unlock file_name
add: 파일 추가. commit 필요                     $ svn add file_name
export: 순수한 소스만 받기                   
$ svn checkout svn://localhost/sample/trunk directory_root_name


Branch 하기
Branch 만들기
$ svn checkout svn://localhost/sample/trunk directory_root_name
$ cd directory_root_name
$ svn copy trunk branches/directory_name
$ svn commit

Branch된 소스 받기
$ svn checkout svn://localhost/sample/branches directory_root_name

Branch에서 수정한 소스를 trunk에 반영
$ svn mearge -r n:m file_name (n과 m사이 차이점을 trunk에 반영)
$ svn commit
$ svn update

Tag 하기
Tag 만들기
$ svn checkout svn://localhost/sample/trunk directory_root_name
$ cd directory_root_name
$ svn copy trunk tags/0.1  (버전을 입력)
$ svn commit

소스 릴리즈
$ svn export svn://localhost/sample/tags/버전 directory_root_name


백업 및 복구
백업
$ svnadmin dump sample > sample.dump

복구
$ svnadmin create sample
$ svnadmin load sample < sample.dump



출처 - http://novrain.egloos.com/viewer/1808344

'OS > 리눅스 & 유닉스' 카테고리의 다른 글

SVN 권한 설정  (0) 2014.11.03
SVN 서버 설정  (0) 2014.11.03
방화벽 오픈/해제  (0) 2014.11.03
mail 전송의 원리  (0) 2014.09.18
큐메일  (0) 2014.09.18
:

SVN 권한 설정

OS/리눅스 & 유닉스 2014. 11. 3. 15:50

svnserve.conf

[general]
anon-access=none
auth-access = write
password-db = passwd
authz-db = authz
realm = Kanji_Proj


요로코롬 짧아진다. 그럼 각각의 의미를 알아 보자.

[general]
anon-access=none           #인증되지않은(즉 계정이 없는) 사용자에 대해 접근을 거부한다.
auth-access = write          #인증된 사용자에 대해 쓰기 권한을 준다.
password-db = passwd     # 인증된 사용자에 대한 계정 정보(아이디/패스) 정보가 기록된 파일명을 의미한다.(기본값 passwd) 
authz-db = authz              # 인증된 사용자에 대해 저장소에 대한 권한 설정이 기록된 파일명(기본값)
#realm = Kanji_Proj             #현재 파일에 해당되는 저장소의 영역에 대해 설정하는 것인데 여기서는 주석처리로 하고 넘어가자.(ㅌㅌ)

즉, 인증된 사용자에게 저장소의 접근권한을 일체 주지 않고, 인증된 사용자에게만 접근을 허용하는 그런 의미를 갖는 svnserve.conf파일이 되겠다. 

다음으로 passwd 파일을 살펴보자.

passwd 

[users]
# harry = harryssecret
# sally = sallyssecret

aaa = a
bbb = b
ccc = c


= 를 기준으로 왼쪽이 아이디 오른족이 비밀번호가 된다. 
id: aaa, pw: a
id: bbb, pw: b 이런식이다.

마지막으로 authz

authz

[groups]
# harry_and_sally = harry,sally
gABC = aaa, bbb, ccc

# [/foo/bar]
# harry = rw
# * =

# [repository:/baz/fuz]
# @harry_and_sally = rw
# * = r

[/]
@gABC = r

[ABC:/]
* = r
@gABC  = rw


authz 파일의 의미를 살펴보자

[groups]
# harry_and_sally = harry,sally   # 사용자를 그룹단위로 묶을 수 있다.
gABC = aaa, bbb, ccc               # 즉, 사용자 aaa, bbb, ccc를 묶어서 gABC라는 그룹으로 관리.

# [/foo/bar]
# harry = rw
# * =

# [repository:/baz/fuz]             #repository저장소의 /baz/fuz위치에 대한 권한
# @harry_and_sally = rw            #@<-의 의미는 그룹을 뜻한다. harry_and_sally 그룹에 읽기/쓰기권한을 준다.
# * = r                                     # * 는 모든 사용자를 의미한다. 모든 사용자에게 읽기 권한을 준다.           

[ABC:/]                                 #ABC:/저장소
* = r                                       #모든 사용자에게 읽기 권한을 준다.
@gABC  = rw                          #gABC그룹에게 읽기/쓰기 권한을 준다.


출처 - http://ummae.tistory.com/197

'OS > 리눅스 & 유닉스' 카테고리의 다른 글

SVN 명령어  (0) 2014.11.03
SVN 서버 설정  (0) 2014.11.03
방화벽 오픈/해제  (0) 2014.11.03
mail 전송의 원리  (0) 2014.09.18
큐메일  (0) 2014.09.18
:

SVN 서버 설정

OS/리눅스 & 유닉스 2014. 11. 3. 15:49


SVN 서버 설정

 
Yes check.svgCentOS 6.3에서 테스트되었습니다.

개요

서브버전 설치 및 설정하기
  • 이 문서에서는 저장소(repository)의 상위 디렉토리를 /svn으로 한 예이다.
  • 해당 디렉토리 아래에 저장소(디렉토리)를 여러 개 둘 수 있다(예: repo1, repo2...).

사전 작업

저장소 생성

서버 1대에 저장소를 여러 개 생성할 수 있다. 저장소 폴더들이 /svn 아래에 있도록 설정할 것이다.

명령어
mkdir /svn
cd /svn
svnadmin create --fs-type fsfs 저장소명
ll
실행 예시
[root@jmnote ~]# mkdir /svn
[root@jmnote ~]# cd /svn
[root@jmnote svn]# svnadmin create --fs-type fsfs repo1
[root@jmnote svn]# ll
total 4
drwxr-xr-x. 6 root root 4096 Jun  1 09:27 repo1
  • 여러 프로젝트를 담기 위해 반드시 저장소를 여러 개 만들 필요는 없다. 저장소 폴더 아래에 다시 프로젝트별 폴더들을 만들어 관리하면 되기 때문이다.
  • 그렇다면 언제 저장소를 여러 개 만들어야 할까? 하나의 저장소는 하나의 사용자 권한 설정을 가지고 있다. 그러므로 사용자들의 권한이 구분되어야 할 때 저장소를 여러 개 두는 것이 좋다.

/etc/sysconfig/svnserve 생성

 /etc/sysconfig/svnserve 문서를 참고하십시오.

이 파일을 생성해주어야 service svnserve start/stop이 가능하다.[1]

명령어
echo 'OPTIONS="--threads --root 저장소최상위폴더"' > /etc/sysconfig/svnserve
cat /etc/sysconfig/svnserve
실행예시
[root@jmnote ~]# echo 'OPTIONS="--threads --root /svn"' > /etc/sysconfig/svnserve
[root@jmnote ~]# cat /etc/sysconfig/svnserve
OPTIONS="--threads --root /svn"

svnserve.conf 수정

 svnserve.conf 문서를 참고하십시오.

svnserve.conf 파일을 svnserve.conf.old 로 변경하여 보존해두고 새로 작성한다.

명령어
cd /svn/repo1/conf/
cat svnserve.conf
mv svnserve.conf svnserve.conf.old
echo '[general]' > svnserve.conf
echo 'anon-access = none' >> svnserve.conf
echo 'auth-access = write' >> svnserve.conf
echo 'password-db = passwd' >> svnserve.conf
echo 'authz-db = authz' >> svnserve.conf
cat svnserve.conf
실행예시
[root@jmnote ~]# cd /svn/repo1/conf/
[root@jmnote conf]# cat svnserve.conf
### This file controls the configuration of the svnserve daemon, if you
### use it to allow access to this repository.  (If you only allow
### access through http: and/or file: URLs, then this file is
### irrelevant.)
... (생략)
[root@jmnote conf]# mv svnserve.conf svnserve.conf.old
[root@jmnote conf]# echo '[general]' > svnserve.conf
[root@jmnote conf]# echo 'anon-access = none' >> svnserve.conf
[root@jmnote conf]# echo 'auth-access = write' >> svnserve.conf
[root@jmnote conf]# echo 'password-db = passwd' >> svnserve.conf
[root@jmnote conf]# echo 'authz-db = authz' >> svnserve.conf
[root@jmnote conf]# cat svnserve.conf
[general]
anon-access = none
auth-access = write
password-db = passwd
authz-db = authz
→ 비로그인 접속자는 권한 없음, 로그인하면 쓸 수 있음, passwd와 authz 파일을 사용함.

계정 설정

 /svn/repo1/conf/passwd 문서를 참고하십시오.
  • svn는 OS계정이 아니라 자체 계정을 사용한다.
  • 해당 저장소의 conf 디렉토리에 있는 passwd를 편집하여 계정을 등록한다.
  • 패스워드 분실시에도 이 파일을 열어보면 된다.
  • passwd 파일을 passwd.old 로 이름을 변경하여 보존해두고 새로 작성한다.
명령어
cat passwd
mv passwd passwd.old
echo '[users]' > passwd
echo 'testuser1 = P@ssw0rd' >> passwd
echo 'testuser2 = P@ssw0rd' >> passwd
cat passwd
실행예시
[root@jmnote conf]# cat passwd
### This file is an example password file for svnserve.
### Its format is similar to that of svnserve.conf. As shown in the
### example below it contains one section labelled [users].
### The name and password for each user follow, one account per line.
 
[users]
# harry = harryssecret
# sally = sallyssecret
[root@jmnote conf]# mv passwd passwd.old
[root@jmnote conf]# echo '[users]' > passwd
[root@jmnote conf]# echo 'testuser1 = P@ssw0rd' >> passwd
[root@jmnote conf]# echo 'testuser2 = P@ssw0rd' >> passwd
[root@jmnote conf]# cat passwd
[users]
testuser1 = P@ssw0rd
testuser2 = P@ssw0rd

서비스 시작

 svnserve 시작/중지 문서를 참고하십시오.

/etc/sysconfig/svnserve 파일을 설정해두었기 때문에 service로 시작/중지를 할 수 있다.

[root@jmnote svn]# service svnserve start
Starting svnserve:                                         [  OK  ]
[root@jmnote svn]# ps -ef | grep svnserve | grep -v grep
root      2581     1  0 11:12 ?        00:00:00 /usr/bin/svnserve --daemon --pid-file=/var/run/svnserve.pid --threads --root /svn
[root@jmnote svn]# netstat -anp | grep svnserve
tcp        0      0 0.0.0.0:3690                0.0.0.0:*                   LISTEN      2581/svnserve
→ 기본 포트인 3690 포트로 서비스 중. (다른 포트로 변경하려면 /etc/sysconfig/svnserve를 수정해야 한다.)

여기까지 되었다면 설정이 완료된 것이다. 다른 컴퓨터에서 SVN 클라이언트로 접속하면 된다.[2] 접속 URL은 svn://서버주소/repo1 이다.

재부팅시 자동시작 설정

[root@jmnote svn]# chkconfig --list svnserve
svnserve       	0:off	1:off	2:off	3:off	4:off	5:off	6:off
[root@jmnote svn]# chkconfig svnserve on
[root@jmnote svn]# chkconfig --list svnserve
svnserve       	0:off	1:off	2:on	3:on	4:on	5:on	6:off
→ 재부팅시에 svnserve 서비스가 자동으로 시작될 것이다.

(저장소 삭제)

주의! 저장소를 삭제하고 싶을 때만 이 문단을 참고하시라. 만들 때는 svnadmin으로 하였지만, 지울 때는 그냥 저장소 폴더를 지우면 된다.

명령어
service svnserve stop
rm -rf /svn/repo1
ll
실행예시
[root@jmnote ~]# service svnserve stop
Stopping svnserve:                                         [  OK  ]
[root@jmnote ~]# rm -rf /svn/repo1
[root@jmnote ~]# ll
total 0
→ 깔끔하게 지워졌다

같이 보기

주석

  1. 이동 /etc/init.d/svnserve 파일이 이 파일을 참조하기 때문이다.
  2. 이동 물론 방화벽 등 다른 문제가 없다는 가정 하에 그렇다.


출처 - http://jmnote.com/wiki/SVN_%EC%84%9C%EB%B2%84_%EC%84%A4%EC%A0%95#cite_note-2

'OS > 리눅스 & 유닉스' 카테고리의 다른 글

SVN 명령어  (0) 2014.11.03
SVN 권한 설정  (0) 2014.11.03
방화벽 오픈/해제  (0) 2014.11.03
mail 전송의 원리  (0) 2014.09.18
큐메일  (0) 2014.09.18
:

방화벽 오픈/해제

OS/리눅스 & 유닉스 2014. 11. 3. 15:47

### 포트 방화벽 확인 ###
#>iptables --list


### 포트 추가
#> iptables -I INPUT -p tcp --dport 80 -j ACCEPT     //80 포트 추가
#> iptables -I INPUT -p tcp --dport 8080 -j ACCEPT //8080포트 추가
#> iptables -I INPUT -p tcp --dport 3306 -j ACCEPT //db포트 추가

### 주의 사항
#>service iptables restart 시 위에처럼 메모리에 올려놓은 방화벽은 모두 메모리 해제
#>service iptables restart 는 파일에 있는 방화벽 정책을 메모리에 올려줌 - 재부팅


### Fedora Linux

### 방화벽 상태 알아보기
/sbin/service iptables status

### 방화벽 올리고 내리기
/sbin/service iptables stop
/sbin/service iptables start

### 방화벽 설정 수정하기
vi /etc/sysconfig/iptables

### 방화벽 해제
iptables -F or ipchains -F


출처 - http://dryang.egloos.com/viewer/4006366

'OS > 리눅스 & 유닉스' 카테고리의 다른 글

SVN 권한 설정  (0) 2014.11.03
SVN 서버 설정  (0) 2014.11.03
mail 전송의 원리  (0) 2014.09.18
큐메일  (0) 2014.09.18
리눅스 명령어 모음  (0) 2012.07.05
:

mail 전송의 원리

OS/리눅스 & 유닉스 2014. 9. 18. 17:27

 ● 용어
MUA(Mail User Agent) : 메일을 작성하여 보내는 프로그램
MTA(Mail Transfer Agent) : 이용자로부터 메일을 받아서, 외부로 전달하는 프로그램
MDA(Mail Delivery Agent) : 전송받은 메일을 해당 사용자에게 전달
SMTP : Simple Mail Transfer Protocol) : 메일을 보낼 때 사용되는 프로토콜
POP3(Post Office Protocol) : 메일을 전송받을 때 사용되는 프로토콜
IMAP(Internet Mail Access Protocol) : 메일을 전송받을 때 사용되는 프로토콜



□ mail 전송의 원리


 

Internet service 중 가장 큰 비중을 차지하고 있는 것 중에 하나가 바로 mail service일 것이다. mail server를 운영하려는 우리는, 과연 internet에서 mail이 어떠한 원리로 전송되는지 반드시 알아야 할 것이다. 우선은 간단한 원리를 소개하겠고.. 앞으로 계속해서 mail server의 작동원리까지 설명해 나가겠다.

 

■ internet에서는 메시지를 송신하기 위해 SMTP 프로토콜을 사용한다.
SMTP란, Simple mail Transfer protocol의 약자로서 메시지를 교환하기 위한 프로토콜 규약이다.
다음의 그림을 보면서 자세히 설명하겠다.

 



 

 1. 사용자는 mail client (outlook 또는 eudora)와 같은 프로그램을 통해서 mail을 작성한 후, SMTP를 사용하여 mail deamon으로 메시지를 전송한다.

※ 유닉스용 전자우편 프로그램으로는 mail, mailx, elm, pine(외부에디터 사용)등이 있으며, 윈도우에서는 넷스케이프 mail 메신저, 익스플로러의 아웃룩 익스프레스, eudora 등이 있다.

2. 메일 데몬은 종단간 client의 주소를 분석하고 가장 가까운 mail server(송신자 소속의 메일서버)로 메시지와 정보를 보낸다.

※ mail deamon이란 일종의 프로세스로서, 송신자의 메일과 정보를 메일 서버가 해석 가능하도록 재가공한다.  반대의 경우 또한 같은 방법으로 수신자의 정확한 메시지 수신과 릴레이를 지원한다.
참고적으로, UNIX 기반의 대표적인 SMTP mail deamon으로는 [send mail]이 있으며, 앞으로 랩의 홈페이지에 unix/linux 카테고리가 생기게 된다면 sendmail의 사용에 대한 강좌도 준비하도록 하겠다.

3. 송신자가 보낸 편지가 일단 송신자 측의 전자우편을 관리하는 Mail Server에 전달되면,  Mail Server는 수신자의 전자우편 주소를 분석해서 최단 경로를 찾아 근접한 Mail Server에 편지를 전달하게 된다.

4. 최종 수신자측의 Mail Server에 도착하기까지 연속적으로 전달하는 중계작업이 계속된다.

서로 근접한 Mail Server들 간에 전자우편을 계속해서 중계해 나가는 방법을 통해 메일을 저장 후 전송 (Store-and-forward)하는 서비스를 하게 된다.

5. 이러한 일련의 작업이 계속적으로 이루어 진후, 송수신자는 정확하게 메일 교환을 할 수 있게 된다.

 

 전자 우편의 주소 체계와 전송

zenome@email.com

email은 '@'을 구분자로 왼쪽에는 소속된 서버에서 부여받은 ID와 오른쪽에는 소속 서버의 주소의 주소를 사용하게 된다.

전자우편의 구성은 주소와 날짜, 메일의 제목인 주제를 포함하고 있는 메일 헤더와 메일의 내용이 포함되어 있는 메일 본체로 구성되어 있다.

인터넷 전자우편은 7비트 아스키 문자를 전송하는 것을 표준으로 하고 있어 한글로 작성된 메일은 변환코드로 인해 "내용을 알아볼 수 없는 문제가 발생할 수 있다.

이진파일은 인코딩을 통해 텍스트로 변환한 후 발송해야 하지만 요즘은 MIME 방식을 이용해 전자우편에 첨부하여 발송하는 기법을 사용하고 있다.

※ "email.com"은 cnn이 운영하는 실제의 mail 서비스 업체의 주소이다. 여러분의 이해를 돕기 위해 사용했을 뿐이다. 하지만 위의 주소는 필자의 이메일 주소이므로.. 여러분의 문의사항을 보내도 좋겠다.
다만 한글의 경우 글씨가 깨지는 경우가 많으므로 주의하여야 한다.

 

 

■ SMTP와 POP3

Θ SMTP (Simple Mail Transfer Protocol)

일반적으로 메일을 송신할 때 사용되어진다고 볼 수 있다.
SMTP와 관련된 프로토콜에 대한 표준은 STD와 RFC에서 정해진 것이다. 서버에서 서버로의 프로토콜이며 이외의 다른 여러 프로토콜은 메시지를 접속하기 위해서 사용한다. STMP와 관련된 프로토콜을 살펴보면 다음과 같다.

① STD 10/RFC 821:두 컴퓨터 사이의 메일 교환 표준을 정의하며 SMTP 자체에 관한 표준으로 TCP/IP 호스트 사이에서 메일을 전달하는데 사용된다.

② STD 11/RFC 822, RFC1049:RFC 822와 RFC 1049에 포함된 메일 메시지의 형식에 관한 표준을 정의하며 공식적인 프로토콜명은 MAIL이다. RFC822는 메일 헤더 필드의 의미를 기술하고 헤더 필드 집합과 그에 대한 해석을 정의한다. RFC 1049는 평문 아스키 이외의 문서 형식들이 메일 본문에서 어떻게 사용될 수 있는지에 대해 기술하고 있다.

③ RFC 974:DNS(domain name system)을 이용한 메일 경로 배정에 관한 표준을 정의하고 있으며 공식 프로토콜명은 DNS-MX이다.

STD 10/RFC 821에서는 SMTP를 통해 전달되는 데이터는 상위 비트가 0으로 설정된 7비트 아스키 데이터라고 기술하고 있다. 이는 영문텍스트 메시지를 전송하는데는 적합하지만, 비영어권 데이터 또는 비 텍스트 데이터에 대해서는 부적합하다. 이러한 제약을 극복하기 위해 다음과 같은 접근 방식이 사용된다.

① MIME(multipurpose internet mail extension):RFC 2045부터 RFC 2049에서는 텍스트와 2진 데이터를 RFC 822에서 정의한 7비트 아스키로 코드화하는 메카니즘을 명시한다.

② SMTP Service Extensions:RFC 821에서 정의한 SMTP의 기능을 확장하는 메커니즘을 RFC 1869, RFC 1652, 1870에서 각각 정의하고 있다.

 

Θ POP (Post Office Protocol)

 인터넷 메일 클라이언트가 메일 서버로부터 메일을 꺼내기 위한 규약으로서 인터넷에서 사실상 표준이 되어 있다. 말그대로 메일의 수신을 위한 프로토콜이다. SMTP가 우체부라면 POP은 우체국이라고 생각하면 쉽다. 전자우편의 헤더와 본문 모두를 사용자의 컴퓨터로 다운로드한다. 이프로토콜은 TCP 세션의 109번 포트를 쓰는데 같은 포트를 쓰면서 조금 진보한 POP2가 있고 최근 많이 사용되는 POP3는 110번 포트를 사용한다.

 

※ 참고, protocol이 사용하는 일반적 port

HTTP  :    80 port
FTP    :    21 port
POP3 :  110 port
SMTP :    25 port
IMAP  :   43 port

 

■ 일반적 mail server 환경(UNIX-send mail)에서의 mail 송수신 과정

Sendmail이 설치된 메일서버는 SMTP(Simple Mail Transfer Protocol) 프로토콜을 사용하여 메일을 전송하고, 호스트로부터 받은 메일을 클라이언트로 전달할 때는 POP3 또는 IMAP등의 프로토콜을 사용합니다.

일반적으로 대부분의 사람들이 E-Mail을 보내기 위하여 PC상의 MUA(Mail User Agent : Outlook, Netscape Messanger등)를 사용하게 됩니다. 개인 PC에는 메일 송수신 기능(즉, MTA 기능)이 없기 때문에 인터넷에 연결되어있는 UNIX기반의 메일서버를 이용합니다. 혹은 NT의 Mail exchange서버를 사용하기도 합니다.

abc@abc.com를 메일주소로 가진 사람이 def@def.com을 메일주소로 가지고 있는 사람에게 E-mail을 보내는 과정을 예로 설명하겠습니다.

① 메일서버로 abc@abc.com을 사용하는 abc은  def@def.com에게 편지를 보내기 위해 MUA로 작성된 편지를 SMTP(port 25)를 이용하여 발송한다.

②메일서버의 25번포트에서는 sendmail이 Demon으로 실행되어져 있다가 outlook express가 보내고자 하는 메일을 받는다.

③메일을 받은 sendmail은 메일의 도착지가 자신인지를 확인한다. 만일 도착지가 자신이 아니라면 도착지로 메일을 다시 전송합니다. 자신이 메일의 도착지라면 메일을 MDA(Mail Delivery Agent)에게 넘겨줍니다. MDA(메일을 MTA로부터 받아서 메일박스등에 저장하거나 원하는 필터링을 할 수 있는 프로그램)는 필터링 과정을 거친 후 사용자의 메일박스에 저장한다.

④ def.com 자신이 도착지가 아니라면 MTA는 메일을 def.com의 25포트를 통하여 MTA에게 넘겨주며 def.com의 MTA에 접속할 수 없다면 email.com의 메일 스풀에 저장되어 주기적으로 def.com 시스템의 MTA와 접속을 시도하여 접속이 이루어지면 메일을 전송하고 자신의 스풀에 저장된 메일을 삭제하며 지정된 시간이 지나도 보낼 수 없다면 메일을 전송한 사람에게 메일을 보낼 수 없다고 되돌려 줍니다.

⑤ 편지를 넘겨받은 def.com의 MTA는 User의 존재유무를 확인하여 전달하며 유저가 존재하지 않을 경우 다시 편지를 처음 전송한 사람에게 되돌려 줍니다. 수신인의 hanmail.net 에 존재할 경우 MDA 프로그램에 메일을 넘겨주며 MDA는 적절한 필터링을 거쳐 각 사용자의 메일 박스에 저장됩니다.

 

⑥ 편지 수신자인 uhkim@hanmail.net의 사용자는 유닉스용 MUA인 mutt,pine,elm과 같은 프로그램으로 편지를 받아보며, pc 용 MUA인 microsoft outlook, Netscape messenger, Eudora를 이용하여 IMAP 혹은 POP3프로토콜을 이용하여 hanmai.net에 접근하여 편지를 가져와 읽을 수 있습니다.

이상에서 보듯이 sendmail은 MTA의 역활을 합니다. 사용자로부터 메일을 전달받아 다른 컴퓨터의 MTA에게 넘겨주고, 다른 MTA로 부터 받은 메일을 MDA에게 넘겨주는 인터넷 전자메일의 가장 중심부에 위치하고 있습니다. 현재 UNIX기반 메일서버의 거의 대부분이 MTA로 sendmail을 쓰고 있습니다.


 

■ MUA & MTA

사용자가 직접 접하게 되는 것은 우편 대행자(MUA:mail user agent)이다. 이 도구는 여러 가지가 있는데 우선 표준 유닉스 도구는 mail이다.

  이 mail은 크게 두 가지로 발전되었는데 그 하나가 BSD(Berkely Software Distribution)에서 개발된 mailx이고 또 하나는 시스템Ⅴ 유닉스(System Ⅴ Unix)에서 개발된 Mail이다. 이 두 도구는 대개의 표준 유닉스 시스템에 기본적으로 탑재되어 있다.  이 외로 Elm, MH, Rmail, Mush 등 여러 가지가 있는데 모두 나름대로의 특징을 가지고 있다.

지금까지 언급된 것은 주로 유닉스 하의 TCP/IP 중 일부인 SMTP로써 유닉스 기반하에서 동작하는 것들이다. 어떤 랜에 연결된 PC는 정해진 Host에 연결해 메일 작업을 할 수도 있지만 직접 PC에 도구를 설치해 운용할 수도 있게 된다. 이와 같이 PC에서 동작하는 메일 프로토콜 중 하나가 POP(Post Office Protocol)이며 이는 SMTP보다 사용하기에 편리한 점이 많다. 이 POP 기반하에 동작되는 것 중 많이 사용하는 도구가 유도라(Eudora)이다.

...by zenome


:::www.zenome.org:::


SMTP (Simple Mail Transfer Protocol) ; 단순 우편전송 규약

SMTP[에셈티피]는 전자우편을 보내고 받는데 사용되는 TCP/IP 프로토콜이다. 그러나, 수신 측에서의 큐 메시지능력의 제한으로 인해, 대개 수신을 위해서는 POP3나 IMAP 중의 하나의 프로토콜을 쓰는 것이 보통이며, 이러한 프로토콜은 서버에 각자의 우편함을 두고 사용자 메시지를 저장한 다음, 주기적으로 서버에 접속하여 편지를 다운로드 하는 식으로 운영된다. 다른 말로 설명하면, 사용자들은 SMTP를 메일을 보내는데 주로 사용하며, POP3나 IMAP 프로토콜은 자신의 서버에 수신되어 있는 메시지를 받아보는데 사용한다는 말이다. 유도라와 같은 대부분의 메일 프로그램은 SMTP 서버와 POP 서버를 모두 설정할 수 있도록 허용한다. 유닉스 기반의 시스템에서 sendmail은 전자우편용으로 가장 광범위하게 사용되는 SMTP 서버이다. 상용 패키지인 Sendmail에는POP3 서버가 포함되어 있으며, 윈도우NT 버전도 나온다.

SMTP는 대개 TCP 25번 포트에서 운영되도록 만들어진다. SMTP의 자세한 내용은 IETF의 RFC 821에 정의되어 있다. SMTP의 대안으로 유럽지역에서 광범위하게 사용되는 것으로 X.400이 있다.



POP3 (Post Office Protocol 3)

POP3[팝 쓰리]는 전자우편을 수신하기 위한 표준 프로토콜로서 가장 최신 버전이다. POP3는 인터넷 서버가 사용자를 위해 전자우편을 수신하고 그 내용을 보관하기 위해 사용되는 클라이언트/서버 프로토콜이다. 사용자(또는 전자우편 수신용 클라이언트 프로그램)는 주기적으로 서버에 있는 자신의 메일 수신함을 점검하고, 만약 수신된 메일이 있으면 클라이언트 쪽으로 다운로드 한다. POP3는 가장 유명한 전자우편 제품 중의 하나인 유도라에 적용되었으며, 넷스케이프와 마이크로소프트 익스플로러 브라우저에도 역시 적용되었다.

POP3의 대안으로 사용할 수 있는 프로토콜이 IMAP이다. IMAP으로는 사용자는 설령 자신의 클라이언트 컴퓨터에 메일이 있다고 해도, 서버에 있는 메일을 본다. 자신의 컴퓨터에서 지워진 메일도 서버에는 아직 남아있다. 메일은 서버에 보관될 수 있고 검색될 수 있다.

POP3는 '보관하고 전달하는' 서비스라고 생각할 수 있으며, IMAP은 원격지 파일서버라고 생각할 수 있다.

POP과 IMAP은 둘 모두 전자우편을 받는 일을 담당하므로, 인터넷을 통해 전자우편을 전달하는 프로토콜인 SMTP와 혼동해서는 안된다. 송신자가 SMTP를 이용해서 메일을 보내면, 상대방 메일서버에 있는 메일처리기가 수신자를 대신해서 그것을 수신한다. 그리고 난 뒤 그 메일을 POP이나 IMAP을 이용하여 수신자가 읽게 되는 것이다.




IMAP (Internet Message Access Protocol)

IMAP[아이맵]은 로컬서버에서 전자우편을 액세스하기 위한 표준 프로토콜이다. IMAP은 인터넷 서버를 이용하여 전자우편을 수신하고 보관하는 클라이언트/서버형 프로토콜이다. 사용자 (또는 사용자의 전자우편 클라이언트 프로그램)는 편지의 제목과 송신자를 보고, 메일을 실제로 다운로드할 것인지를 결정할 수 있다. 사용자는 서버에 폴더나 우편함을 만들거나 관리할 수 있으며, 메시지를 지우거나 메시지의 일부 또는 전체의 내용에 대해 검색을 수행할 수 있다. IMAP은 사용자의 메일을 송수신하기 위해 업무시간 중에 지속적으로 서버에 액세스해야한다.

좀더 덜 복잡한 프로토콜이 POP3이다. POP3를 이용하면 사용자 메일이 서버에 있는 우편함에 저장된다. 사용자가 메일을 읽을 때 즉시 사용자의 컴퓨터로 다운로드되며, 서버에는 더 이상 남아있지 않게 된다.

IMAP은 원격 파일서버라고 생각할 수 있으며, POP은 "저장 및 전달"서비스를 수행한다고 생각할 수 있다.

POP과 IMAP은 전자우편의 수신을 담당하므로, 인터넷상의 각 지점으로 전자우편을 전송하는 프로토콜인 SMTP와 혼동하지 말아야한다. 송신측에서 SMTP를 이용하여 메일을 보내면, 상대방의 메일관리자는 수신인을 대신해서 그 메일을 받아놓는다. 그후 수신인은 그 메일을 POP이나 IMAP을 이용하여 읽을 수 있게된다.


'OS > 리눅스 & 유닉스' 카테고리의 다른 글

SVN 서버 설정  (0) 2014.11.03
방화벽 오픈/해제  (0) 2014.11.03
큐메일  (0) 2014.09.18
리눅스 명령어 모음  (0) 2012.07.05
POSIX Semaphore & System V Semaphore  (0) 2012.06.01
:

큐메일

OS/리눅스 & 유닉스 2014. 9. 18. 16:06


D. J. Bernstein 
Internet mail

qmail

이 페이지는 qmail의 저자인 D. J. Bernstein의 qmail 페이지를 번역한 것입니다.

FAQ (자주 질문되어 지는것들) - [번역됨]
qmail의 안전성 보장
대형 sendmail 사이트에서 qmail로의 이전 - [번역됨]
mini-qmail 설치하기 - [번역됨]
POP 토스터 만들기 - [번역됨]
qmail 구조도 - [번역됨]

누가 qmail을 이용하는가? - [번역됨]
최근의 버전에서 바뀐 것들
qmail의 미래 - [번역됨]

미리 컴파일된 바이너리 패키지에 대해
배포자를 위한 안내


qmail은 메일링 리스트에서 논의되고 있다. 새로운 버전 공지는 qmail 알림 메일링 리스트에서 받아볼수 있다.

현재 qmail의 마지막 버전은 qmail-1.03.tar.gz 이며 다음에서 받을 수 있다.

관련 패키지:

  • djbdns, qmail과 사용하기를 권장하는 DNS 소프트웨어;
  • ezmlm, 사용하기 쉽고, 빠른 메일링 리스트 관리 도구;
  • ucspi-tcp, SMTP 서버를 위한 매우 빠른 inetd의 대체 프로그램과 RBL-목록 사이트를 사용해 스팸 메일 거부에 이용할 수 있는 도구가 포함되어 있다;
  • serialmail, 시리얼 연결을 통해 메일을 전달하는 도구들 (AutoTURN을 지원함);
  • qmailanalog, qmail의 로그를 분석할 수 있는 로그 분석기;
  • dot-forward, qmail을 위한 .forward 지원;
  • fastforward, qmail을 위한 테이블 기반의 포워딩 도구, /etc/aliases 를 지원;
  • mess822, SMTP 클라이언트를 위해 메세지를 재작성 하거나 헤더 분석기등을 포함하는 도구;
  • patch majordomo 1.93 과 qmail이 작동하기 위한 패치
  • the checkpassword qmail-pop3d 를 위한 인증 프로그램.

qmail 관련 유틸리티, 패치, 상업 지원등 많은 정보를 www.qmail.org (한글)에서 찾을 수 있다.

Dave Sill의 The qmail handbook.

qmail이 무엇인가?

qmail은 안전하며 신뢰할 수 있고, 효율적인 메세지 전송 에이전트이다.

이것은 sendmail-binmail 시스템을 대체할 수 있다는 의미이다.

안전성: 보안이 목적이 될 수는 없지만 절대적으로 필요한 것이다. 메일 전송은 사용자에게는 매우 중요한것이며 전송되어야만 하며, 완벽하게 안전해야 한다. (이것이 qmail이 만들어진 동기로 정기적으로 알려지곤 하는 센드메일이나 다른 MTA의 보안 구멍때문에 지쳤기 때문이었다.)

신뢰성: 큐메일은 메세지를 절대 잃어버리는 일이 없다. 큐메일은 NFS 파일 시스템상에서도 안전한 Maildir 형태 메일함의 선구자이다. Maildir 형태는 큐메일에서 처음으로 사용하기 시작한 메일함 형식으로 배달이 이루어 지고 있는 동안에 시스템이 다운되더라도 파일 시스템에 문제가 생기지 않는 유일한 메일함이며, NFS 파일 시스템상에서 동시에 여러개의 메일이 배달되고 있는 동안에도 사용자가 메일을 읽을 수 있는 안전한 메일함이다.

효율성: 펜티엄시스템, BSD 운영체제하에서 qmail은 하루에 20만개의 로컬 메세지를 손쉽게 처리할 수 있다. --- 분리된 메세지를 주입하고 메일 박스로 배달하는 실제 테스트였다. 큐메일은 메세지를 센드메일보다 빠르게 처리하면서 안정성을 잃지 않는다. 특히 수 많은 메일을 동시에 배달해야 하는 메일링 리스트의 경우 가장 빠른 성능을 보인다. 예를 들어 1000개 이상의 각기 다른 호스트에 메일을 배달하는데 76초 밖에 걸리지 않았다.

간단함:

  1. 포워딩, 알리아싱, 메일링 리스트 메카니즘을 독립적으로 가지고 있는 다른 MTA들과는 다르게 큐메일은 한가지의 간단한 포워딩 메카니즘을 사용해 모든 기능을 구현하였다.
  2. 다른 MTA가 "빠르고 불안전한 -> 느린 큐" 방식의 배달 방식을 사용하는것 과는 달리 큐메일은 새로운 아이템을 즉시 큐에 넣으므로 큐메일은 "빠른 큐"라는 하나의 배달 방식만을 사용한다.

sendmail을 대체: qmail은 host, 유저 마스커레이딩과 완벽한 호스트 숨김, 가상 도메인, null 클라이언트, list-owner rewriting, 릴레이 조절, 더블 바운스 기록, RFC 822를 따르는 주소 목록, 호스트 간의 메일링 루프 (loop) 인식, 수신자 단위의 체크 포인팅, 다운된 호스트를 위한 보류기능, 스케쥴에 따른 메세지 재전송 기능등을 지원한다. 또한 qmail은 기존의 어플리케이션들과의 호환을 위해 sendmail 바이너리를 대체하는 wrapper를 가지고 있다.

왜 당신은 qmail하에서의 메일링 리스트를 좋아하게 될 것인가?

메일링 리스트의 관리는 qmail의 큰 장점중의 하나이다.

  • qmail은 각 사용자가 자신만의 메일링 리스트를 관리 할 수 있다. 배달 명령은 ~user/.qmail-whatever을 따르게 된다.
  • qmail에서는 메일링 리스트 소유자 설정을 매우 쉽게 할 수 있다. 만약 ~user/.qmail-whatever-owner를 만들어 주면 모든 바운스는 그에게 배달된다.
  • qmail에서는 어떠한 크기의 메일링 리스트에서도 완벽히 신뢰되는 바운스 처리가 가능한 VERP를 지원한다.
  • 속도--qmail은 sendmail 보다 상당히 빠르게 메일링 리스트를 처리한다. 예를 들면 qmail 메일링 리스트상에서 각각의 메세지를 단지 76초 동안에 서로 다른 1000개의 호스트에 배달한다.
  • qmail은 자동적으로 메일링 리스트의 루프(loop)를 막아준다.
  • qmail은 믿지 못 할 정도의 거대한 메일링 리스트를 지원한다.
  • qmail은 알리어싱과 포워딩을 간단하고 동일한 매커니즘으로 지원한다. 예를 들어 postmaster는 ~alias/.qmail-postmaster에 의해 제어된다. 이것은 알리아스에 대한 크로스-호스트 루프(cross-host loop) 또한 인식한다는 의미이다.
  • qmail은 메일링 리스트 관리기인 ezmlm을 지원한다. ezmlm은 바운스, 가입 요청, 아카이브등을 쉽고 자동적으로 처리한다.

효율성

qmail의 모듈러 (작은 여러개의 프로그램으로 이루어짐), 작은 디자인과 현명한 큐 관리는 qmail을 가장 빠른 MTA를 만들어 주었다. 다른 MTA들과의 다음 다섯가지 차이점으로 속도의 차이를 알 수 있다.

  • 스케쥴링: 8192개 메세지를 나의 집에 있는 컴퓨터에서 보내 보았다. 모든 메세지들은 단지 78초에 배달되었다. -- 이것은 하루에 9백만개의 편지를 전달할수 있다는것을 의미한다! 하루에 백십만개를 전송 할 수 있는 속도가 빠르다고 광고하는 Zmailer와 비교해보라. (Zmailer의 이 수치는 스팍스테이션 10/50MHz 에서 하루에 전송한 량이다. 나의 집의 컴퓨터는 16MB 100MHz 펜티엄에 BSD/OS에 qmail을 기본 설정으로 사용하였고, 로그는 accustamp를 통해 디스크에 일반적으로 저장되었다).
  • 로컬메일링 리스트: qmail은 메일함에 메세지를 전달할때, 물리적으로 메세지를 디스크에 쓴 후에 그것이 성공적으로 배달되었음을 알린다. -- 이 방식은 전원을 잃었다 하더라도 메일의 손실이 없다. 나는 1024개의 메세지를 내 컴퓨터의 동일한 디스크 상의 로컬 메일박스에 전송해 보았는데 모든 전송은 25.5 초에 끝났다. 이것은 하루에 3백 4십만통 이상의 전송을 수행 할 수 있는 속도이다! Zmailer은 스팍 스테이션에서 겨우 4십 8만통의 전송 속도를 보여 주었을 뿐이다.
  • 메일링 리스트와 원격 수신: qmail은 LSOFT의 LSMTP와 동일한 배달 전략을 사용한다. 즉, 매우 빠르게 외부로 메일을 전송한다. 여러분은 동시 SMTP 접속수를 선택할 수 있다. 물론 실행속도는 얼마나 수신자가 많은가에 따른다. qmail의 장점은 다른 패키지에 비하여 크기가 작다는 것이다. 예를 들어 16M 메모리를 가지는 리눅스 박스에서 스왑을 사용하지 않고도 60개의 동시 접속을 유지할 수 있다.
  • 로컬메세지 분리: LSOFT가 LSMTP에 대해 말해주지 않은것은 얼마나 많은 분리된 메세지를 하루에 처리할 수 있는가이다. 큐에 가득차면 지연 현상이 있지 않을까? 내 컴퓨터에서 qmail의 배달을 정지시켜놓고 5000개의 분리된 메세지를 하나의 수신자에게 보내 보았다. 모든 메세지는 23분에 동안 속도 저하없이 안전하게 큐 디스크에 저장되었다. 다시 qmail의 배달을 시작하자 12분만에 수신자의 메일함에 모든 메세지가 배달되었다. 이것은 하루에 20만통이상을 처리할 수 있는 속도이다.
  • 전반적인 성능: 실제적인 예로 레드헷 소프트웨어는 그들의 메일 허브인 펜티엄/48MB, sendmail 8.7 운영 환경에서 하루에 7만개의 메세지를 전송하였다. 후에 이것을 더 작은 시스템인 486/66MHz, 16MB, qmail로 바꾸었으며 잘 작동하고 있다.

특징

설정:

  • 여러분의 UNIX에 자동적으로 적응한다 -- 포팅이 불필요 하다.
  • AIX, BSD/OS, FreeBSD, HP/UX, Irix, Linux, OSF/1, SunOS, Solaris등을 포팅없이 지원한다.
  • 자동적인 호스트별 설정(config, config-fast)
  • 빠른 설치

보안:

  • 주소, 파일, 프로그램은 명확하게 구분되어 있다.
  • setuid code (qmail-queue)의 최소화
  • root code (qmail-start, qmail-lspawn)의 최소화
  • 다섯가지 방법의 확실한 분활 -- 보안의 계층화
  • 선택적인 로그 (단 방항의 해쉬, 모든 내용, 기타. (QUEUE_EXTRA)

메세지 구조(qmail-inject):

  • RFC 822, RFC 1123
  • 주소 그룹을 완벽하게 지원
  • RFC 822 형태로 자동 구식 주소 변환 지원
  • 이전 사용자들을 위한 sendmail wrapper 지원
  • 메모리에 의해서만 제한되는 헤더의 길이
  • 호스트 매스커레이딩 (control/defaulthost)
  • 사용자 매스커레이딩 ($MAILUSER, $MAILHOST)
  • Mail-Followup-To 헤더 자동 생성 ($QMAILMFTFILE)

SMTP 서비스 (qmail-smtpd):

  • RFC 821, RFC 1123, RFC 1651, RFC 1652, RFC 1854
  • 8-bit clean
  • 931/1413/ident/TAP callback (tcp-env)
  • 릴레이 제어 --- 인증되지 않은 외부 사용자의 릴레이 방지 (control/rcpthosts)
  • 릴레이와 알리아스간의 간섭 없음
  • 로컬 IP 주소 자동 인식
  • 버퍼별 타임아웃 지원
  • 홉 카운팅 (hop counting)
  • 병렬 처리 제한 (ucspi-tcp/tcpserver, available separately)
  • 알려진 스팸 서버로 부터의 연결 거부 (tcpserver)
  • 인증된 클라이언트를 위한 릴레이와 메세지 재작성
  • 선택적인 RBL/ORBS 사용 가능 (ucspi-tcp/rblsmtpd)

큐 관리(qmail-send):

  • 메세지를 즉시 큐에 추가
  • 병렬 처리 제어 (control/concurrencyremote, control/concurrencylocal)
  • 큐 디렉토리의 분리 -- 큐가 커질때의 속도 제하가 없음
  • 2차원의 재시도 스케줄 -- 오래된 메세지일 수도록 재시도를 자주 하지 않음
  • 독립적인 메세지 재시도 스케쥴
  • 자동적이고 안전한 큐잉(queueing) -- 만일 시스템이 비정상적이어도 메일을 잃지 않음
  • 자동 수신자별 체크 포인팅
  • 자동 큐 청소 (qmail-clean)
  • 큐 보기 (qmail-qread)
  • 자세한 전송 통계 (qmailanalog)

바운스 (qmail-send):

  • QSBMF 바운스 메세지 --- machine-readable 과 human-readable
  • HCMSSC 지원 --- RFC 1893 오류 코드에서 독립적임
  • 더블 바운스는 postmaster에게 보내짐

도메인별 라우팅(qmail-send):

  • 복수의 로컬 호스트 이름 지원 (control/locals)
  • 복수의 가상 도메인 지원 (control/virtualdomains)
  • 도메인 와일드 카드 지원 (control/virtualdomains)
  • 설정이 가능한 percent hack 지원 (control/percenthack)
  • UUCP hook

SMTP 전송 (qmail-remote):

  • RFC 821, RFC 974, RFC 1123
  • 8-bit clean
  • 다운된 호스트를 위한 배달 지연
  • 지능적인 라우팅 -- smarthost, localnet, mailertable (control/smtproutes)
  • 버퍼별 타임아웃
  • 수동 SMTP 큐 -- SLIP/PPP를 위해 완벽함 (serialmail)
  • AutoTURN 지원 (serialmail)

포워딩과 메일링 리스트 (qmail-local):

  • sendmail의 .forward 와 호환 (dot-forward)
  • hashed forwarding databases (fastforward)
  • sendmail의 /etc/aliases 와 호환 (fastforward/newaliases)
  • 주소의 와일드 카드 지원 (.qmail-default, .qmail-foo-default, 등.)
  • 소유자를 위한 메일링 리스트 --- 자동으로 바운스를 전환하고 휴가 메세지 전송
  • VERPs--- 메일링 리스트 바운스를 위한 자동적인 수신자 인식
  • Delivered-To---메일 루프 방지
  • 자동 가입 요청 관리 (ezmlm)

로컬 전송 (qmail-local):

  • 이용자가 제어하는 주소 계층
  • mbox 배달
  • 신뢰되는 NFS 배달 (maildir)
  • 이용자가 제어하는 전송 프로그램 : procmail 등 (qmail-command)
  • 선택적인 새 메일 알림 (qbiff)
  • 선택적인 NRUDT 지원 (qreceipt)
  • 선택적인 필터링 (condredirect, bouncesaying)

POP3 서비스 (qmail-popup, qmail-pop3d):

  • RFC 1939
  • UIDL 지원
  • TOP 지원
  • APOP 후크
  • 분리된 암호 인증 프로그램 (checkpassword)

참조 - http://qmail.kldp.net/phpbb/

       - http://qmail.kldp.net/qmail.html

:

리눅스 명령어 모음

OS/리눅스 & 유닉스 2012. 7. 5. 11:07

addbib  -  도서목록 형식의 데이터베이스를 만들거나, 확장
apropos  - 사용설명서의 키워드 검색
ar       -  라이브러리 만들기, 관리
at, batch - 원하는 시간에 원하는 명령을 실해하게 하는 명령
awk     - 패턴 검색과 언어 처리
banner   - 큰 글자(배너) 만들기
basename - 경로 이름에서 마지막에 있는 이름만 출력
biff     - 자신에게 편지가 배달되면 알려주는 명령
bin-mail, binmail - 예전에 사용한 전자우편 프로그램
cal     - 달력보기
calendar - 간단한 일정표
cat    - 파일 병합과 내용 보기
cb     - 간단한 C 프로그램 beautifier(?)
cc     - C 컴파일러
cd    - 작업 디렉토리 바꾸기
checknr - nroff 또는 troff 입력 파일 검사; 오류를 보여준다
chgrp  - 파일의 사용자 그룹 바꾸기
chmod - 파일의 접근 권한 바꾸기
clear  - 터미날 화면 깨끗이 하기
cmp   - 두 파일을 바이트 단위로 비교
colcrt  - troff 파일의 밑줄 속성 문자 처리
comm  - 지정 두파일의 줄 단위 비교와 그 처리
compress, uncompress, zcat - 파일 압축관련 유틸리티들
cp     - 파일 복사
cpio   - copy file archives in and out
cpp    - C 언어 전처리기
csh    - C 문법과 비슷한 쉘 스크립트 문법과 기타 여러 기능이 내장된 쉘
ctags  - ex 나 vi 편집기에서 사용될 tag 파일을 만드는 명령
date    - 시스템 시간 보기나 지정하기
dbx    - 소스 수준의 디버거
deroff  - nroff, troff, tbl, eqn 관련 내용 지움
df     - disk free: 디스크의 남은 용량 보기
diff    - 두 파일의 차이점 비교
du     - disk used : 디스크 사용량 보기
echo   - 인자를 표준 출력으로 출력
ed, red - 기본 줄 편집기
eqn, neqn, checkeq - 수식 표현 포멧 도구
error   - 컴파일러 오류 메시지 목록
ex, edit, e - 줄 편집기
expand, unexpand - TAB 문자를 공백문자로 바꿈, 또는 그 반대로
expr    - 인자를 수식으로 처리
file     - 파일 형식 알아보기
find    - 파일 찾기
finger   - 사용자 정보 알아보기
fmt, fmt_mail - 간단한 문서나, 편지 포멧 도구
fold    - 긴 줄 출력 방법 지정
ftp     - 파일 전송 프로그램
gcore   - 실행 중인 프로세스의 core 이미지를 구한다.
gprof   - call-graph profile data(?)를 보여줌
grep   - 문자열 찾기
groups - 사용자의 그룹을 보여줌
history - 이전 명령 보기
hostname - 현재 시스템 이름을 보여줌
imake   - makefile 만드는 프로그램
indent  - C 프로그램 소스 파일을 들여쓰기 하는 포멧 도구
install  - 파일 설치
join    - 관계형 데이터베이스 연산자
kill     - 프로세스  stop :-)
last     - 사용자가 마지막 접속 상태를 보여줌
ld, ld.so - 링크 편집기, 동적 링크 편집기
leave    - 자신의 접속 종료 시간을 알려줌
less     - more 명령의 확장
lex     - 어휘 분석 프로그램 생성기
lint     - C 프로그램 verifier
ln      - 파일의 하드, 심벌릭 링크 명령
login   - 시스템 접속 명령
look    - 시스템 디렉토리나, 정열된 목록에서 단어 찾기
lookbib - 도서목록형 데이타베이스에서 찾기
lorder  - 오브젝트 라이브러리의 관계 찾기
lp, cancel - 인쇄 시작, 취소
lpq     - 인쇄 작업 상황 보기
lpr     - 인쇄
lprm   - 인쇄 작업 지우기
ls      - 디렉토리 내용 보기
mail, Mail - 전자 우편 프로그램
make   - 실행 파일을 만들거나, 특정 작업 파일을 만들 때 사용하는 도구
man    - 온라인 사용자 설명서를 보는 명령
mesg   - 메시지 수신 상태를 보거나 지정
mkdir   - 디렉토리 만들기
mkstr   - C 소스 파일을 참조로 오류 메시지 파일을 만듬.
more, page - 텍스트 파일 보기 명령
mv     - 파일 이동이나, 이름 바꾸기
nawk   - 패턴 검색과 언어 처리
nice    - 낮은 우선권에서 명령 실행
nm     -  심블 이름 목록 보기
nroff   - 문서 포멧 도구
od     - 8진수, 10진수, 16진수, ascii 덤프
passwd, chfn, chsh - 비밀번호, 핑거정보, 쉘 바꾸기
paste   - 여러파일의 서로 관련 있는 줄 연결시키기
pr      - 문서 파일 양식화 도구
printenv - 현재 환경 변수들의 내용과 그 값 알아보기
prof     - profile 자료 보기
ps      - 현재 프로세스 정보 보기
ptx     - permuted(순열화된?, 교환된?) 색인 만들기
pwd     - 현재 작업 디렉토리 보기
quota   - 한 사용자에게 지정된 디스크 할당량보기
ranlib   - archive를 random 라이브러리로 변화
rcp     - 리모트 카피
rcs     - RCS 파일 속성 바꾸기
rcsdiff  - RCS revisions 비교
rev     - 한 줄의 문자열 꺼꾸로
rlogin   - 리모트 로그인
rm, rmdir - 파일, 디렉토리 지우기
roffbib   - 도서목록형 데이터베이스 보기 또는 양식화
rsh     - 리모트 쉘
rup     - 로칼 머쉰의 호스트 상태 보기(RPC version)
ruptime - 로칼 머쉰의 호스트 상태 보기
rusers   - 현재 접속자 보기 (RPC version)
rwall   - 모든 사용자에게 알림(RPC)
rwho    - 현재 접속자 보기
sccs    - Source Code Control System (SCCS)
sccs-admin, admin   - SCCS 사용 내역 파일을 만들고, 관리
sccs-cdc, cdc        - SCCS 델타의 델파 주석을 바꿈
sccs-comb, comb    - SCCS 델타 조합
sccs-delta, delta     - SCCS 파일에 데해 델타를 만듬
sccs-get, get        - SCCS 파일 버전확인
sccs-help, help      - SCCS 오류나 경고 메시지 검색
sccs-prs, prs       - SCCS 사용내역의 선택된 부분 보기
sccs-prt, prt        - SCCS 파일에서 델타 테이블 정보를 봄
sccs-rmdel, rmdel   - SCCS 파일에서 델타를 지움
sccs-sact, sact      - SCCS 파일의 편집 상태를 봄
sccs-sccsdiff, sccsdiff - SCCS 파일들의 버전 비교
sccs-unget, unget   - SCCS 파일의 미리 얻은 것(?)을 취소한다.
sccs-val, val       - SCCS 파일 유요화
script     - 화면 갈무리
sed       - stream editor
sh        - 유닉스 표준 쉘
size       - 오브젝트 파일의 크기들을 보여줌
sleep     - 지정한 시간 만큼 실행 보류
sort      - 줄 정열과 검색
sortbib    - 도서목록형 데이터베이스 정열
spell, hashmake, spellin, hashcheck - 맞춤범 검사(물론 영어겠지요)
split      - 파일 나누기
strings   - 오브젝트 파일이나, 실행 파일에서 문자열 찾기
strip     - 오브젝트 파일에서 심벌 테이블과 중복된 비트 삭제
stty     - 터미날 설정
su      - super-user, 임시적으로 새 ID로 바꿈
symorder - 심벌 순서 바꿈
tabs    - 터미날 tab 크기 지정
tail     - 파일의 끝 부분 보기
talk    - 다른 사용자와 이야기하기
tar     - 여러 파일 묶기 또는 묶긴 파일 풀기
tbl     - nroff 또는 troff의 도표 작성 도구
tee      - 표준 출력으로 방향 전환
telnet   - TELNET 프로토콜을 이용한 원격 리모트 호스트 접속
test     - 주워진 환경이 참인지, 거짓인지를 돌려줌
tftp     - 간단한 ftp.
time     - 명령 실행 시간 계산
touch    - 파일 날짜 관련 부분을 바꿈
troff     - 문서 양식화 도구
true, false - 쉘 스크립트에서 사용되는 참/거짓을 리턴하는 명령
tsort    - topological sort
tty     - 현재 터미날 이름 보기
ue      - MICROemacs
ul      - 밑줄 속성 문자 표현
unifdef - cpp 입력 줄에서 ifdef 부분 바꾸거나 지움
uniq   - 중복되는 빈줄 지우기
units   - 프로그램 변환도구
uptime  - 시스템 부팅 기간 보기
users   - 현재 접속 사용자 보기
uucp, uulog, uuname - 시스템 간의 복사
uuencode, uudecode - 이진 파일을 아스키파일로 인코딩, 반대로 디코딩
uusend   - 리모트 호스트에 파일 보내기
uux     - 리모트 시스템 명령 실행
vacation  - 자동으로 편지 답장하기
vgrind   - grind nice program listings
vi, view, vedit - ex 바탕의 편집기
vtroff    - 문서 양식화 도구
w       - 현재 누가 접속해 있으며, 무엇을 하고있는지
wait     - 프로세스가 마치기를 기다림
wall      - 모든 사용자에게 알림
wc       - 단어, 줄, 바이트 계산
what    - 파일에서 SCCS 버전 정보 알아냄
whatis   - 명령의 간단한 설명 보여줌
whereis   - 찾는 명령의 실행파일, 소스, 맨페이지가 어디 있는지 경로를 보여 줌
which    - 명령만 찾음.
who     - 시스템에 접속되어 있는 사람만 보여줌
whoami - 현재 사용하고 있는 자신이 누군지 보여줌
write   - 다른 사용자의 화면에 특정 내용을 알림
xargs   - 명령행 인자 처리 명령
xstr    - extract strings from C programs to implement shared strings
yacc    - yet another compiler-compiler: 파싱(형태소분석) 프로그램 생성기
yes     - 항상 yes만 응답하는 명령
zcat     - 압축 파일 내용보기


[2]명령어 상세

adduser
루트로 로그인해서 이용자를 추가
$ adduser [ID]

admin
SCCS(Source code control system) 파일을 작성 또는 관리를 위한 명령어
$ admin [-nirtfdaemyhz] files
-n  : 신규 SCCS 화일을 작성
-i[name] : 신규 SCCS 화일에 등록된 화일명(name)
-f  : flag SCCS 화일에 등록하는 플래그들의 값을 지정
-r  : 번호 초기 델타의 릴리즈 번호 지정은 -i와 함께 사용
-t[name] : SCCS 화일의 주석문으로 등록되는 화일명(name)
-e  : login 델타 작성 가능한 사용자 리스트로 부터 삭제되는 로그인명
-h  : 신규 check sum을 계산하고 기존 check sum과 비교
-z  : check sum을 계산하여 SCCS 화일에 기록

alias
자주 쓰이는 명령어를 쓰기 편하게 바꾸는 명령
$ alias [새로만들 명령어]='[기존 명령어] [옵션]'

$ alias cp='cp -i'
$ alias la='ls $LS_OPTIONS -a'
$ alias less='less -rf'
$ alias lf='ls $LS_OPTIONS -F'
$ alias ll='ls $LS_OPTIONS -l'
$ alias ls='ls $LS_OPTIONS'
$ alias mv='mv -i'
$ alias rm='rm -i'
$ alias dir='ls -al

ar
아카이브 화일에 있는 화일의 그룹들을 유지 관리하는 명령어
$ ar [-X32_64] [-]{dmpqrstx}[abcfilNoPsSuvV] [member-name] [count] archive-file file...
$ ar -M [<mri-script]

d  : delete file(s) from the archive
m[ab] : move file(s) in the archive
p  : print file(s) found in the archive
q[f]  : quick append file(s) to the archive
r[ab][f][u] : replace existing or insert new file(s) into the archive
t  : display contents of archive
x[o]  : extract file(s) from the archive
command specific modifiers:
[a]  : put file(s) after [member-name]
[b]  : put file(s) before [member-name] (same as [i])
[N]  : use instance [count] of name
[f]  : truncate inserted file names
[P]  : use full path names when matching
[o]  : preserve original dates
[u]  : only replace files that are newer than current archive contents
generic modifiers:
[c]  : do not warn if the library had to be created
[s]  : create an archive index (cf. ranlib)
[S]  : do not build a symbol table
[v]  : be verbose
[V]  : display the version number
[-X32_64] : (ignored)

at
프로그램을 지금이 아닌 나중에 실행하도록 예약한다.
$ at [option]
-q 큐  : 대소문자 알파벳으로 큐를 지정한다. 순서적으로 빠른 알파벳이 지정된 큐 일수록 CPU 시간 점유 우선권이 낮다.
-r 작업번호 : 큐에서 작업 번호가 지시하는 작업을 지운다. 슈퍼유저가 아니라면 자신의 작업만을 지울 수 있다.
-l  : 현재 계획된 작업들의 목록을 보여준다. 슈퍼 유저라면 모든 작업들의 계획목록을 보여준다.
-m  : 작업이 완결되면 사용자에게 메일을 보낸다.
-f filename : 표준 입력이 아닌 지시된 파일에서 작업을 읽어온다.
  ps- 수행 시간 지정 명령어 -->at 11:30 pm

awk
program file에서 기술된 pattern들 중 일치되는 line 을 찾기 위해 입력 화일을 검색하는 명령어
$ awk [-Fc] [profile] [file] ...
$ awk [-Fc] [-f profile] [file] ...
-Fc  : 입력필드의 구분기호로서 c를 이용
-f  : progam file로서 다음 인수 사용

background : 하나의 명령을 수행시킨후 그 수행의 종료 이전에 다른 명령을 수행 하는 것
     명령어 끝에 &로 표시 (cc -o test1 test1.c &)

banner
인수로 주어진 문자열을 큰 글씨로 만들어서 출력
$ banner [ -w [숫자] ] 문자열
-w  : 옵션 지정만 하면 80 칼럼으로 폭을 바꾼다. 지정하지 않으면 132 칼럼으로 내정되어 있다. -w 옵션 뒤에 숫자를 지정하면 원하는 폭으로 조정할 수 있다.

bang
'!' 문자를 부르는 말로, C shell에서 '!!'를 명령어 라인에 입력하면, 마지막 명령을 반복하며, Bang!Bang!(뱅뱅)이라고 부른다.

bash
bash 셸이 아닌 사용자가 셸을 변경하고자 할 때 사용하는 명령입니다.
bash셸은 일반적으로 Linux의 기본 셸로 지정되어 있습니다.
만약 다른 셸을 사용하고 있으면서 bash 셸로 바꾸기 위한 명령은 다음과 같습니다.
# bash     (enter)'

bc
C Language와 유사한 대화식 번역기이며 무제한 정도의 연산을 제공하는 명령어
$ bc [-cl] [file ... ]
-c  : compile만 한다
-l  : 임의 정밀도의 수학 library명을 의미

bg %1( " ) : 포그라운드로 " " 백그라운드로 전환

biff
전자우편의 수신을 즉시 알려주는 동작을 가능하게 할 것인지 그렇지 않은 지의 여부를 보여주거나 결정
$ biff [ y 혹은 n]

닉스 셸은 사용중이라도 주기적으로 전자우편의 수신 여부를 점검한다. 만일 사용자가 전자우편이 도착하는 즉시 알고자 한다면
biff를 사용하여 그것을 지시할 수 있다. 또는 언제라도 그 기능을 해제할 수도 있다. biff는 인수없이 사용되면 현재 어떤
상태로 되어 있는지 보여준다. 기능 설정과 해제 여부는 y 혹은 n 인수를 주어서 결정한다.

bzip2
자료를 압축하기 위한 새로운 알고리즘이다. 보통은 gzip으로 한 것의 60-70%의 크기로 압축한다.
bzip2는 압축률과 복원률에서 탁월한 성능을 자랑하고 있다. 또한 UNIX 및 WIN32에서 모두 사용할 수 있으며 프로그램은 GNU을 따르므로 누구든지 사용할 수 있다.

cal
서기 원년부터 9999년까지의 달력을 볼 수 있다 .
$ cal [-jy] [ [ 달 ] 연도 ]
-j  : 1월 1일부터 날짜수를 계산하는 julian 날짜를 표시한다.
-y  : 올해의 달력을 표시한다.
      cal 9 1995 : unix 시스템에 내장되어있는 달력을 화면에 출력

cancel [print name] ; 프린터 취소

cat
파일의 내용을 표준 출력으로 내보내어, 파일내용을 알아보거나, 여러 파일을 하나의 파일로 출력하여 연결합니다. 또는 표준 입력으로부터 파일을 만들 수도 있습니다.
$ cat [option] file_name(s)
-b  : 공백 외의 글자가 있는 모든 행의 개수를 센다.
-e  : 제어 문자를 ^ 형태로 출력하면서, 각 행의 끝에 $를 추가한다. -vE와 같다.
-n  : 각 행을 출력하면서 행 번호를 함께 첨부한다.
-s  : 중복되고 겹치는 빈 행은 하나의 빈 행으로 처리한다.
-r  : 행바꿈 문자를 제외한 제어 문자를 ^ 형태로 출력한다. -vT와 같다.
-u  : 유닉스 호환성을 위해 추가된 옵션으로서 무시된다.
-v  : tab과 행바꿈 문자를 제외한 제어 문자를 ^ 형태로 출력한다.
-E  : 각 행마다 끝에 $ 문자를 출력한다.
-T  : 시로서 탭(tab) 문자를 출력한다.
-A  : -vET 옵션을 사용한 것과 같은 효과를 가진다.

cat address.list : 파일의 내용을 화면에 출력한다

cat : 파일을 작성하거나 파일의 내용을 간단하게 출력
  # cat test1.c
  # cat > test1.c

cc
C Language를 compile 하는 compiler
$ cc [option] file
-c  : compile의 linkage editor 단계를 억제한다
-E  : 지정된 C program에 대해 cpp만을 실행하고 결과는 표준출력하지 않는다
-f  : C program에서 부동소수점을 포함하는 코드를 linkage editor시킨다
-o  : outfile outfile이라는 화일명으로 목적프로그램을 저장하며 생략시는 a.out에 저장
-s  : C program을 compile 하지만 assemble하지 않으며 어셈블리 언어 출력은 .S가 붙은 화일에 저장
cc test.c
  -옵션 -r: 이전에 지정된 작업 취소, -l : 지정된 작업 번호 출력
  (sleep 20; cc -o sample sample.c)& -->백그라운드 실행, 20초 뒤 프로그램 컴파일
  (sleep 10; ps -el) --> 10초후 모든 프로세서 상태 출력
  time cc -o test test.c --수행 시간 출력 명령어

cd
디렉토리를 변경
$ cd [directory]
$ cd cgi-bin : 하부 디렉토리인 cgi-bin으로 들어감.
$ cd .. : 상위디렉토리로 이동
$ cd or cd ~ : 어느곳에서든지 자기 홈디렉토리로 바로 이동
$ cd /webker : 현재 작업중인 디렉토리의 하위나 상위 디렉토리가 아닌 다른 디렉토리(webker)로 이동하려면 /로 시작해서 경로이름을 입력하면 된다.

chfn
사용자의 finger 정보를 바꾸는 명령어입니다.

chgrp
파일의 그룹 소유권을 바꾼다.
$ chgrp [option] 그룹_파일들
-c  : 실제로 소유자가 바뀐 파일에 대해서 자세히 기술한다.
-f  : 파일의 그룹 소유권을 바꿀 수 없더라도 에러 메시지를 출력하지 않는다.
-v  : 소유권의 바뀜에 대해서 자세히 기술한다.
-R  : 디렉토리와 그 내용 파일들의 소유권을 재귀적으로 모두 바꾼다.

chmod
화일 permission 제어
$ chmod [option] [file]
$ chmod [option] 레벨 동작 권한 파일이름(들)
-c  : 실제로 파일의 권한이 바뀐 파일만 자세히 기술한다.
-f  : 파일의 권한이 바뀔 수 없어도 에러 메시지를 출력하지 않는다.
-v  : 변경된 권한에 대해서 자세히 기술한다.
-R  : 디렉토리와 파일들의 권한을 재귀적으로 모두 바꾼다.
참고
예) -rwxr-xr-x guestbookt.html
rwx : 처음 3개 문자 = 사용자 자신의 사용 권한
r-x : 그다음 3개 문자 = 그룹 사용자의 사용 권한
r-x : 마지막 3개 문자 = 전체 사용자의 사용 권한

읽기(read)---------- 화일 읽기 권한
쓰기(write)---------- 화일 쓰기 권한
실행(execution)------ 화일 실행 권한
없음(-)------------ 사용권한 없음
chmod --- 파일 및 디렉토리에 이미 정해진 접근 허가 모드를 변경
  - 사용 형식: %chmod [ugoa] [+-=] [rwx] [file name]
  u: 파일 소유자, g: 그룹, o: 기타 사용자, a: 모든 사용자
  +: 사용허가부여, -: 사용허가박탈, =: 허가 취소
  r: 읽기 허가, w:쓰기 허가, x: 실행 허가
  특정 사용자를 지정하지 않으면 모든 사용자를 의미한다
  chmod go+r test.c ; 소유자 그룹과 기타 사용자에게 읽기 허가
  chmod ugo-w test.c ; 소유자,그룹,기타 사용자에게 읽기 허가 박탈
  chmod +x test.c
  chmod o -rwx test.c
  r = 4, w = 2, x =1
  chmod 744 test.c
  -rwxr--r-- 1 edul user 235 Oct 15 13:23 test.c
  chmod 724 test.c
  -rwx-w-r-- 1 edul user 235 Oct 15 13:23 test.c

chown
파일의 소유권을 다른 사람에게로 변경시킨다.
$ chown [option] [user file]
-c  : 실제로 파일의 소유권이 바뀐 파일만 자세히 기술한다.
-f  : 파일의 소유권이 바뀔 수 없어도 에러 메시지를 출력하지 않는다.
-v  : 변경된 소유권에 대해서 자세히 기술한다.
-R  : 디렉토리와 파일들의 소유권을 재귀적으로 모두 바꾼다.
파일의 소유권을 다른 사람에게로 바꾸는 것은 슈퍼 유저만이 할 수 있다.

chsh
사용자의 shell을 바꾸는 명령어입니다.

clear
화면 지우기

cmp
두 개의 파일 내용을 비교
$ Cmp [option] [file1] [file2]
-l  : 두 파일 내용을 비교하여 틀린 곳마다 byte수(10진수)와 틀린 byte수(8진수) 출력
-s  : 비교하여 틀린 내용을 출력하지 않고 return code 만 반환

comm              
두 개의 정렬(sort)된 화일에서 공통된 line을 선택하거나 삭제
$ comm [option] file1 file2
-1  : file1에만 있는 line을 출력하지 않는다
-2  : file2에만 있는 line을 출력하지 않는다
-3  : file1, file2 양쪽 화일에 있는 line을 출력하지 않는다

compress
확장자 .Z 형태의 압축파일 생성
$ compress [file]  : 압축시
$ uncompress [file]  : 해제시
compress test.c (파일 압축) --->uncompress test.c.Z (압축 풀기)

cp
화일 복사(copy)
$ cp [option] [file1] [file2]
$ cp [option] [file1] [directory]
-a  : 가능한한 원 파일의 구조와 속성을 그대로 복사한다.
-b  : 복사할 때 덮어쓰게 되는 파일은 백업을 만든다.
-d  : 심볼릭 링크는 심볼릭 링크로 복사한다. 그리고 원본 파일과의 하드 링크 관계를 유지한다.
-f  : 복사 위치에 존재하는 파일을 제거하고 복사한다.
-i  : 복사시 같은 이름의 파일이 존재한다면 덮어쓸 것인가 확인한다.
-I  : 하드 링크를 만든다.
-P  : 원본 파일의 소유자, 그룹, 권한, 시간 기록을 그대로 복사한다.
-r  : 파일과 하위 디렉토리에 포함된 파일 모두를 재귀적으로 복사한다.
-s  : 디렉토리가 아닌 파일의 심볼릭 링크를 만든다. 소스 파일의 이름은 전체 경로 이름으로 한다. 목적지 파일 이름은 전체 경로를 주지 않아도 현재 디렉토리로 간주되므로 상관없다.
-u  : 파일의 정보를 갱신한다.
-x  : 다른 파일 시스템인 하위 디렉토리는 무시한다.
-R  : 디렉토리를 재귀적(recursive)으로 복사한다.
cp :시스템내에 있는 특정 파일을 복사
  # mkdir temp --temp라는 디렉토리 생성
  # cp sample test temp --temp라는 디렉토리 밑에 sample 과 test 라는 파일을 복사
  # mkdir example
  # cp -r temp example --temp라는 디렉토리 아래에있는 모든 내용을 example디렉토리에 복사

cpio
아카이브 파일을 복사하여 입출력
$ cpio -o [abcv]
$ cpio -i [Bdmtuvsb] [patterns]
$ cpio -p [adlmv] directory
-o 복사 출력 : 화일을 path명과 정보 상태를 함께 출력
-i  복사 입력 : 표준 입력 화일로 부터 pattern에 일치하는 화일을 추출
-p  : *directory 내에 file 을 조건부로 작성하고 복사
command:
a  : *file 복사후 입력 화일의 최종 접근 시간을 reset한다
B  : 입출력을 5,120 byte의 레코드로 블럭화한다
c  : ASCII 문자로 헤드 정보를 쓴다
d  : 필요에 따라 directory를 생성
m  : 존재하는 최종 화일 수정 시각을 보존
r  : 대화 문법으로 화일명을 변경
t  : 입력 화일명 목록을 출력하여 화일은 작성되지 않는다
u  : 무조건 복사
v  : 화일명 목록을 출력

crontab
지정한 화일을 입력으로 받아 user의 크론탭 화일을 관리 및 directory로 복사하는 명령어
$ crontab [file]
$ crontab [-u user] file
$ crontab [-u user] { -e | -l | -r }
-l  : crontab 파일 목록을 보여준다.
-e  : 에디터를 사용하여 crontab 파일을 수정한다.
-d  : 사용자의 crontab 파일을 지운다.
-u user : 특정 사용자의 crontab 파일을 다루도록 지정한다.
   이 명령을 사용하려면 슈퍼 유저로 로그인해야만 한다.
crontab 파일 내의 빈 핵과 # 문자로 시작되는 행은 무시된다.
파일의 각 행은 M H D m d cmd 형태로 되어 있다. 필드의 에스테리스크(*)표시는 어떠한 값이든 일치하는 조건으로 가정한다는 의미이다.

csh
유닉스 C 셸이다. 하지만 리눅스에서는 tcsh에 링크되어 있는 파일에 불과하다.

cu
다른 system을 호출
$ cu [options] [system or phone-number]
-h  : 반이중 모드만을 지원하는 시스템을 호출
-t  : 자동응답 모드에 설정된 ASCII단말기 호출
-d  : message 출력
-o  : 홀수 parity 생성을 지시
-n  : 전화번호 입력을 요구
-l  : line 통일 회선 장치명을 지정
-s  : speed 전송 속도(1200,2400,4800,7200,9600 bps)를 지정

cut
파일에서 필드를 뽑아낸다. 필드는 필드 구분자나 문자 위치로 지정된다.
$ cut -c문자위치 [file1 file2]
$ cut -f필드 -d필드구분자 [-s] [file1 file2 ...]
-c문자위치  : 잘라낼 곳의 글자 위치를 지정한다. 콤마를 사용하거나 하이픈을 사용하여 범위를 정할 수도 있으며, 이런 표현들을 혼합하여 사용할 수도 있다.
-f필드 : 잘라낼 필드를 정한다. 지정하는 방법은 -c 옵션과 같다.
-d필드 구분자: 필드를 구분하는 문자를 지정한다. 디폴트는 탭 문자다.
-s  : 필드 구분자를 포함할 수 없다면 그 행은 하지 않는다.

date: 현재의 날짜와 시간을 화면에 표시
  date;who;cat > sample.c : 한 줄에 두 개 이상의 명령어를 동시에 입력하고자 할 경우 명령어와 명령어 사이를 ; 으로      구분한다
  date > date.out : 이전 내용이 지워지고 새로운 내용이 저장
  * date >> date.out : 이전 내용과 함께 새로운 내용 첨가

dc
system을 이용한 탁상계산기
$ dc [file]
file  : 읽어들일 화일 지정, 생략시 표준 입력으로 간주

dd
다양한 데이타 형식을 가진 화일을 복사, 변환
$ dd [option = value] ...
bs=n  : 입출력 블럭의 크기를 n byte로 쓴다
cbs=n : buffer 크기변환
conv=ascii : EBCDIC 코드를 ASCII 코드로 변환
conv=ebcdic : ASCII 코드를 EBCDIC 코드로 변환
conv=lcase : 알파벳을 소문자로 변환
conv=ibn : 약간은 다르지만 ASCII 코드를 EBCDIC 코드로 변환
conv=noerror : 에러처리를 중지하지 않는다
conv=swab : 두개의 byte를 서로 교환
conv=sync : 각 입력 레코드를 ibs로 패딩
conv=ucase : 알파벳을 대문자로 변환
...,...  : 컴마로 구분된 여러개의 변환
count=n : 입력코드를 n개만 복사
files=n : 복사 시작전에 n개의 화일을 건너뛴다
seek=n : 복사 시작전에 출력화일의 처음으로 n 레코드를 탐색
ibs=n  : 입력블럭크기를 n byte로 한다 (디폴트는 512)
if=file  : 입력화일명(디폴트는 표준입력)
obs=n : 출력블럭크기를 n byte로 한다 (디폴트는 512)
of=file : 출력화일명(디폴트는 표준출력)
skip=n : 복사전에 입력레코드를 건너뛴다 

df
이용 가능한 디스크 블록 수 출력
$ df [-f] [-t] [file sysytem]
-f  : 디스크내의 자유리스트내의 정확한 블럭수를 출력
-t  : 사용가능 블럭 및 i-node와 할당된 전체블럭과 i-node가 출력
-m  : 파일 크기를 Mbyte단위로 출력

diff
두 개의 파일 중에서 다른 라인을 출력
$ diff [option] file1 file2
-b  : 비교할 때 라인의 마지막에 있는 탭(tab)과 공백을 무시
-e  : file1으로부터 file2를 재생성. ed 편집을 위한 a,c 그리고 d 명령어의 script를 만든다
-f  : 비슷한 script를 만들지만 역순이기 때문에 ed 편집에서는 사용할 수 없다
-h  : 정밀도가 없어도 빠른 속도를 처리하고자 할 때 사용하며 -e와 -f와 함께 사용할수 없다
-i  : 대소문자를 구분하지 않는다.
-w  : 탭(tab) 문자를 포함한 모든 공백 문자를 무시하고 비교 작업을 수행한다.

diff3
세 개의 파일 중에서 다른 라인을 출력
$ diff3 [option] file1 file2 file3
-e  : file1에 file2와 file3의 차이 비교를 기록
-x  : file1에 3개 화일 모두의 차이 비교를 기록
-3  : file1에 file3과 차이 비교되는 부분만 기록
disable -c [print name] ; 지정한 프린터에서 현제 출력중인 작업 취소
  * disable -w laser-3 ; 모두 인쇄한 다음 프린터를 disable 상태로 만든다
  * disable -c -r "out of paper" laser-1 ; 주석을 달아 놓는다

dmesg
부팅 메시지를 보여주는 명령어
Done : 백그라운드 프로세서의 수행이 완전히 종료된 상태

du
하드 사용량 체크(chkdsk)
$ du [option][dirctory, file]
-s  : 총 합계만을 따진다. 하위 디렉토리의 숫자 등은 나오지 않는다.
-a  : 크기가 계산된 각 파일의 크기를 보인다.
-b  : 바이트 크기로 출력한다.
-x  : 현재 디렉토리에 마운트된 파일 시스템만 검사된다.
-L  : 심볼릭 링크 자신의 공간 대신 연결된 파일의 크기를 다룬다.

echo
외부 프로그램과 내부 쉘명령어 사이에 있으며 echo의 인수는 공백에 의해 구분되어지며 new line으로 종료하는 각 인수를 화면에 표준출력하는 명령어
$ echo [option] [string]
-n  : 새로 개행하지 않고 출력하게 한다.
-e  : 문자열 중에서 백슬래쉬와 조합되는 특수 문자를 인식하게 한다.
                그러한 특수 문자들은 다음과 같은 것들이 있다.
\a 밸소리    \b 백스페이스
\f 용지바꿈(form feed)  \n 행바꿈
\r 0 칼럼으로(carriage return)  \f 탭(tab)
\v  수직 탭    \\ 백슬래쉬 문자
\nnn 8진법으로 표기되는 ASCII 문자 \c 출력 후 행바꿈 금지

ed
풀 스크린 에디터를 사용할 수 없는 열악한 환경의 터미널을 위한 라인 에디터
$ ed [-] [-s] [-p문자열] [file]
-  : e, r, w, q, ! 명령에 의해 발생하는 메시지를 금지한다.
-s  : 검사 작업을 금지한다.
-p문자열 : 프로프트를 원하는 문자열로 바꾼다.

edquota
사용자의 하드디스크 용량 및 파일의 개수를 제한한다.
$ edquota [option] [ID]
-n  : 쿼터 할당을 림트 서버에 할 수 있다.
-u  : 사용자를 정희한다. (기본값)
-p  : 사용자 그룹에 제한을 주기위한 옵션
-t  : 파일시스템의 soft time의 제한 값을 정한다. 디폴트 값은 /linux/quota.h를 따른다.

env
현재의 환경에 영향을 주지 않고 원하는 환경을 만들어 명령을 실행, 또는 현재의 환경 보고
$ env [-][-i ][-u 이름][name=value][command arg]
-  : 뒤에 오는 이름=값 목록으로 환경을 제한한다.
-i  : 현재의 환경을 무시하고 빈 환경 상태로 시작한다.
-u 이름 : 현재의 환경에 그 이름의 변수가 있다면 제거한다.
-name=value : 명령 수행 전의 원래 환경을 지정
-command arg: 수행하고자 하는 명령어 지정

ex
ed 기능을 강화한 텍스트 편집기
$ ex [-] [-trRV] [+command] name ...
-  : 대화형 사용자를 위해 feed-back을 억제
-t  : tag tag를 갖는 화일을 편집후 편집기를 그 화일의 위치에 지정
-r  : file file을 복구
R  : 읽기 허가만 된 모드로 한다
+ command : 지정한 명령어를 수행하고 편집

exit
현재의 프로세스를 종료하고 빠져나감
Exit : 백그라운드 프로세서가 수행도중 오류 때문에 빠져 나온 상태

fdformat
플로피 디스켓을 포멧한다
$ fdformat [device]

fg
후면 작업을 전면 작업으로 전환
$ fg [%작업번호]
fg %1(작업 번호) : 백그라운드로 수행중인 작업을 포그라운드로 전환

fgrep
문자열에 따라 파일 검색
$ fgrep [option] string [file]
-b  : 각 행의 선두에 그 행이 발견된 블럭번호를 넣어줌.
-c  : 일치하는 패턴을 갖고 있는 행의 수 만을 출력함.
-l  : 일치하는 행이 있는 화일의 화일명만을 복귀개행으로 구별시켜 출력하는데, 화일내에 패턴이 몇 개나 포함되어 있어도 화일명은 한 개밖에 출력하지 않음.
-n  : 각 행의 선두에 화일내의 행번호를 넣음.(1 라인은 1임)
-i  : 비교시 소문자와 대문자의 차이를 무시
-v  : 일치하는 행을 제외한 모든행을 출력.

file
파일이 어떤 형태의 파일인지 알아낸다.
$ file [option1][option2] file
-c  : 매직 파일의 파생된 형태를 보여준다
-z  : 압축되어 있는 파일의 형태를 검사
-l  : 뒤따르는 심볼릭 링크를 야기 시킴
-f 파일명 : 검사한 파일에 대해 리포트를 만들 파일의 이름을 지정
-m 파일명 : 파일의 형태를 결정하는 데에 사용되는 매직 파일을 정함
file < test > test.out : test 파일을 입력으로 받아서 file 명령을 실행하고 test.out에 출력
  file test.c : test.c라는 파일의 형태를 출력

find
원하는 특정 파일이나 디렉토리를 탐색하여 찾는다.
$ find path_list expression!

Expression!s
-name 파일명 : 찾고자 하는 파일의 이름을 정한다. 와일드 카드도 가능하다.
-perm 모드 : 파일권한(permission)이 일치되는 것을 찾는다. 원하는 권한은 ls로 볼 수있는 형태와 같이 지정한다.
-type ? : 형태가 같은 파일을 찾는다. 물음표(?) 부분에 디렉토리는 d, 파이프는 p, 심볼릭 링크는 l, 소켓은 s, 블록 파일은 b, 일반 파일은 f 등의 기호를 사용한다.
-links ? : 특정 개수의 링크를 가진 파일을 찾는다. 물음표 부분에 링크의 숫자를 표기한다.
-size ? : 파일의 크기가 일치하는 것을 탐색한다. 파일 크기는 블록단위로 물음표 부분에 지정한다. 한 블록은 512바이트로 내정되어 있지만 블록 숫자 뒤에 단위로 k자를 붙이면 1키로바이트 크기의 블록 숫자로 간주된다.
-user 사용자 : 파일 사용자의 ID에 따라서 검색한다. 로그인 이름이나 번호 모두가 가능하다.
-atime ? : 최근 며칠내에 엑세스한 파일을 검색한다. 날짜수는 ?에 명시한다.
-exec 명령 : 원하는 검색 조건에 맞는 파일을 찾으면 명시된 명령을 실행한다. 명령의 끝은 \;을 사용하여 끝낸다. find가 검색해낸 파일의 이름을 인수로 사용하고 싶다면 그 위치에 {}를 사용한다.
-newer 파일 : 어떤 파일보다 최근에 갱신된 모든 파일을 검색한다.
-cpio device : 현재의 화일은 cpio(1)의 문법(5120byte 레코드)으로 장치에 써넣는다
-ctime n : 화일이 n 날짜내에 변경되면 참
-group gname: 화일에 gname에 포함되어 있으면 참
-mtime n : 화일이 n 날짜 이내에 수정되면 참
-ok cmd : 명령어 라인을 의문부호를 선두에 부과하여 화면에 출력하며 만약 사용자가 y를 칠 경우에만 실행 가능
find: 사용자가 지정한 특정 범위에 해당하는 모든 파일을 검색
  # find / -name test1.c -print ; 최상위 루트 디렉토리부터 검색하여 검색된 파일을 한 행에 하나씩 표준 출력
  # find . -name test1.c -print ; 현제의 작업 디렉토리에서 검색
  # find / -size +1000 -print ; 최상위 루트에서 크기가 1000블록 이상인 파일 검색
  # find . -size -1000 -print ; 현 디렉토리에서 크기가 1000블록 이하인 파일 검색
  # find . -mtime +10 -print ; 10일 이전에 수정된 파일 검색
  # find . -mtime -10 exec rm {} \: ; 10일 이내에 수정한 파일을 검색하여 모두 지운다

finger
시스템 상의 사용자들에 대한 정보를 보여준다.
특정 사용자에 대한 정보를 알려면 finger username(또는 사용자가 다른 컴퓨터에 있으면 finger username@domain)을 입력한다.
$ finger [option] [user]
-s  : 사용자의 로그온 이름, 실제이름, 터미널 이름, 로그온 시간 등등을 보인다.
-l  : -s 옵션 정보에 몇 가지를 추가하여, 여러 줄에 걸쳐서 보여준다.
-p  : -l 옵션 정보에서 .plan과 .project 파일을 보이지 않는다.


foreground : 하나의 명령이 실행되어 결과를 출력할때까지 다른 명령을 수행 할 수 없다

free
메모리의 사용상태와 남은 상태, 버퍼의 상태등을 보여줌

fsck
파일 시스템의 완전한 상태를 유지하고 있는가를 검사하고, 잘못된 것은 수정한다.
$ fsck [option] [file system]
-f  : 빠른 속도로 블록과 크기 및 자유리스트를 점검
-n  : fsck 명령 수행중에 모든 질문에 대해 no라 응답한다.
-y  : fsck 명령 수행중에 모든 질문에 대해 yes라 응답한다.

-a  : 검사도중 발견된 에러를 자동적으로 복구한다.
-r  : 검사도중 에러가 발견되면 복구할 것인가를 물어온다. 이것은 하위 호환성을 위한 것으로서 사실상은 사용되지 않는다.
-s  : 병렬적인 방법이 아니라 순차적인 방법으로 검색한다.
-V  : 검색중 각종 정보를 자세하게 보여준다.
-N  : 실제로 검사 작업을 하지는 않도록 한다.

grep
파일 중에서 어떠한 패턴을 검색합니다.
$ grep [option] expression! [file]
-A  : [숫자] 라인에서 패턴과 매치되는 문자열을 찾아서 그 이상의 라인을 전부 보여줍니다.
-B  : [숫자] 라인에서 패턴과 매치되는 문장열을 찾아서 그 이하의 라인을 전부 보여줍니다.
-b  : 매치되는 라인과 그 크기(bite)를 출력합니다.
-c  : 매치되는 개수를 출력합니다.
-f  : 파일로부터 패턴을 입력받아 들입니다.
-n  : 매치되는 라인과 그 라인수를 출력합니다.
-v  : 매치되지 않는 라인을 출력합니다.
-w  : 주어진 단어와 완전히 매치되는 라인을 출력합니다.
-l  : 매치되는 내용이 있는 파일의 이름만을 표시한다.
-h  : 매치되는 내용을 찾은 파일의 이름을 표시하지 않는다.
-i  : 대소문자 구분을 하지 않는다.
-e expression! : 표현이 하이픈 문자로 시작될 때 사용한다.
-f file  : 규칙적인 식(grep) 또는 리스트열(fgrep)이 화일로부터 취한다
-s  : 읽지못하는 화일이거나 존재하지 않는 화일에 대한 에러 메세지 출력을 억제
grep [option] 형태 [화일명] -- 정규식을 이용 패턴 지정
  # grep -i tom sample.c -- sample.c 라는 파일에서 tom 이라는 문자열을 대소문자 구분 없이 검색
  # grep -n tom sample -- 행 번호와 함께 출력
  # grep -i "tom is" sample -- 공백은 " "로 표기
  # grep -v tom sample --tom이라는 형태를 포함하지 않는 행을 출력
  # cat sample
  computer science
  computer graphics
  # cut -c10-17 sample -- sample 파일에서 칼럼 단위10-17을 절단 --> science/graphics
  # cmp test1 test2 -- 서로 다른 두 파일을 비교
  # dircmp test test -- 서로 다른 두 디렉토리 비교

groupadd
그룹 이용자를 추가하는 명령어.

gpasswd
group의 사용자나 관리자를 추가, 또는 삭제할 때 쓴다.
root또는 관리자만이 group member를 추가, 삭제할 수 있다.
$ gpasswd [-r|-R] group
$ gpasswd [-a user] group
$ gpasswd [-d user] group
$ gpasswd [-A user,...] [-M user,...] group

gzip
파일 압축(확장자 .gz, .z 형태의 압축파일 생성)
$ gzip [파일명] : 압축시
$ gzip -d [파일명] : 해제시
gzip은 tar파일을 압축하는데 사용하는 명령어로 1단계에서 9단계로 압축률을 조정할 수 있다. 6단계를 사용하면 적절한 압축률로 압축할 수 있고 압축하는데 시간을 줄일 수도 있다.

halt
신속하게 system을 정지시키는 명령어

hd
16진수로 파일을 덤퍼하는 명령어(od참조)
$ hd [-bcdox] [file] [[+[x]] offset [.] [b]]

head
파일의 처음 n개의 내용을 보고자 할때 사용하는 명령

help
system 명령어에 대한 설명과 메시지에 대한 정보를 On-line 으로 제공
$ help [args]

history
작업 내역을 보여줌

hostname
현재 설정되어 있는 호스트의 이름을 표시하거나 변경한다.
$ hostname [name of host]

id
시스템에 등록된 ID를 확인한다.
$ id [option]
-g  : 그룹 ID만을 출력한다.
-G  : 추가 그룹들만을 출력한다.
-n  : ID 번호대신 이름으로 출력한다.
-r  : 실제 사용자나 그룹 ID를 출력한다. 다른 옵션과 함께 사용한다.
-u  : 사용자의 ID만을 출력한다.

ifconfig
네트워크 정보 표시
$ ifconfig [네트워크명]

ipcs
process 상호간의 통신에 대한 상태를 출력하는 명령어
$ ipcs [option]
-c  : 사용자의 로그인 명과 그룹명을 출력
-o  : 사용 상황 상태에 대한 정보를 출력
-p  : 프로세서 번호에 대한 정보를 출력
-q  : 수행중인 메세지 큐(Queue)에 대한 정보를 출력
-t  : 시간에 대한 정보를 출력

ispell
영어 단어의 철자를 확인
$ ispell [option] [file(s)]
파일 이름을 써주면 해당 파일의 단어를 검사하며, 파일 이름없이 실행시키면 표준 입력의 단어를 체크합니다. 해당하는 단어가 없을 때는 비슷한 단어들의 리스트를 보여줍니다.

install
파일을 갱신하고 이진 파일로써 인스톨하기 위해 makefile에서 종종 사용되는 유틸리티

jobs
현 터미널에서 수행된 작업들을 간략하게 나열해 준다.
$ jobs [-lnprs] [jobspec ...] or jobs -x command [args]
-l  : 프로세서 번호를 추가해서 보여준다.
jobs : 백그라운드로 수행중인 모든 프로세서의 상태 출력

join
두 개의 정렬된 파일을 하나로 수평 병합한다.
$ jobs [option] [file1] [file2]
-an  : 첫 번째나 두 번째 파일로부터 일치하지 않는 것도 처리, n은 1이나 2
-e 문자열 : 비어 있는 필드는 문자열로 대체
-j n m : 파일 n의 m번째 필드를 두 파일에 병합
-o file : 명시된 파일의 형태에 따라서 출력을 만듬
-t 문자 : 필드 구분 as자를 정한다. 기본적으로 공백, 탭, 개행 문자
-v file : file1이나 file2의 짝이 연결되지 않는 행을 지정된 파일로 출력

joe
emacs에 기초한 텍스트 에디터
kernel; 생성되는 프로세스마다 PCB 부여하고 관리

kill
프로세스를 강제 종료하는 명령어
$ kill [-signal number] process id
$ kill -l : 시그널 종류를 나열한다. 시그널의 종류는 시그널 번호 순서대로 이름으로 나열한다.
1 hang up     2 인터럽터   3 정지
4 정확하지 않는 명령    5 trace trap   6 IOT
7 EMT    8 부도소수점 expression! 발생  9 강제 종료
10 버스 에러     11 세그먼트 위배  12 bad system 콜
13 읽는 사람없이 파이프에 써 넣음  14 경보 신호    15 Software 종료
kill [번호] -- 프러세서 강제 종료 명령어
  * 강제 종료가 안될 경우 -9옵션을 사용 %kill -9 1239

killall
system내에 활동중인 모든 프로세서를 강제로 종료하는 명령어

last
시스템에 마지막으로 접근한 사용자를 표시
$ last [option]
-f  : 파일명을 참조하여 출력합니다.
-t  : tty로 로그인한 터미널을 추적합니다.
-v  : 로그인한 연도를 추가해서 출력합니다.

less
more와 유사하게 페이지 단위로 문서를 보여준다. 문서의 앞으로 이동하는 것이 가능
$ less [option] file
-?  : less에서 사용할 수 있는 명령들에 대한 도움말을 제공한다. 이 옵션이 사용되면 다른 인수는 무시되고, 도움말 화면을 보여준다.
-a  : 마지막 라인이 화면에 출력되고 나서 탐색을 시작한다.
-c  : 필요할 때 전체 화면은 다시 갱신한다.
-C  : -c 옵션과 같지만 갱신할 때 화면 전체를 지우고 시작한다.
-e  : 두 번째로  파일의 끝에 도달하면 자동적으로 종료한다.
-E  : 파일의 끝에 도달하기만 하면 자동적으로 종료한다.
-i  : 대소문자를 구분하여 탐색한다.
-n   : 행번호를 추가한다.
-q  : 특정 에러가 발생하지 않으면 아무 소리도 내지 않고 조용히 동작한다.
-Q  : 결코 아무 소리도 내지 않는다.
-s  : 연속되는 공백 라인은 하나의 행으로 처리한다.
-x 숫자 : 수치를 지정해서 탭 간격을 조정한다. 기본값은 8이다.

link / unlink
file 및 directory 링크 / 링크해제  명령
$ (un)link file1 file2

ln
실제 file을 file name에 연결시키는 명령
$ ln [-s] file_name1 file_name2
$ ln file_name(s) directory
-s  : 하드 링크 대신 심볼릭 링크를 만듬
ln test1 test2 --- test1과 test2라는 2개의 파일을 연결 (unlink ; 연결 해제)

locate
저장 위치를 찾아줌

login / logout
자신을 식별하고 시스템에 대한 액서스를 얻기 위해 사용하는 명령
$ logiin [option] ID
-f  : 뒤의 사용자명으로 로그인
-g  : 뒤의 그룹사용자명으로 로그인

longname
현재 시스템에서 자신이 사용하는 로그온 이름을 보여줌

lp
특정 file / 정보를 프린터로 출력하는 명령어
$ lp [options] files
-c  : 프린터가 끝나기전에 화일 변경이 가능하도록 프린트할 화일을 복사
-d dest : 프린터 또는 프린터 클라스를 dest로 지정
-m  : 프린트 후 전자우편을 보낸다
-n number : 프린트 할 매수를 지정
-s  : 메세지 출력을 억제
-w  : 프린트 후 사용자의 단말장치에 메세지를 보낸다

lpadmin
스풀 프린터 시스템 구축 명령어
$ lpadmin [options]
-d dest : 기존 dest를 신규 시스템의 생략시 수신자로 한다

lpstat
출력되는 라인 프린터의 상태에 대한 정보를 화면에 나타내는 명령어
$ lpstat [option]
-a list  : 프린터나 클라스의 처리 상태 출력
-c list  : 클라스명과 멤버 출력 이때 list는 프린터명 또는 클라스명의 리스트
-d  : lp에 대한 system을 생략시 주소를 출력
-o list : 출력 request의 상태 출력 이때는 프린터명,클라스명,request id 리스트
-p list : 프린터 상태 출력 이때 리스트는 프린터명
-r  : 라인 프린터 scheduler 상태 출력
-t  : 프린터의 모든 상태 출력
lpstate : 프린터의 현제 상태 (활성화: enable, 비활성화: disable)
  * lp -c temp.c ; 내용이 변경되어도 문제가 지속되지 않도록미리 출력될 파일을 복사
  * lp -n7 /etc/lp/temp ; 7장 프린트
  * lp -m temp.c ; 출력이 끝난후 사용자에게 전자우편을 보냄
  * lp -t"chon bing hee" test.out ; chon bong hee라는 표제를 달아 줌

ls
directory의 내용을 화면에 출력하는 명령어
$ ls [option] file..
-a  : .file을 포함한 전 entry를 출력
-A  : -a option과 유사하지만 .또는 ..을 포함하는 화일은 출력 억제
-c  : 마지막 변경된 i-node의 시간을 출력
-C  : 멀티칼럼으로 출력하며 디폴트로는 CRT에 출력
-d  : directory명만 출력하며 내용은 출력하지 않는다
-D  : directory만 출력
-f  : 인수를 directory로 해석하며 각각의 슬롯에 있는 directory 및 file명을 출력
-F  : system에 있는 화일이 directory면 /를 실행가능한 화일이면 *를 붙인다
-g  : 옵션 -l과 같으나 소유자명이 출력되지 않는다
-i  : 첫 칼럼에 i-number를 출력
-l  : 화일 및 directory 상태 정보를 long 문법으로 출력
-m  : 스트림 문법의 출력
-n  : 소유자명과 그룹명 대신에 UID 번호와 GID 번호가 출력되는 것을 제하고는 옵션 -l과 같다
-g  : 비도형문자를 ?문자로 출력
-r  : 화일명이나 수정시간을 알파벳 또는 오래된 역순으로 출력
-R  : 발견되는 sub-directory의 내용을 순환적으로 출력
-s  : 간접블럭을 내포하는 블럭수를 출력
-t  : 화일명 대신에 수정된 시간으로 분류
-u  : -t 또는 -l option으로 분류하는 중에서 최종접근 시간을 사용
ls: 현재 위치한 디렉토리 아래에 있는 파일 및 서브디렉토리의 정보를 나열
  - 옵션: -l: 파일의 모든 정보 출력
  -c: 최근 변경한 시간 순서데로 출력
  -d: 디렉토리 명만 출력
  -F: 파일의 특성을 출력( /디렉토리 *실행화일)
  -a: dot(.)으로 시작하는 파일의 이름을 포함한 모든 내용을 출력

mail
사용자들간에 전자우편을 주고 받는 명령어
$ mail ID@domain_address
$ mail [-f file] [-par]
-f file  : 지정한 화일을 전자우편 화일로 한다
-p  : 조치를 위한 prompt를 나타내지 읺고 전자우편을 출력
-g  : 인터럽터를 건후에 종료
-r  : 메세지를 FiFo(선입선출)방식으로 한다

mailx
대화형 메시지 처리를 하는 명령어
$ mailx [option] [name ...]
-e  : 전자우편이 있는가 없는가를 조사
-f[file name] : mailbox 대신에 화일명에서 메세지를 읽는다
-F  : 메세지를 최종 수신자명이 붙어 있는 화일에 기록
-S  : subject 종속 헤드필드를 subject로 한다
-U  : user 사용자의 mailbox를 읽어낸다

man
원하는 명령어의 사용방법을 검색하여 보여주는 명령어
$ mailx [option] [chapter] title ...
-k  : 인수로 주어진 단어를 키워드로 사용하여, 해당 키워드가 발견되는 모든 매뉴얼의 내용을 검색
man date : 예약어나 명령어에 대한 온라인 매뉴얼

mcd
MSDOS 시스템으로 현재 사용하는 디렉토리 장소로 이동
$ mcd [dos directory]

mcopy
MSDOS file system으로 or DOS file system의 file을 복사
$ mcopy [option] file_name1 file_name2
-t  : 텍스트 파일 복사시 CR/LF 문자를 \n 하나로 바꾼다.
-n  : 파일을 덮어쓰게 되는 경우에도 경고하지 않는다.
-v  : 자세히 안내문을 보여준다.
-m  : 파일 갱신 시간을 보존한다.

mdel
MSDOS file system에서 file을 제거
$ mdel [-v] file
-v  : 진행되는 상황을 자세히 보여줌

mdir
MSDOS directory의 목록을 보여준다.
$ mdir [-w] file
-w  : 파일 크기나 생성 날짜는 제외하고 넓은 형식으로 보여줌

mesg
teminal에 들어오는 메시지를 허가 또는 거부하는 명령어
$ mesg [n] [y]
n  : 메세지 거부
y  : 메세지 허가

newgrp
현재 그룹 ID를 변경한다.

mfs
모든 file system을 mount 하는 명령어

mkdir
directory 생성
$ mkdir [-m mode] [-p] directory
-m  : 디렉토리를 만들 때 같이 사용하여 사용자 권한을 줄수 있다.
-p  : 만들 디렉토리의 상위 elfprxhflRK지 한꺼번에 만든다.
mkdir : 디렉토리 생성 명령어 (%mkdir [option] [directory name]

mknod
특수화일을 위해 directory와 이에 i-node를 만드는 명령어
$ mknod file [b] [c] major minor
b  : 특수화일이 블럭형
c  : 특수화일이 문자형
major  : 주장치 번호
minor  : 부장치 번호

mkswap
swap 공간 생성

more
한 화면씩 출력을 보여주는 유틸리티
$ more [ -ncdflspu ][ +줄번호 ][ 파일이름(들) ]
-n  : 여기서 n은 숫자를 의미하여, 숫자는 출력 윈도우의 행수를 지정한다.
-c  : 위에서부터 한 행씩 지운 후 한 행씩 출력한다. 보통은 화면 전체를 지운 후 각 행을 출력하기 시작한다. 특정한 터미널을 위해 사용한다.
-d  : 스페이스나 q 키를 누르라는 프롬프트를 출력한다.
-f  : 화면의 행이 아닌 논리적인 행 수를 계산한다. 보통은 긴 칼럼의 행은 화면에서 행바꿈을 하여 새로운 행으로 계산된다. -f 옵션을 사용하면 이러한 행은 계산하지 않는다.
-s  : 여러 개의 빈 공백행은 하나로 취급한다.
-p  : 스크롤하지 않는다. 대신 화면을 지우고 출력한다.
-u  : 밑줄 차기를 금지한다.

설명
more 명령은 몇 가지 명령을 인식할 수 있다. 스페이스 바를 누르는 것을 포함해서 다음과 같은 조작을 하는 것이 가능하다.
■ <return> : 한 줄만 스크롤된다.
■ D        : 반 페이지만 뒤로 이동한다.
■ <space> : 한 페이지만 뒤로 이동한다.
■ B  : 한 페이지 앞으로 이동한다.
■ H  : 도움말을 제공한다.
■ V  : vi 에디터를 부른다. 에디터를 종료하면 원 위치로 돌아간다.
■ Q  : more 를 종료한다.

more [file name] : 한 번에 한 화면씩 파일의 내용을 표준 출력
  -내용을 보지 않고 종료시 q 나 Q 키를 누른다

mount
다른 파티션의 디스크나 물리적으로 다른 rldr 장치를 파일 시스템으로 연결
$ mount [option] 장치명 디렉토리
-v  : 마운트 작업을 수행하면서 자세한 정보를 출력한다.
-w  : 마운트되는 파일 시스템을 읽기와 쓰기가 가능하도록 한다.
-r  : 마운트되는 파일 시스템이 읽기 동작만 가능하도록 한다.
-n  : 마운트 정보가 기록되는 /etc/rntab 파일에 정보를 기록하지 않는다.
-a  : /etc/fstab 파일에 있는 모든 파일 시스템을 마운트하도록 한다.
-t 형태 : 마운트되는 파일 시스템의 형태를 지정한다.

mountall
여러개의 file system을 mount하는 명령어
$ mountall [-] file system
$ mountall [-k]
-  : 입력되는 데이타가 표준입력
-k  : 화일을 open시키고 프로세서를 찾은 다음 SIGKILL 시그널을 보낸다

Multitask

mv
파일의 위치를 이동하거나 파일의 이름을 바꾸어 준다.
$ mv [ -fi ] 파일명1 파일명2
$ mv [ -fi ] 파일명(들) 디렉토리명
-f  : 같은 이름의 파일이 존재하고 쓰기 권한이 금지되어 있더라도 물어 보지 않고 덮어쓰기를 해버린다. 이런 경우 이 옵션을 사용하지 않으면 사용자에게 다시 확인을 할 것이다.
-i  : 파일을 덮어쓰기 전에 사용자에게 확인한다.
mv [file name1] [file name2] --file name1을 file name2로 이름 변경
mv [file1] [file2] [directory1] --file1, file2를 directory1으로 이동
mv [directory1] [directory2] --directory1의 모든 내용을 directory2로 이동
  **명령어 cp, mv, rm에서 option -i는 사용자에게 여부를 묻는 옵션입니다

mvdir
file system 내에서 directory 변경을 하는 명령어
$ mvdir [oldname] [newname]

nice
프로세스의 순위를 변경하는 명령어
$ nice command -n XX
nice
값은 -20에서 19까지 있는데, 값이 작을수록 우선 순위가 높습니다. -n옵션을 쓰기 않으면 디폴트로 10이 쓰입니다. 일반
유저는 nice값을 증가시킬 수밖에 없지만 root는 nice값을 감소시켜 우선 순위를 높을 수도
있습니다.               
nice [-정수값:1~39 , 20으로 설정] 명령어 -->우선 순위 변경 명령어
  정수값이 높을수록 우선 순위가 낮다 (nice -10 cc -o test test1.c)

nl [file name] : 지정한 파일의 내용을 츨력할 때 맨 앞에 행 번호를 이어서 출력

nohup cc -o sample1 sample1.c & 1132[PID번호]
    백그라운드로 실행, 로그 아웃이나 중지 신호후에도 프로세서의 수행 계속

nslookup
네임 서버를 조회한다.
$ nslookup [option] [host or IP Address] [name server]
-q=A  : IP Address
-q=MX : 메일서버 확인
-q=NS : 네임서버 확인
-q=CNAME : 호스트의 앨리어스
-q=PTR : 호스트 또는 포인터명
-q=SOA : Statt of Authority 정보

od
8, 10, 16진 또는 파일의 ASCII 덤프를 만들기 위한 명령어
$ od [option] file
-b  : 바이트를 8진수로 출력
-c  : 바이트를 아스키 문자로 출력
-x  : 바이트를 16진수 워드 단위로 출력

pack test.c (파일 압축) ---> unpack test.c.z

page [option] [file name] : 한 번에 한 화면씩 파일의 내용을 표준출력(=== %pg)

passwd
자신의 패스워드를 관리하는 명령어
$ passwd [user]
암호화 되어 /etc/passwd 파일에 놓여집니다.
암호는 최소한 6자 이상이어야 합니다(8자 이상 권장).
암호는 구두점 기호와 숫자뿐만 아니라 대소문자를 모두 포함해도 됩니다.

paste
하나 혹은 그 이상의 파일로부터 칼럼 형태의 출력을 만든다. cut과 함께 사용
$ paste [-s] [-d 구분문자] file_name(s)
-s  : 각 file을 순회하면서 paste를 수행한다.
-d 구분문자 : 어떠한 문자로 칼럼을 구분하는지 지정. 기본값은 탭 문자

pico
UNIX용 에디터

pine
PINE 4.10   MAIN MENU                            Folder: INBOX  19 Messages

          ?     HELP        -  Get help using Pine
          C     COMPOSE MESSAGE  -  Compose and send a message
          I     MESSAGE INDEX -  View messages in current folder
          L     FOLDER LIST         -  Select a folder to view
          A     ADDRESS BOOK       -  Update address book
          S     SETUP               -  Configure Pine Options
          Q     QUIT                -  Leave the Pine program
    Copyright 1989-1999.  PINE is a trademark of the University of Washington.
                   [Folder "INBOX" opened with 19 messages]
? Help                     P PrevCmd                 R RelNotes
O OTHER CMDS > [ListFldrs] N NextCmd                 K KBLock
메일을 주고 받을 수 있는 명령

ping
자신의 네트워크나 다른 네트워크가 통신이 잘되고 있는지 점검함
$ ping hostname

ps
프로세서들의 상태를 점검하는 명령어
$ ps [options]
-l  : 자세한 형태의 정보를 출력한다.
-u  : 각 프로세서의 사용자 이름과 시작 시간을 보여준다.
-j  : 작업 중심 형태로 출력한다.
-s  : 시그널 중심 형태로 출력한다.
-v  : 가상 메모리 중심 형태로 출력한다.
-m  : 메모리 정보를 출력한다.
-a  : 다른 사용자들의 프로세서도 보여준다.
-x  :
로그인 상태에 있는 동안 아직 완료되지 않은 프로세서들을 보여준다. 유닉스 시스템은 사용자가 로그아웃하고 난 후에도 임의의
프로세서가 계속 동작하게 할 수 있다. 그러면 그 프로세서는 자신을 실행시킨 셸이 없이도 계속 자신의 일을 수행한다. 이러한
프로세서는 일반적인 ps 명령으로 확인할 수 없다. 이때 -x 옵션을 사용하면 자신의 터미널이 없는 프로세서들을 확인할 수 있다.
-S  : 차일드(child) CPU 시간과 메모리 페이지 결함(fault) 정보를 추가 한다.
-c  : 커널 task_structure로 부터 명령 이름을 보여준다.
-e  : 환경을 보여준다.
-w  : 긴(wide) 형태로 출력한다. 한 행 안에 출력이 잘리지 않는다.
-h  : 헤더를 출력하지 않는다.
-r  : 현재 실행중인 프로세서를 보여준다.
-n  : USER 와 WCHAN 을 위해 수치 출력을 지원한다.

설명
기본적으로 ps는 현재 명령이 내려지는 셸에서 만들어진 프로세서들의
목록만을 보여준다. ps는 자신이 실행되는 당시, 현재의 셸에 의해서 수행된 프로세서들을 검사하고 보고한다는 점을 생각하자.
그러면 ps의 출력결과 리스트에 ps 자신이 있는 이유를 쉽게 이해할 수 있을 것이다. 각 필드의 의미는 다음과 같다.

  COMMAND : 명령어의 이름
  PID  : 프로세서 ID, 각 프로세서를 구분하기 위한 고유의 ID
  RSS  : 프로세서에 의해 사용되는 실제 메모리의 용량(K byte 단위)
  USER : 프로세서를 실행시킨 소유자의 계정을 보여준다.
  SZ  : 프로세서의 자료와 스텍 크기의 (K byte 단위)
  TIME : 현재까지 사용된 CPU의 시간(분,초)
  TT  : 프로세서의 제어 터미널(t3=/dev/tty3)
  %CPU : 마지막 분동안 프로세서가 사용한 CPU시간의 백분율
  START : 프로세서가 시작된 시간
  STAT : 프로세서의 상태

이중 STAT 필드는 몇 가지의 부호를 사용해서 프로세서의 상태를 표시하고 있다. 그것들을 정리해 보면 다음과 같다.

  P  : 수행 가능/수행중
  T  : 일시 정지
  D  : 디스크 입출력 대기 같은 인터럽트할 수 없는 대기상태
  S  : 20초 미만의 짧게 잠듦(sleep)
  I  : 20초 이상의 길게 잠듦
  Z  : 좀비(zombi) 프로세서

좀비(zomb) 상태라는 것은 프로세서가 사라질 때 시그널 처리의 문제로 완전히 소멸되지 못한 상태를 말한다.
ps -l --프로세스에 관한 모든 상태 정보 출력
  ps -e --현제 실행중인 모든 프로세스에 관한 정보 출력
  ps ps -t 00 --지정된 터미널에서 실행중인 프로세스에 관한 정보 출력

pstree
프로세서의 트리구조를 출력한다.

pwd
현재 작업하는 디렉토리를 알기 위해서 pwd 명령을 사용한다.
print working directory, 현재 작업 Directory를 출력한다.
pwd : 현제 작업 디렉토리 출력 명령어

quota
계정에 할당된 사용량을 확인한다.
$ quota [-vq] [[-ug] | -u[ user] | -g[ group]]

quit
대화식 모드에서 떠남

reboot
system을 재부팅
$ reboot [-q]
-q  : 현재의 프로세서들을 종료시키지 않고, 부팅 동작만을 수행한다. 이 옵션을 사용하면 더 빠르게 리부팅할 수 있다. 다시 부팅한 기록은 로그 파일인 /var/adm/wtmp에 기록된다.

rcp
컴퓨터 사이에서 file을 복사할 때 사용된다.
$ rcp [option] file_name1 file_name2
$ rcp [option] file(s) directory
-q  : 현재의 프로세서들을 종료시키지 않고, 부팅 동작만을 수행한다. 이 옵션을 사용하면 더 빠르게 리부팅할 수 있다. 다시 부팅한 기록은 로그 파일인 /var/adm/wtmp에 기록된다.
-r  : 하위 디렉토리까지 재귀적으로 모두 복사한다.
-p  : 파일의 시간과 모드를 보존한다.
-k  : kerberos ticktets을 요구한다.
-x  : 복사되는 모든 데이터에 암호화 과정을 거친다.

rfd:디스켓, rct:카트리지테이프, rmt: 테이프) 백업 및 복사에 관한 명령어 하드 ----> 디스켓
  Non-preemptive(비선점) ; 커널 모드
  # tar -cvf /dev/rfd0c test1
  (c: 저장되는 파일들이 디스크의 처음부터 기록, v:기록되는 화일명 화면 출력)
  # tar -tvf /dev/rfd0c --- 디스켓의 파일 목록 확인
  디스켓 ----> 하드
  #  tar -xvf /dev/rfd0c test1 --- 지정한 파일 복원 
  동일한 하드 ---> %tar -cvf test1.tar test1
  test.c.Z (파일 생성) --- >zcat test.c.Z (파일 보기)
  touch : 내용이 없는 빈 파일을 생성, 이미 생성된 파일의 수정 시간 갱신
  # touch [option] [시간] [파일명]

rm
file을 지우는 명령
$ rm [option] file_name
-f  : 보통 지울 수 있는 권한이 없으면 안되지만, 이 옵션을 사용하면 성가신 작업을 하지 않고서도 강제로 파일을 지울 수 있다.
-i  : 파일을 지울 것인가 다시 물어본다. 지우기를 원한다면 y를 누른다.
-r  : 서브 디렉토리의 파일도 모두 재귀적으로 지운다.
-v  : 파일을 지우기 전에 파일의 이름을 나타내준다.

rmdir
원하는 directory를 제거한다.
$ rmdir [-p] directory
-p  : mkdir의 -p 옵션의 반대 동작으로 하위 디렉토리와 그 상위 디렉토리 모두를 제거할 수 있다. 이때 모든 디렉토리는 비워져 있어야 한다. 수행 후 결과가 어떻게 되었는지를 보여준다.
rmdir : 디렉토리 삭제 명령어
  - 옵션: rm -r test ; test의 하위디렉토리와 파일을 전부 삭제
  - 옵션: rm -i test ; 삭제 여부를 사용자에게 물어 본다

rm test1 test2 test3 --- test1,test2,test3 파일을 삭제
  rm -r quit --- quit 디렉토리 및 모든 내용을 삭제

route
현재 라우터에 상태 확인 및 라우터 정보를 수정할 수 있다.
$ route add -net network address netmask device
route를 이용해서 라우터의 정보를 변경 또는 추가할 수 있다. 특히 가상 IP 설정을 할 수 있다. 즉, 한 대의 서버에 여러개의 IP를 사용할 수 있다.

rpm
레드헷 패키지 관리자
$ route add -net network address netmask device
rpm
명령어는 바이너리 소프트웨어를 설치해주는 역할을 하므로써 일반사용자에게 설치의 편리성을 제공해주는 편리한 명령어이다. 설치뿐만
아니라 소프트웨어의 삭제도 간단한 명령어로 간단하게 해결해 주기 떄문에 설치된 소프트웨어의 파일을 일일이 찾아 삭제하는 수고를
덜어준다.

Running : 현제 백그라운드 수행중인 상태

sh
원래의 nunix 명령인 본 셀을 불러내는 명령어

shutdown
시스템을 종료할 때 일반적으로 사용하는 명령어
$ shutdown [ -thnrfck ] 시간 [ 메시지 ]
$ shutdown now
-t n  : t 옵션 뒤에 n초를 명시해서, 경고 메시지를 보낸 후 n초 후에 kill 시그널을 보낸다.
-h  : shutdown시 halt를 실행하게 한다.
-n  : 디스크 동기화 동작의 수행을 금지한다. 이런 옵션은 보통 사용할 일이 없을 것이다.
-r  : 시스템 종료를 완료하고 나서 다시 부팅 과정을 수행한다.
-f  : 빠른 리부팅을 한다. 리부팅시 파일 시스템 검사를 하지 않는다.
-c  : 이미 예약되어 있는 shutdown을 취소한다. 이 옵션을 준다면 시간 인수는 줄 수 없다. 하지만 메시지는 사용자들에게 줄 수 있다.
-k  : 모든 동작을 제대로 수행하지만 시스템을 종료할 시간이 되면 아무 것도 하지 않는다. 보는 사람으로 하여금 '절로 누구 놀리나?'하는 말이 나오게 한다. k는 'just kidding'의 의미라고 한다.

sleep
이름 그래로 잠자는 일 외에는 하는 일이 없다.
$ sleep 시간

간은 초 단위의 정수 숫자이다. 전면(foreground)에서 수행된다면 사용자의 터미널은 정해진 시간만큼 잠을 잘 것이다.
물론 정해진 시간에 즉각 일어나니 안심해라. 원한다면 ^C로 흔들어 깨울 수도 있다. sleep을 사용하는 가장 좋은 예는
3장에서 본 것과 같이 다중 작업을 시행할 때이다.

다음과 같은 확인자를 사용한다면 다른 시간 단위를 사용할 수 있다.

S 초   m 분
h 시간   d 날짜

sort
파일 내의 단어 순서를 행 단위로 정렬하는 명령어
$ sort [option] file_name(s)
-c  : 파일이 정렬되었는지 검사한다. 그렇다면 아무런 출력도 하지 않는다.
-m  : 특정한 파일을 병합한다. 파일은 이미 정렬되었다고 가정한다.
-u  : 고유한 행만이 출력된다.
-o 파일명 : 출력 파일 이름을 지정한다. 이름은 입력 파일 이름과 같을 수 있다.
-d  : 사전(dictionary)과 같은 순서대로 정렬한다. 단어 정렬 순서에는 문자, 숫자, 공백 문자만이 사용된다.
-f  : 대문자와 소문자를 구별하지 않는다.
-i  : 정렬에 사용되는 문자 중 프린트될 수 없는 문자는 사용하지 않는다.
-M  : 단어를 정렬할 때 달을 의미하는 문자를 취급한다. FEB는 JAN보다 뒤에 정렬된다.
-n  : 숫자를 같은 문자가 아닌 정말로 숫자로 취급해서 수의 크기대로 정렬한다.
-r  : 역순으로 정렬한다.
-t 문자 : 단어 등 필드를 구분하는 문자를 지정한다. 탭(tab)이나 공백 문자 이외의 문자를 구분 문자로 취급하도록 한다.
-b  : 단어의 뒤에 오는 공백 문자는 정렬 키(key) 값으로 무시하도록 한다.

split
텍스트 file을 작은 조각으로 나눈다. 너무 커서 다루기 불편한 텍스트 문서를 나눌 때 사용
$ split -행 수 file_name [tag_name]
-행 수 : 몇 개의 행 단위로 조각을 나누는지 정한다.

Stopped : fg로 수행되다가 ^D로 잠시 중단된 상태

su
다른 사용자 계정으로 서브 셸을 생성한다. 잠시만 다른 사용자 계정으로 작업할 필요가 있을 때 사용한다.
$ su [-] [userID] [인수]
-  : 하이픈 (-)을 사용하면 새로운 셸로 로그인할 때 자신의 로그인 과정을 수행한다. 옵션이 주어지지 않으면 새로운 셸은 단지 셸 역할을 수행할 뿐이다.
아무런 인수없이 su를 사용하면, 이것은 root 계정으로 로그인하기를 원하는 것으로 간주된다. 그래서 많은 사람들이 su가 'super user'를 의미하는 말로 생각하지만, 사실은 'substitute user'를 의미하는 말이다. 물론 수퍼 유저의
패스워드를 알고 있어야만 한다.

swapon
스왑 공간 사용하기

sync
현재 시스템 디스크의 IO 버퍼에 있는 디스크 이미지를 하드 디스크로 기록한다.
$ sync

스템을 다운시키기 전에 버퍼에 있는 이미지를 반드시 디스크로 기록해야 한다. 그렇지 않으면 디스크는 기록된 정보의 이미지와 일치하지 않는 이미지를 가지게 될지도 모른다. 사실, 이것을 사용할 경우는 극히 드물다. 왜냐하면 shutdown등의 동작을 수행하면 그들이 자동적으로 sync를 호출하기 때문이다.

tail
문서의 끝 부분을 화면에 출력한다.
$ tail [-행수] file_name(s)
-행 수 : 출력될 행수를 지정한다.

tar
file들을 묶는 명령어
$ su [-] [userID] [인수]
주요 동작 모드 :
-t, --list   : 아카이브의 내용물을 출력합니다
-x, --extract, --get  : 아카이브에서 파일을 추출합니다
-c, --create   : 새로운 아카이브를 만듭니다
-d, --diff, --compare : 아카이브와 파일 시스템간의 차이점을 비교합니다
-r, --append  : 아카이브 끝에 파일을 추가합니다
-u, --update  : 아카이브 안의 것보다 새로운 파일만 추가합니다
-A, --catenate  : 아카이브에 tar 파일을 추가합니다
    --concatenate  : -A와 같음
    --delete   : 아카이브로부터 제거합니다 (자기 테이프에선 안됨!)

동작 변경자:
-W, --verify   : 아카이브를 기록한 다음 검증하도록 합니다
    --remove-files  : 아카이브에 파일을 추가한 다음 지웁니다
-k, --keep-old-files  : 추출할 때 이미 존재하는 파일을 덮어쓰지 않습니다
-U, --unlink-first  : 추출하기에 앞서 대상 파일을 지웁니다
    --recursive-unlink : 디렉토리를 추출하기에 앞서 그 체계를 비웁니다
-S, --sparse   : 스파스 파일을 효율적으로 처리합니다
-O, --to-stdout  : 표준 출력으로 파일을 추출합니다
-G, --incremental  : 오래된 GNU 형식의 점진적 백업 파일을 처리합니다
-g, --listed-incremental : 새로운 GNU 형식의 점진적 백업 파일을 처리합니다
    --ignore-failed-read : 읽을 수 없는 파일에 대해 영 아닌 값으로 종료하지 않습니다

장치 선택과 전환:
-f, --file=ARCHIVE  : 아카이브 파일 또는 ARCHIVE 장치를 사용합니다
    --force-local  : 이름에 콜론이 있는 아카이브 파일도 지역 파일로 인식합니다
    --rsh-command=COMMAND: rsh 대신 원격 COMMAND를 사용합니다
-[0-7][lmh]   : 드라이브와 기록 밀도를 지정합니다
-M, --multi-volume  : 다중 볼륨 아카이브를 생성/출력/추출합니다
-L, --tape-length=NUM : NUM x 1024 바이트를 쓴 뒤에 테이프를 바꿉니다
-F, --info-script=FILE : 각 테이프의 끝에서 스크립트를 실행합니다 (-M을 포함함)
    --new-volume-script=FILE: -F FILE과 같음
    --volno-file=FILE  : FILE 안에 있는 볼륨 번호를 사용/갱신합니다

장치 블럭 설정:
-b, --blocking-factor=BLOCK: 레코드당 BLOCK x 512 바이트
    --record-size=SIZE : 레코드당 SIZE 바이트, 512의 배수
-i, --ignore-zeros  : 아카이브에서 영으로 된 블럭을 무시합니다 (EOF를 의미함)
-B, --read-full-records : 읽은 것을 재블럭화합니다 (4.2BSD 파이프용으로)
정보 출력에 관한 옵션:
    --help   : 이 도움말을 인쇄하고 끝냅니다
    --version  : tar 프로그램의 버전 번호를 인쇄하고 끝냅니다
-v, --verbose  : 처리되는 파일을 순서대로 출력합니다
    --checkpoint  : 아카이브를 읽을 동안 디렉토리 이름을 인쇄합니다
    --totals   : 아카이브를 만들 동안 쓰여진 총 바이트 수를 인쇄합니다
-R, --block-number  : 각 메시지마다 아카이브내의 블럭 번호를 표시합니다
-w, --interactive  : 모든 행동에 대해 확인을 요구합니다
     --confirm!ation  : -w와 같음
-s, --same-order  : sort names to extract to match archive
    --preserve-order  : same as -s
    --preserve  : same as both -p and -s
-z, --gzip, --ungzip  : filter the archive through gzip
-Z, --compress, --uncompress: filter the archive through compress
    --use-compress-program=PROG: filter through PROG (must accept -d)

tcsh
c 셸 명령 번역기. c 셸의 확장판
$ tcsh [option] file
-T  : tenex라고 하는 특수한 기능을 수행하도록 한다.
-V  : -v 옵션과 같지만 초기화 스크립트의 수행에도 영향을 미친다.
-X  : -x 옵션과 같지만 초기화 스크립트의 수행에도 영향을 미친다.
나머지 옵션들은 bash셸과 같다.

tee
파이프 연결 출력을 양방향으로 나눈다.
$ tee [option] file_name(s)
-i  : 인터럽트를 무시하도록 한다.
-a  : 지정된 파일들로 출력이 덮어쓰지 않고, 뒤에 추가되도록 한다.
Terminated : Kill 명령을 사용해 강제로 종료된 상태

test
file의 각종 상태를 검사하여 결과를 알려준다. 셀 스크립트 상에서 if 문이나 while 문등과 함께 사용되는게 보통이다.
$ test [expression!]

Expression!s
-r 파일명 : 파일이 읽기 권한이 있으면 참
-w 파일명 : 파일이 쓰기 권한이 있으면 참
-x 파일명 : 파일이 실행하기 권한이 있으면 참
-f 파일명 : 파일이 일반(regular) 파일이면 참
-d 파일명 : 파일이 디렉토리이면 참
-b 파일명 : 파일이 존재하고 블록 장치 파일이면 참
-c 파일명 : 파일이 문자 전용 파일(character special file)이면 참
-u 파일명 : 파일이 set-user-ID 플래그가 세트되어 있으면 참
-g 파일명 : 파일이 set-group-ID 플래그가 세트되어 있으면 참
-k 파일명 : 파일이 sticky 비트가 세트되어 있으면 참
-s 파일명 : 파일의 크기가 0보다 크면 참
-t 파일 디스크립터 : 파일 디스크립터에 해당하는 파일이 열려 있고, 터미널 장치로부터 사용되고 있으면 참, 기본 디스크립터 값은 1이다.
-z 문자열 : 문자열의 길이가 0이면 참
-n 문자열 : 문자열의 길이가 t 이상이면 참
-문자열 1 = 문자열2 : 문자열1과 문자열2가 같으면 참
-문자열 1 != 문자열2 : 문자열1과 문자열2가 다르면 참
-문자열 : 문자열이 널(null)이 아니면 참, 널 문자열이면 거짓
-정수1-eq정수2 : 두 개의 정수1과 정수2가 같으면 참
-정수1-ne정수2 : 두 정수가 다르면 참
-정수1-gt정수2 : 정수1이 정수2 보다 크면 참
-정수1-ge정수2 : 정수1이 정수2 보다 크거나 같으면 참

이외에도 -lt(작으면) -le(작거나 같으면), !(논리부정), -a(AND), -o(OR) 등과 같은 표현을 사용할 수 있으며, 괄호를 사용할 수도 있다.

time
프로그램이 수행되는 시간을 측정한다.

설명
time의 인수로 측정하고자 하는 명령을 준다. time은 세 가지 다른 형태의 시간 측정 결과를 보고한다. 실제로 얼마만큼의 시간이 걸렸는가 하는 real 커널이 사용한 시간을 제외하고 CPU에서 소비된 시간을 나타내는 user그리고 실제로 얼마만큼의 커널 시간을 할애했는가 하는 sys시간이 있다. sys+user 시간이 실제로 작업에 할애된 시간이며, real 값에서 sys+user 값을 뺀 결과값은 다른 프로세서 처리에 할당된 시간이다.

top
프로세서의 상태를 실시간으로 확인한다.

설명
top명령어는 현재 시스템의 메모리의 상태를 실시간으로 점검할 수 있는 장점이 있다. 현재 사용중인 프로세서와 사용중인 메모리 및 스왑의 양이 출력된다. 시스템을 주의 관찰해야 되는 경우에 사용하면 상당히 도움이 된다.

touch
파일의 엑세스 시간이나 갱신 시간을 수정한다.
$ touch [option] file
$ [-acm] MMDDhhmm[YY] file (obsolescent)
-a   : change only the access time
-c   : do not create any files
-d, --date=STRING : parse STRING and use it instead of current time
-f    : (ignored)
-m   : change only the modification time
-r, --reference=FILE : use this file's times instead of current time
-t STAMP  : use [[CC]YY]MMDDhhmm[.ss] instead of current time
   --time=WORD : access -a, atime -a, mtime -m, modify -m, use -a
   --help  : display this help and exit
   --version  : output version information and exit

tr
특정한 문자들을 다른 문자로 변경한다. redirection과 함께 사용
$ tr [option] 변경할문자 변경문자
-c  : 파일의 모든 내용을 보이지 않고 바꾸는 작업만 보여준다.
-d  : 파일에서 변경할 문자를 제거한다.

설명
문자 표현시 백슬래쉬 문자 뒤에 8진법 숫자를 써서 문자 코드를 표현할 수 있다. 또한  [c1-c2]와 같은 하이픈 표현으로 문자의 범위를 지정할 수 있으며 [c*n]과 같은 방법으로 n 만큼의 문자 반복을 표현할 수도 있다. 변경할 문자의 변경 문자의 개수는 같아야 한다.

traceroute
네트웍크의 구간에 접속한 시간을 측정한다.
$ traceroute [IP Address 또는 Host]

true
셸 상에서 참의 의미를 가지는 0을 반환한다.

tty
현재 로그온 되어 있는 터미널의 장치 이름을 알려준다.
$ tty [-s]
-s  : 표준 입력이 터미널 장치인지 아닌지를 시험한다. 터미널이 표준이라면 0을 반환하며 아니면 1을 반환한다.
tty : 현재 사용하고 있는 단말 장치의 이름을 경로와 함께 표준 출력

umask
파일을 생성할 때 현재 사용되고 있는 권한(permission)값의 마스크가 무엇인지 알려주거나 그것을 새로 지정할 때 사용된다.
$ umask [마스크]
마스크 값은 세 자리의 8진법 숫자로 구성된다. 이것을 마스크라고 부르는 이유는 마스크 값의 각 비트가 들어오는 값을 걸러내는
역할을 하기 때문이다. 즉 마스크 값이 0이면 권한 지정에 제한을 두지 않는다는 것이고 6이라면 읽기와 쓰기에 제한을 가한다는
의미가 되기 때문이다.

umount
설정된 마운트 정보를 해제한다.
$ umount 장치면 or mount_piont
$ umount -a
$ umount -t file_system_type
-a  : 모든 파일 시스템의 마운트 정보를 해제한다.
-t  : 특정 형태의 파일 시스템만을 선택하여 해제된다. 옵션 뒤에는 어떤 파일 시스템을 해제할 것인지 지정한다.

uname
시스템 이름과 다른 정보를 보여준다.
$ uname [option]
-s  : 시스템 이름을 알려준다. (기본값으로 내장)
-n  : 시스템의 노드(node) 이름을 알려준다.
-r  : 오퍼레이팅 시스템의 증명번호를 알려준다.
-v  : 오퍼레이팅 시스템의 버전(version) 번호를 알려준다.
-m  : 하드웨어의 이름을 알려준다.
-a  : 모든 정보를 알려준다. -snrvm 과 같다.

uncompress
compress로 압축되어 있는 file의 압축을 푼다.
$ uncompress file_name(s)

실상, compress의 -d 옵션을 사용하면 압축을 풀 수 있기 때문에 이 명령은 불필요하다. 하지만 옵션을 사용하는 것보다
의미있는 단어를 사용함으로 좀더 친숙하게 사용할 수 있다. uncompress는 자신이 압축 풀기 동작을 수행하는 것이 아니라
-d 옵션을 주어 compress를 호출한다. uncompress 자신의 파일 크기는 아주 적다.

users
간단히 사용자들의 ID 이름만을 알고자 할때 사용한다.

uptime
서버 부팅시간과 현재 시간이 출력된다.

uundecode / uuencode
uuencode는 USENET과 같이 ASC2 코드만을 다루는 미디어를 위해 바이너리 코드를 변환한다.
uudecode는 그 반대의 동작을 수행한다.
$ uudecode file..
$ uuencode file.. 이름

사용예
$ uuencode canexe.Z canexe.Z > exemail.uu
canexe.Z 라는 파일을 인코딩 작업을 거친 후 exemail.uu라는 파일로 저장한다. 이 파일을 디코딩하면 canexe.Z라는 이름으로 파일이 만들어진다.

vi
vi 에디터. 유닉스 계열의 운영체제에서 가장 널리 쓰이는 에디터

vi 명령어 요약
1. 시작
vi file   : vi를 시작하여 지정한 파일 편집
vi -R file  : 읽기 전용(read- only) 편집기로서 vi를 시작하여 지정한 파일 편집
view file  : 읽기 전용(read- only) 편집기로서 vi를 시작하여 지정한 파일 편집

2. 종료
:wq   : 데이터를 저장하고 종료
:q!   : 데이터를 저장하지 않고 종료

3. 시스템이 다운된 후에 되살리기
vi -r   : 되살릴 수 있는 모든 파일 이름 보여주기
vi -r file   : vi를 시작하여 지정한 파일 되살리기

4. 디스플레이 제어하기
^L   : 현재 화면을 다시 디스플레이하기
:set number  : 내부 줄 번호 디스플레이
:set nonumber  : 배부 줄 번호 디스플레이 않기
5. 마지막으로 지운 것 복사하기
p   : 마지막으로 지워진 것을 커서의 뒤/아래에 삽입
P   : 마지막으로 지워진 것을 커서의 앞/위에 삽입
xp   : 두 문자를 바꿈
deep   : 두 단어를 바꿈
ddp   : 두 줄을 바꿈

6. 패턴 검색
/rexp   : 지정된 정규 표현식에 대해 앞으로 이동
/   : 이전의 패턴에 대해 앞으로 검색을 반복
?rexp   : 지정된 정규 표현식에 대해 뒤로 이동
?   : 이전의 패턴에 대해 뒤로 검색을 반복
n   : /나 ?명령에 대해 같은 방향으로 반복
N   : /나 ?명령에 대해 반대 방향으로 반복

7. 약어의 사용
:ab short long  : short를 long에 대한 약어로 변경
:ab   : 현재 약어 목록을 표시
:una short   : 약어 short를 표시

8. 줄 길이의 조정
r<Return>  : 문자를 뉴라인으로 변경
J   : 줄의 결합
:set wm=n  : 오른쪽으로 n문자 위치에서 자동적으로 줄 나눔

9. 커서 이동
h<Left>  : 커서를 한 칸 왼쪽으로 이동
j<Down>  : 커서를 한 줄 아래로 이동
k<Up>   : 커서를 한 줄 위로 이동
l<Right>  : 커서를 한 칸 오른쪽으로 이동

<Backspace>  : 커서를 한 칸 왼쪽으로 이동
<Space>  : 커서를 한 칸 오른쪽으로 이동
-   : 커서를 이전 줄의 처음으로 이동
+   : 커서를 다음 줄의 처음으로 이동
<Return>   : 커서를 다음 줄의 처음으로 이동
0   : 커서를 현재 줄의 맨 앞으로 이동
$   : 커서를 현재 줄의 맨 끝으로 이동
^   : 커서를 현재 줄의 첫글자(공백이나 탭이 아닌)로 이동
w   : 커서를 다음 단어의 첫 글자로 이동
e   : 커서를 다음 단어의 끝 글자로 이동
b   : 커서를 이전 단어의 첫 글자로 이동
W   : w와 같음(문장 부호 무시)
E   : e와 같음(문장 부호 무시)
B   : b와 같음(문장 부호 무시)
(   : 다음 문장의 처음으로 이동
)   : 이전 문장의 처음으로 이동
{   : 다음 문단의 처음으로 이동
}   : 이전 문단의 처음으로 이동
H   : 커서를 화면 맨 위로 이동
M   : 커서를 중간으로 이동
L   : 커서를 맨 아래로 이동

10. 편집 버퍼를 통한 이동
^F   : 한 화면 아래로 이동
^B    : 한 화면 위로 이동
n^F    : n화면 아래로 이동
n^B   : n화면 위로 이동
^D   : 반 화면 아래로 이동
^U   : 반 화면 위로 이동
n^D   : n줄만큼 아래로 이동
n^U   : n줄만큼 위로 이동
11. 셸 명령 실행
:!command  : vi를 중단하고 지정한 셸 명령을 실행
:!!   : vi를 중단하고 이전의 셸 명령을 실행
:sh   : vi를 중단하고 셸을 실행
:!csh    : vi를 중단하고 새로운 C-셸을 실행

12. 패턴에 의한 치환
:s/pattern/replace/ : 현재 줄의 치환
:lines/pattern/replace/ : 지정한 줄의 치환
:line,lines/pattern/replace/: 지정한 범위의 치환
:%s/pattern/replace/ : 모든 줄의 치환

13. 데이터 읽기
:liner file  : file의 내용을 지정한 줄 다음에 삽입
:r file   : file의 내용을 현재의 줄 다음에 삽입
:liner !command  : command의 결과를 지정한 줄 다음에 삽입
:r !command  : command의 결과를 현재의 줄 다음에 삽입
:r !look pattern   : 지정한 pattern으로 시작된 단어 삽입

14. 정규 표현식을 사용하기 위한 특수 기호
.   : 뉴라인을 제외한 모든 단일 문자와 대응
*   : 영 또는 그 이상의 선행 문자와 대응
^   : 줄의 시작과 대응
$   : 줄의 끝과 대응
\<   : 단어의 시작과 대응
\>   : 단어의 끝과 대응
[ ]   : 묶여진 문자중의 하나와 대응
[^ ]   : 묶여진 문자를 제외한 아무것하고나 대응
\   : 이어지는 기호를 문자 그대로 해석

15. 줄 번호
nG   : 줄번호 n으로 건너뛰기
1G   : 편집 버퍼의 첫 줄로 건너뛰기
G   : 편집 버퍼의 마지막 줄로 건너뛰기
:map g lG  : g가 lG와 같도록 매크로 정의

16. 삽입
i   : 입력 모드로 전환, 커서 위치 앞에서 삽입
a   : 입력 모드로 전환, 커서 위치 뒤에서 삽입
I   : 입력 모드로 전환, 현재 줄의 앞에 삽입
A   : 입력 모드로 전환, 현재 줄의 끝에 삽입
o   : 입력 모드로 전환, 현재 줄의 아래에 전개
O   : 입력 모드로 전환, 현재 줄의 위에 전개

17. 편집하고 있는 파일을 바꾸기
:e file   : 지정한 파일의 편집
:e! file   : 지정한 파일의 편집, 자동 점검의 생략

18. 내용 고치기
r   : 단지 한 글자만 변경(입력 모드로 바뀌지 않음)
R   : 입력하는 대로 겹쳐 써서 변경
s   : 삽입에 의해 한 단어의 변경
C   : 커서의 위치로부터 줄 끝까지 삽입에 의한 변경
cc   : 전체 줄을 삽입에 의한 변경
S   : 전체 줄을 삽입에 의한 변경
cmove   : 커서부터 move까지 삽입에 의해 변경
~   : 대,소문자 바꾸기
19. 고치기의 취소 또는 반복
u   : 편집 버퍼를 수정했던 마지막 명령을 취소
U   : 현재 줄을 저장
.   : 편집 버퍼를 수정했던 마지막 명령 반복

20. 문자 삭제
x   : 커서가 있는 문자 삭제
X   : 커서의 왼쪽 문자 삭제
D   : 커서부터 줄의 끝까지 삭제
dd   : 현재 줄의 전체 삭제
dmove   : 커서부터 move까지 삭제
dG   : 커서부터 편집 버퍼의 끝까지 삭제
d1G   : 커서부터 편집 버퍼의 맨 앞까지 삭제
:lined   : 지정한 줄의 삭제
:line, lined  : 지정한 범위의 삭제

21. 여러 줄의 복사와 이동
:linecotarget  : 지정한 줄을 복사하여 target 줄 밑에 삽입
:line, linecotarget : 지정한 범위를 복사하여 target 줄 밑에 삽입
:linemtarget  : 지정한 줄로 이동하여 target 줄 밑에 삽입
:line, linemtarget  : 지정한 범위로 이동하여target 줄 밑에 삽입

22. 데이터를 처리하기 위한 셸 명령의 사용
n!!command  : n번 줄에서 command의 실행
!move command  : 커서부터 move까지 command 실행
!move fmt  : 커서부터 move까지 줄들을 형식 맞추기

23. 데이터 저장하기
:w   : 원래의 파일로 데이터를 저장
:w file   : 지정한 파일로 데이터를 저장
:w>> file   : 지정한 파일에 데이터를 추가

w
현재 시스템에 접속한 사용자들의 정보를 출력한다.
$ w [user]

wait [작업번호] --백그라운드 실행 종료

wall
현재 시스템에 로그온되어 있는 모든 사용자들에게 메시지를 보낸다.
$ wall [message]
메시지는 각 사용자의터미널에 나타나게 된다. 인수로 파일 이름이 주어지지 않으면 표준 입력으로부터 데이터를 받아들이며, ^D로
입력을 종결하고 메시지를 발송한다. 이것을 사용하려면 슈퍼 유저로 로그인되어야 한다. 사용자가 자신의 터미널을 메시지 수신 거부
상태로 만들어 놓더라도 슈퍼 유저는 그것을 무시할 수 있다.

wc
file 내의 단어 수 등의 정보를 출력한다.
$ wc [option] file(s)
-c  : 문자(character)의 개수만을 알고 싶을 때 사용한다.
-w  : 단어(word)의 개수만을 알고 싶을 대 사용한다.
-l  : 행(line)의 숫자를 알고 싶을 때 사용한다. 혹은 개행 문자의 개수를 알고자 할 때 사용될 수도 있다.

whereis
문자열 또는 file을 검색한다.

which
등록된 path를 통해서 특정 프로그램을 찾는다.

who
현재의 시스템에 접속한 사용자의 이름이나 로그온 정보를 보여준다.
$ who [ -uTHqs ] [로그온 정보파일 ]
-u  : 현재 시스템에 누가 로그온되어 있는지 보여준다.
-T  : 사용자의 터미널이 메시지를 보낼 수 있는지를 알려준다. +기호는 메시지를 쓸 수 있고, -는 그렇지 않음을 보여준다.
-H  : 헤더 라인을 프린트한다.
-q  : 사용자 이름과 카운트가 구분된 목록을 보여줌, 다른 옵션은 무시된다.
-s  : 호환을 위해 포함된 옵션으로 무시된다.
who : 유닉스 시스템에 로그인 되어 있는 사용자들에 대한 정보를 화면에 표시

whoami
현재 접속한 계정명 확인 및 접속자의 정보를 출력한다.
$ whoami

write
사용자의 터미널 사이에 메시지를 전달한다.
$ write [user] [tty]

시지를 전달하고자 하는 사용자의 이름을 지정한다. 만일 한 사용자의 이름으로 두 명 이상이 사용중이면 특정 터미널을
지정하여(tty) 메시지를 전달할 수 있다. write는 표준 입력 장치로 전달할 메시지를 입력받는다. 각행에서 리턴 키를 누를
때마다 메시지가 전달되며, ^D를 누르면 그만둔다.

메시지가 수신되면 'Message from 보낸사람 터미널'등의 정보를 보여주어서
누가 어느 터미널에서 메시지를 보내는지를 알 수 있도록 한다. 보내고자 하는 사람이 로그인되어 있지 않다면 'user is
not logged on이라고' 알려주며 만일 그 사람의 터미널이 메시지 수신을 거부하고 있는 상태라면 'permission
denied 라는' 말을 보여준다. 그는 아마도 mesg n 명령을 사용했을 것이다.

xdm
X-Widows상에서 login screen을 보여준다.
어떤 system은 특정 level로 가도록 지정하면 xdm을 시동시킨다(/etc/inittab를 보도록).
리눅스 부팅 스크립트에 넣어두면 리눅스를 처음 부팅할 때부터 엑스윈도우로 부팅할 수 있다.

zcat
데이터를 다른 명령에 파이프 하려는 경우 사용하는 명령어

cat 명령과 똑같이 작업하지만 입력으로 압축된 파일이 필요하다.
zcat은 파일을 압축 해제한 후 표준 출력 디바이스에 프린트한다.
zcat namelist | program1 | program2 ...





출처 - http://2fered.pe.kr/756

'OS > 리눅스 & 유닉스' 카테고리의 다른 글

mail 전송의 원리  (0) 2014.09.18
큐메일  (0) 2014.09.18
POSIX Semaphore & System V Semaphore  (0) 2012.06.01
Speaking UNIX: 공유 메모리를 이용한 프로세스 간 통신(IPC)  (0) 2012.06.01
ibm aix polling  (0) 2012.05.31
:

POSIX Semaphore & System V Semaphore

OS/리눅스 & 유닉스 2012. 6. 1. 09:28


Contents

1 세마포어란 무엇인가
1.1 세마포어의 작동원리
2 System V 세마포어
2.1 세마포어의 사용
2.2 세마포어의 관리
2.3 semget 을 이용해서 세마포어를 만들자.
2.4 세마포어를 이용해서 접근제어 하기
2.5 세마포어 조작
2.6 예제
3 POSIX 세마포어
3.1 세마포어 만들기
3.2 세마포어 얻기 (기다리기)
3.3 세마포어 정보 가져오기
3.4 세마포어 되돌려주기
3.5 세마포어 삭제
3.6 POSIX 익명 세마포어 예제
3.7 이름있는 세마포어 예제
4 결론

1 세마포어란 무엇인가

세마포어(Semaphores)를 비록 IPC설비중의 하나로 분류하긴 했지만, 다른 파이프, 메시지큐FIFO등과는 좀다르다. 다른 IPC 설비들이 대부분 프로세스간 메시지 전송을 그 목적으로 하는데 반해서 세마포어는 프로세스간 데이타를 동기화 하고 보호하는데 그목적이 있다. POSIX세마포어와 System V 세마포어 모두를 다룰 계획이다.

프로세스간 메시지 전송을 하거나, 혹은 공유메모리를 통해서 특정 데이타를 공유하게 될경우 발생하는 문제가, 공유된 자원에 여러개의 프로세스가 동시에 접근을 하면 안되며, 단지 한번에 하나의 프로세스만 접근 가능하도록 만들어줘야 할것이다. 이것은 쓰레드에서 메시지간 동기화를 위해서 mutex 를 사용하는것과 같은 이유이다. 

하나의 데이타에 여러개의 프로세스가 관여할때 어떤 문제점이 발생할수 있는지 간단한 예를 들어보도록 하겠다.
int count=100;  
A 프로세스가 count를 읽어온다.     100 
B 프로세스가 count를 읽어온다.     100 
B 프로세스가 count를 1 증가 시킨다.  101  
A 프로세스가 count를 1 증가 시킨다.  101 
 
count는 공유자원(공유메모리 같은)이며 A와 B 프로그램이 여기에 대한 작업을 한다. A가 1을 증가 시키고 B가 1을 증가시키므로 최종 count 값은 102 가 되어야 할것이다. 그러나 A 가 작업을 마치기 전에 B가 작업을 하게 됨으로 엉뚱한 결과를 보여주게 되었다. 위의 문제를 해결하기 위해서는 count 에 A가 접근할때 B프로세스가 접근하지못하도록 block 시키고, A가 모든 작업을 마쳤을때 B프로세스가 작업을 할수 있도록 block 를 해제 시키면 될것이다.

우리는 세마포어를 이용해서 이러한 작업을 할수 있다. 한마디로 줄여서 세마포어는 "여러개의 프로세스에 의해서 공유된는 자원의 접근제어를 위한 도구" 이다.

1.1 세마포어의 작동원리

세마포어는 상호 배제알고리즘으로 임계 영역을 만들어서 자원을 보호한다. 작동원리는 매우 간단하다. 차단을 원하는 자원에대해서 세마포어를 생성하면 해당자원을 가리키는 세마포어 값이 할당된다. 이 세마포어값을 검사해서 임계영역에 접근할 수 있는지를 결정하게 된다. 

세마포어 값이 0이면 이 자원에 접근할수 없으며, 0보다 큰 정수면 해당 정수의 크기만큼의 프로세스가 자원에 접근할수 있다라는 뜻이 된다. 그러므로 우리는 접근제어를 해야하는 자원에 접근하기 전에 세마포어 값을 검사해서 값이 0이면 자원을 사용할수 있을때까지 기다리고, 0보다 더 크면(1이라고 가정하자) 자원에 접근하게 된다. 자원에 접근하면 세마포어 값을 1 감소해서 세마포어 값을 0으로 만들고 다른 프로세스가 자원에 접근할수 없도록 한다. 자원의 사용이 끝나면 세마포어 값을 다시 1증가시켜서 다른 프로세스가 자원을 사용할수 있도록 만들어주면 된다.

이렇게 보호되어야 하는 자원과 연산을 포함한 영역을 임계 영역 (Critical Section)이라고 한다. 세마포어는 임계 영역에 진입하기 위한 이다. 공용 사물함을 사용하기 위한 의 작동방식을 생각하면 된다.

 
세마포어의 이론적인 원리는 원자화문서를 참고하자.

2 System V 세마포어

2.1 세마포어의 사용

세마포어의 사용은 위의 작동원리를 그대로 적용한다. 즉 
  1. 임계 영역을 설정한다. 
  2. 임계 영역에 진입하기전에 세마포어 값을 확인한다. 
  3. 세마포어 값이 0보다 크면 세마포어를 가져온다. 세마포어를 가져왔으니 (커널의 입장에서)세마포어가 1감소 한다. 
  4. 세마포어 값이 0이면 값이 0보다 커질때까지 block 되며, 0보다 커지게 되면 2번 부터 시작하게 된다. 

이렇게 해서 임계 영역에 하나의 프로세스만 존재하도록 제어할 수 있다.
 
위의 작업을 위해서 Unix 는 다음과 같은 관련함수들을 제공한다. 
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <sys/sem.h>  
  
int semget(key_t key, int nsems, int semflg);  
int semop (int semid, struct sembuf *sops, unsigned nsops);  
int semctl(int semid, int semnum, int cmd, union semun arg);  
 

2.2 세마포어의 관리

세마포어는 그 특성상 원자화된 연산을 필요로 한다. 원자화된 연산은 유저레벨의 함수에서는 제공하기가 힘들므로, 세마포어 정보는 커널에서 전용 구조체를 이용해서 관리하게 된다. 다음은 커널에서 세모포어 정보를 유지하기 위해서 관리하는 구조체인 semid_ds 구조체의 모습이다. 

semid_ds는 /usr/include/bits/sem.h 에 선언되어 있다. (이것은 리눅스에서의 경우로 Unix 버젼에 따라서 위치와 멤버변수에 약간씩 차이가 있을수 있다) 
struct semid_ds 
{ 
    struct ipc_perm sem_perm;      
    __time_t sem_otime;            
    unsigned long int __unused1; 
    __time_t sem_ctime;            
    unsigned long int __unused2; 
    unsigned long int sem_nsems;   
    unsigned long int __unused3; 
    unsigned long int __unused4; 
}; 
 
sem_perm 은 세마포어에 대한 퍼미션으로 일반 파일퍼미션과 마찬가지의 기능을 제공한다. 즉 현재 세마포어 구조체에 접근할수 있는 사용자권한을 설정한다. sem_nsems 는 생성할수 있는 세마포어의 크기이다. sem_otime 은 마지막으로 세마포어관련 작업을 한 시간(semop 함수를 이용)이며, sem_ctim 은 마지막으로 구조체 정보가 바뀐 시간이다. 

2.3 semget 을 이용해서 세마포어를 만들자.

세마포어의 생성혹은 기존에 만들어져 있는 세마포어에 접근하기 위해서 유닉스에서 는 semget(2)를 제공한다. 첫번째 매개변수는 세마포어의 유일함을 보장하기 위해서 사용하는 키값이다. 우리는 이 키값으로 유일한 세마포어를 생성하거나 접근할 수 있다. 새로 생성되거나 기존의 세마포어에 접근하거나 하는것은 semflg 를 통해서 제어할수 있다. 다음은 semflg에서 사용할 수 있는 값이다.
  • IPC_CREAT
    만약 커널에 해당 key 값으로 존재하는 세마포어가 없다면, 새로 생성 한다. 
  • IPC_EXCL
    IPC_CREAT와 함께 사용하며, 해당 key 값으로 세마포어가 이미 존재한다면 실패값을 리턴한다. 

semflg 를 통해서 세마포어에 대한 퍼미션을 지정할수도 있다. 퍼미션 지정은 보통의 파일에 대해서 유저/그룹/other 에 대해서 지정하는것과 같다. 

만약 IPC_CREAT 만 사용할경우 해당 key 값으로 존재하는 세마포어가 없다면, 새로 생성하고, 이미 존재한다면 존재하는 세마포어의 id 를 넘겨준다. IPC_EXCL을 사용하면 key 값으로 존재하는 세마포어가 없을경우 새로 생성되고, 이미 존재한다면 존재하는 id 값을 돌려주지 않고 실패값(-1)을 되돌려주고, errno 를 설정한다.

nsems 은 세마포어 셋 즉 배열의 크기다. 이값은 최초 세마포어를 생성하는 생성자의 경우에 크기가 필요하다(보통 1). 그외에 세마포어에 접근해서 사용하는 소비자의 경우에는 세마포어를 만들지 않고 단지 접근만 할뿐임으로 크기는 0이 된다. 

이상의 내용을 정리하면 semget 은 아래와 같이 사용할수 있을것이다. 
만약 최초 생성이라면 
    sem_num = 1; 
그렇지 않고 만들어진 세마포어에 접근하는 것이라면 
    sem_num = 0;  
sem_id = semget(12345, sem_num, IPC_CREAT|0660)) == -1) 
{ 
    perror("semget error : "); 
    return -1; 
} 
 
semget 은 성공할경우 int 형의 세마포어 식별자를 되돌려주며, 모든 세마포어에 대한 접근은 이 세마포어 실별자를 사용한다. 

위의 코드는 key 12345 를 이용해서 세마포어를 생성하며 퍼미션은 0660으로 설정된다. 세마포어의 크기는 1로 잡혀 있다(대부분의 경우 1). 

만약 기존에 key 12345 로 이미 만들어진 세마포어가 있다면 새로 생성하지 않고 기존의 세마포어에 접근할수 있는 세마포어 식별자를 되돌려주게 되고, 커널은 semget 를 통해 넘어온 정보를 이용해서 semid_ds 구조체를 세팅한다.

예제: semget.c
#include <sys/types.h>  
#include <sys/ipc.h>  
#include <sys/sem.h>  
 
int main() 
{ 
    int semid; 
    semid = semget((key_t)12345, 1, 0666 | IPC_CREAT); 
} 
 
이제 위의 코드를 컴파일해서 실행시키고 나서 실제로 세마포어 정보가 어떻게 바뀌였는지 확인해 보도록 하자. 커널에서 관리되는 ipc 정보를 알아보기 위해서는 ipcs(8)라는 도구를 이용하면 된다.
[root@localhost test]# ipcs -s     
------ Semaphore Arrays -------- 
key        semid      owner      perms      nsems      status       
0x00003039 0          root      666        1          
 

0x00003039 은 key 12345 의 16진수 표현이다. 퍼미션은 666으로 되어 있고 semget 를 통해서 제대로 설정되어 있음을 알수 있다. 

2.4 세마포어를 이용해서 접근제어 하기

이제 semget을 통해서 세마포어를 새로 만들고 얻었으니, 이제 실제로 세마포어상태를 검사해서 접근제어를 해보도록하자. 접근제어는 세마포어를 얻거나 되돌려 주는 방식으로 이루어진다. semop함수로 이러한 일들을 할 수 있다. 

int semop(int semid, struct sembuf *sops, unsigned nsops); 
 
semop의 첫번째 semid 는 semget 을 통해서 얻은 세마포어 식별자이다. 2번째 아규먼트는 struct sembuf 로써, 어떤 연산을 이루어지게 할런지 결정하기 위해서 사용된다. 구조체의 내은 다음과 같으며, sys/sem.h 에 선언되어 있다. 
struct sembuf 
{ 
    short sem_num;    // 세마포어의수 
    short sem_op;     // 세마포어 연산지정 
    short sem_flg;    // 연산옵션(flag) 
} 
 
sem_num 멤버는 세마포어의 수로 여러개의 세마포어를 사용하지 않는다면(즉 배열이 아닐경우) 0을 사용한다. 배열의 인덱스 사이즈라고 생각하면 될것이다. 보통의 경우 하나의 세마포어를 지정해서 사용하므로 0 이 될것이다.

sem_op 를 이용해서 실질적으로 세마포어 연산을 하게 되며, 이것을 이용해서 세마포어 값을 증가시키거나 감소 시킬수 잇다. sem_op 값이 양수일 경우는 자원을 다 썼으니, 세마포어 값을 증가시키겠다는 뜻이며, 음수일 경우에는 세마포어를 사용할것을 요청한다라는 뜻이다. 

음수일 경우 세마포어값이 충분하다면 세마포어를 사용할수 있으며, 커널은 세마포어의 값을 음수의 크기의 절대값만큼을 세마포어에서 빼준다. 만약 세마포어의 값이 충분하지 않다면 세번째 아규먼트인 sem_flg 에 따라서 행동이 결정되는데, sem_flg 가 IPC_NOWAIT로 명시되어 있다면, 해당영역에서 기다리지 않고(none block) 바로 에러코드를 리턴한다. 그렇지 않다면 세마포어를 획득할수 있을때까지 block 되게 된다. 

sem_flg 는 IPC_NOWAIT 와 SEM_UNDO 2개의 설정할수 있는 값을가지고 있다. IPC_NOWAIT 는 none block 모드 지정을 위해서 사용되며, SEM_UNDO 는 프로세스가 세마포어를 돌려주지 않고 종료해버릴경우 커널에서 알아서 세마포어 값을 조정(증가)
할수 있도록 만들어 준다. 

설명이 아마 애매모호한면이 있을것이다. 간단한 상황을 예로 들어서 설명해 보겠다.
현재 세마포어 값이 1 이라고 가정하자.  
이때 A 프로세스가 semop 를 통해서 세마포어에 접근을 시도한다.  
A는 접근을 위해서 sem_op 에 -1 을 세팅한다. 즉 세마포어 자원을 1 만큼 사용하겠다라는  
뜻이다.    
현재 준비된 세마포어 값은 1로 즉시 사용할수 있으므로,  
A는 자원을 사용하게 되며, 커널은 세마포어 값을 1 만큼 감소시킨다.  
 
이때 B 라는 프로세스가 세마포어 자원을 1 만큼 사용하겠다라고 요청을 한다.  
그러나 지금 세마포어 값은 0 이므로 B는 지금당장 세마포어 를 사용할수 없으며,  
기다리거나, 에러값을 리턴 받아야 한다(IPC_NOWAIT).    
B는 자원 사용가능할때까지 기다리기로 결정을 했다.   
 
잠수후 A는 모든 작업을 다마쳤다.  
이제 세마포어를 되돌려줘야 한다. sem_op 에 1 을 세팅하면,  
커널은 세마포어 값을 1증가시키게 된다.  
 
드디어 기다리던 B가 세마포어 자원을 사용할수 있는 때가 도래했다.  
이제 세마포어 값은 1이 므로 B는 세마포어를 획득하게 된다.   
커널은 세마포어 값을 1 감소 시킨다. 
B는 원하는 작업을 한다. 
... 
... 
 

2.5 세마포어 조작

semctl 이란 함수를 이용해서 우리는 세마포어를 조정할수 있다. 

semctl 은 semid_ds 구조체를 변경함으로써 세마포어의 특성을 조정한다.

첫번째 아규먼트인 semid 는 세마포어 식별자다. semnum 은 세마포어 배열에서 몇 번째 세마포어를 사용할지를 선택하기 위해서 사용한다. 세마포어의 크기가 1이라면 0이 된다. (배열은 0번 부터 시작하기 때문) cmd 는 세마포어 조작명령어 셋으로 다음과 같은 조작명령어들을 가지고 있다. 아래는 그중 중요하다고 생각되는 것들만을 설명하였다. 더 자세한 내용은 semctl 에 대한 man 페이지를 참고하기 바란다. 
  • IPC_STAT
    세마포어 상태값을 얻어오기 위해 사용되며, 상태값은 arg 에 저장된다. 
  • IPC_RMID
    세마포어 를 삭제하기 위해서 사용한다. 
  • IPC_SET
    semid_ds 의 ipc_perm 정보를 변경함으로써 세마포어에 대한 권한을 변경한다.

2.6 예제

지금까지 익혔던 내용을 토대로 간단한 예제프로그램을 만들어보겠다. 예제의 상황은 하나의 파일에 2개의 프로세스가 동시에 접근하고자 하는데에서 발생한다. 파일에는 count 숫자가 들어 있으며, 프로세스는 파일을 열어서 count 숫자를 읽어들이고, 여기에 1을 더해서 다시 저장하는 작업을한다. 이것을 세마포어를 통해서 제어하지 않으면 위에서 설명한 문제가 발생할것이다.

위의 문제를 해결하기 위해서는 파일을 열기전에 세마포어를 설정해서 한번에 하나의 프로세스만 접근가능하도록 하면 될것이다. 모든 파일작업을 마치게 되면, 세마포어 자원을 돌려줌으로써, 비로서 다른 프로세스가 접근가능하게 만들어야 한다.

예제: sem_test
#include <sys/types.h>  
#include <sys/sem.h>  
#include <sys/ipc.h>  
#include <stdio.h>  
#include <unistd.h>  
 
#define SEMKEY 2345  
 
union semun 
{ 
    int val; 
    struct semid_ds *buf; 
    unsigned short int *array; 
}; 
 
static int  semid; 
int main(int argc, char **argv) 
{ 
    FILE* fp; 
    char buf[11]; 
    char count[11]; 
 
    union semun sem_union;  
 
    // open 과 close 를 위한 sembuf 구조체를 정의한다.  
    struct sembuf mysem_open  = {0, -1, SEM_UNDO}; // 세마포어 얻기 
    struct sembuf mysem_close = {0, 1, SEM_UNDO};  // 세마포어 돌려주기 
    int sem_num; 
 
    memset(buf, 0x00, 11); 
    memset(count, 0x00, 11); 
 
    // 아규먼트가 있으면 생성자 
    // 그렇지 않으면 소비자이다. 
    if (argc > 1) 
        sem_num = 1; 
    else  
        sem_num = 0;             
 
    // 세마포설정을 한다.  
    semid = semget((key_t)234, sem_num, 0660|IPC_CREAT); 
    if (semid == -1) 
    { 
        perror("semget error "); 
        exit(0); 
    }     
 
// 세마포어 초기화 
        sem_union.val = 1; 
        if ( -1 == semctl( semid, 0, SETVAL, sem_union)) 
        {    
                printf( "semctl()-SETVAL 실행 오류\n"); 
                return -1;  
        }    
    // counter.txt 파일을 열기 위해서 세마포어검사를한다.  
    if(semop(semid, &mysem_open, 1) == -1) 
    { 
        perror("semop error "); 
        exit(0); 
    } 
 
    if ((fp = fopen("counter.txt", "r+")) == NULL) 
    { 
        perror("fopen error "); 
        exit(0); 
    } 
    // 파일의 내용을 읽은후 파일을 처음으로 되돌린다.   
    fgets(buf, 11, fp); 
    rewind(fp); 
 
    // 개행문자를 제거한다.  
    buf[strlen(buf) - 1] = 0x00; 
 
    sprintf(count, "%d\n", atoi(buf) + 1);  
    printf("%s", count); 
    // 10초를 잠들고 난후 count 를 파일에 쓴다.  
    sleep(10); 
    fputs(count,fp); 
 
    fclose(fp); 
    // 모든 작업을 마쳤다면 세마포어 자원을 되될려준다 
    semop(semid, &mysem_close, 1); 
    return 1; 
} 
 
코드는 매우 간단하지만, 세마포어에 대한 기본적인 이해를 충분히 할수 있을만한 코드이다. 생성자와 소비자의 분리는 프로그램에 넘겨지는 아규먼트를 이용했다. 모든 작업을 마치면 테스트를 위해서 10초를 기다린후에 세마포어를 돌려주도록 코딩되어 있다.

우선 count 를 저장할 파일 counter.txt 를 만들고 여기에는 1을 저장해 놓는다.
그다음 ./sem_test 를 실행시키는데, 최초에는 생성자를 만들어야 하므로 아규먼트를 주어서 실행시키고, 그다음에 실행시킬때는 소비자가 되므로 아규먼트 없이 실행하도록 하자. 다음은 테스트 방법이다.
[root@coco test]# ./sem_test 1 
[1] 3473 
36 
[root@coco test]# ./sem_test 
 
위 코드를 실행해보면 ./sem_test 1 이 세마포어자원을 돌려주기 전까지 ./sem_test 가 해당영역에서(세마포어 요청하는 부분) 블럭되어 있음을 알수 있고, 충돌없이 count가 잘되는것을 볼수 있을것이다. 

세마포어는 커널에서 관리하는데 세마포어를 사용하는 프로세스가 없다고 하더라도 semctl 을 이용해서 제거하지 않는한은 커널에 남아있게 된다. 세마포어 정보를 제거하기 위해서는 semctl 연산을 하든지, 컴퓨터를 리붓 시커거나, ipcrm(8)이란 도구를 사용해서 제거시켜 줘야 한다. 

3 POSIX 세마포어

POSIX 규격을 따르는 새로운 세마포어 인터페이스로 전통적인 System V 인터페이스에 비해서 좀 더 명확하다. 또한 세마포어 집합이란 개념이 없는데, 덕분에 이해하기가 수월해진 것 같다. 

POSIX 세마포어 함수를 사용하기 위해서는 -lrt로 리얼타임 라이브러리를 링크해야 한다.
# gcc -lrt sem_test sem_test.c 
 

3.1 세마포어 만들기

세마포어는 "익명 세마포어 (unnamed-)"와 "이름 있는 세마포어 (named-)"가 있다.

익명 세마포어는 sem_init로 만든다.
#include <semaphore.h> 
 
int sem_init(sem_t *sem, int pshared, unsigned int value); 
 
  • sem : 초기화할 세마포어 객체 
  • pshared : 0이 아니면 프로세스들 간에 세마포어를 공유한다. 0이면 프로세스 내부에서만 사용한다. 
  • value : 세마포어 초기 값 
사용 예
sem_init(&sem_name, 0, 10); 
 

이름 있는 세마포어는 sem_open으로 만든다.
sem_t* sem_open(const char* name, int oflag, mode_t mode, unsigned int value); 
 
이름 있는 세마포어는 파일로 만들어지기 때문에, 파일 이름과 권한설정이 필요하다. 세마포어 파일은 /dev/shm에 만들어진다. 그러므로 /dev/shm을 마운트 시켜줘야 한다.
# mount /dev/shm 
 

3.2 세마포어 얻기 (기다리기)

세마포어를 얻을 때까지 기다린다.
sem_wait(sem_t *sem); 
sem_trywait(sem_t *sem); 
sem_timedwait(sem_t *sem, const struct timespec *abs_timeout); 
 
sem_wait함수는 만약 세마포어 값이 0보다 크면 프로세스는 세마포어를 얻고 세마포어를 감소하고 즉시 반환한다. 세마포어값이 0이라면 세마포어가 0보다 더 커지거나 시그널이 발생할 때까지 대기한다.

sem_trywait는 즉시 세마포어를 감소시키고 반환하는 것을 제외하고는 sem_wait와 같다. 

timeout시간동안의 제한시간을 가진다는 것을 제외하고는 sem_wait함수와 같다. stimespec구조체를 이용해서 초+나노초 수준에서 제한시간을 지정할 수 있다.
struct timespec  
{ 
    time_t tv_sec;        /* Seconds */ 
    long   tv_nsec;       /* Nano Seconds */ 
}; 
 
제한 시간내에 세마포어를 얻지 못하면 errno 값으로 ETIMEDOUT을 설정하고 반환한다.

3.3 세마포어 정보 가져오기

#include <semaphore.h> 
 
int sem_getvalue(sem_t *sem, int *sval); 
 
현재 세마포어의 값을 알아온다. 값은 sval로 넘어온다.

3.4 세마포어 되돌려주기

sem_pos함수로 세마포어를 되돌려준다. 세마포어 값이 하나 증가한다.
#include <semaphore.h> 
 
int sem_post(sem_t *sem); 
 

3.5 세마포어 삭제

sem_unlink함수로 세마포어를 삭제한다. 이름있는 세마포어를 삭제하고자 할때 사용한다.
#include <semaphore.h> 
 
int sem_unlink(const char *name); 
 

3.6 POSIX 익명 세마포어 예제

뮤텍스 대신 세마포어로 임계영역을 관리했다.
#include <semaphore.h> 
#include <stdio.h> 
#include <unistd.h> 
#include <stdlib.h> 
#include <pthread.h> 
 
#define MAX_THREAD_NUM  2 
int count = 0; 
sem_t mysem; 
void *t_function(void *data) 
{ 
    pthread_t id; 
    int tmp; 
    id = pthread_self(); 
    printf("Thread %lu Created.\n", id); 
    while(1) 
    { 
        sem_wait(&mysem); 
        tmp = count; 
        tmp = tmp + 1; 
        sleep(1); 
        count = tmp; 
        printf("%lu : %d\n", id, count); 
        sem_post(&mysem); 
        usleep(1); 
    } 
} 
int main(int argc, char **argv) 
{ 
    pthread_t p_thread[MAX_THREAD_NUM]; 
    int thr_id; 
    int status; 
    int i = 0; 
 
    if (sem_init(&mysem, 0, 1) == -1) 
    { 
        perror("Error"); 
        exit(0); 
    } 
    for( i = 0; i < MAX_THREAD_NUM; i++) 
    { 
        // 쓰레드 생성 아규먼트로 2 를 넘긴다.   
        thr_id = pthread_create(&p_thread[i], NULL, t_function, (void *)&i); 
        if (thr_id < 0) 
        { 
            perror("thread create error : "); 
            exit(0); 
        } 
    } 
    pthread_join(p_thread[0], NULL); 
    pthread_join(p_thread[1], NULL); 
    return 0; 
} 
 

3.7 이름있는 세마포어 예제

세마포어 생산자
#include <semaphore.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
 
#include <stdlib.h> 
#include <stdio.h> 
 
const char *countFile = "count.db"; 
int main(int argc, char **argv) 
{ 
    int count = 100; 
    int fd; 
    sem_t *mysem; 
    sem_unlink("mysem"); 
    if((mysem = sem_open("mysem", O_CREAT, 0777, 1)) == NULL) 
    { 
        perror("Sem Open Error"); 
        return 1; 
    } 
    if( (fd = open(countFile,O_CREAT|O_RDWR, S_IRUSR|S_IWUSR )) == -1) 
    { 
        perror("Open Error\n"); 
        return 1; 
    } 
    while(1) 
    { 
        sem_wait(mysem); 
        lseek(fd, 0, SEEK_SET); 
        read(fd, (void *)&count, sizeof(count)); 
        printf("Read Data %d\n",count); 
        count++; 
        lseek(fd, 0, SEEK_SET); 
        write(fd, (void *)&count, sizeof(count)); 
        sem_post(mysem); 
        sleep(1); 
    } 
    close(fd); 
} 
 

소비자
#include <semaphore.h> 
#include <sys/types.h> 
#include <fcntl.h> 
#include <sys/stat.h> 
 
#include <stdlib.h>  
#include <stdio.h> 
         
const char *countFile = "count.db"; 
int main(int argc, char **argv) 
{        
        int count = 100; 
        int fd;  
        sem_t *mysem; 
        if((mysem = sem_open("mysem", 0, 0777, 0)) == SEM_FAILED) 
        { 
                perror("Sem Open Error"); 
                return 1; 
        } 
        if( (fd = open(countFile,O_RDWR)) == -1) 
        { 
                perror("Open Error\n"); 
                return 1; 
        } 
        while(1) 
        {        
                sem_wait(mysem); 
                lseek(fd, 0, SEEK_SET); 
                read(fd, (void *)&count, sizeof(count)); 
                printf("Read Data %d\n",count); 
                 
                count++;  
                lseek(fd, 0, SEEK_SET); 
                write(fd, (void *)&count, sizeof(count)); 
                sem_post(mysem); 
                sleep(1);  
        }        
        close(fd); 
}                
 

4 결론

fcntl()이용한 잠금으로도 세마포어와 비슷한 일을 수행할 수 있는데, fcntl보다 좀더 세밀한 조정이 가능하다라는 장점을 가지고 있다. 세밀한 만큼, 간단한 일을 하기에는 지나치게 복잡한 면이 있으니, 상황에 따라서 적절하게 선택하면 된다. 

fcntl의 잠금을 이용한 자원접근 제어는 fcntl을 이용한 파일/레코드 잠금 문서를 참고하기 바란다.

'OS > 리눅스 & 유닉스' 카테고리의 다른 글

큐메일  (0) 2014.09.18
리눅스 명령어 모음  (0) 2012.07.05
Speaking UNIX: 공유 메모리를 이용한 프로세스 간 통신(IPC)  (0) 2012.06.01
ibm aix polling  (0) 2012.05.31
공유 메모리 (shared memory)  (0) 2012.05.29
:

Speaking UNIX: 공유 메모리를 이용한 프로세스 간 통신(IPC)

OS/리눅스 & 유닉스 2012. 6. 1. 09:04

겉모습으로 볼 때, UNIX® 애플리케이션은 기본 호스트의 명령을 전적으로 따르는 것으로 보인다. UNIX 애플리케이션은 프로세서에 자유롭게 액세스할 준비가 되어 있고, 그 메모리는 신성 불가침의 영역이며, 연결된 장치들은 애플리케이션이 부리는 모든 변덕도 다 받아준다. 그러나 "겉모습만 보고는 알 수 없다"는 말도 있듯이, UNIX 애플리케이션이 그렇듯 뭐든 다 할 수 있을 것 같은 생각은 사람들의 뇌리에 교묘하게 각인된 착각이다. UNIX 시스템은 거의 무제한적으로 애플리케이션을 동시에 실행하면서, 무엇보다도 유한한 실제 자원을 현명하게 공유한다. 프로세서 용량은 조금씩만 분배되고, 애플리케이션 이미지는 늘 실제 메모리의 안팎에서 뒤섞이고, 장치 액세스는 요구에 따라 이루어지고 액세스 권한에 의해 단속된다. 친절하게도 쉘 프롬프트가 깜박거려도, UNIX 시스템은 왕성한 활동력을 보인다.

자주 사용하는 약어

  • API:Application programming interface
  • IPv4:Internet Protocol version 4
  • IPv6:Internet Protocol version 6
  • POSIX:Portable Operating System Interface for UNIX

복잡도가 문제가 되더라도, 대부분의 애플리케이션들은 다행히도 공유 테넌시를 잘 감지하지 못한다. 하지만, 애플리케이션들이 서로 상호 작용하도록 애플리케이션을 작성할 수 있다. 예를 들어, 한 애플리케이션이 데이터를 수집하거나 생성하는 동안, 다른 애플리케이션은 진행률을 모니터하고 정보를 동시에 분석할 수 있다. 메시지를 즉시 교환하는 채팅은 애플리케이션이 상대방에게 데이터를 전송하는 동시에 그로부터 데이터를 수신하는 협력 코드의 또 다른 예다. ssh(Secure Shell) 역시 완전히 다른 두 호스트 간에 조화를 이룰 잠재력이 있다. 각각의 예에서 코드는 독립된 다른 코드에 연결하여 정보를 스왑하는데, 이때 종종 이런 교환을 협상하고 제어하기 위한 프로토콜을 사용한다.

UNIX는 그런 프로세스 간 통신을 위한 다양한 기술을 제공한다. 어떤 기술들은 같은 호스트에서의 통신을 위한 것인 반면, 다른 기술들은 호스트 간 교환을 용이하게 하기 위한 것이다. 또한, 기술마다 속도가 다르므로 자신의 요구사항에 가장 적합한 옵션을 선택해야 한다. 타이밍과 배타성을 적용하는 조정도 늘 필수적이다. 예를 들어, 한 애플리케이션에서 데이터를 생산하고 다른 애플리케이션이 이 데이터를 사용하는 경우, 데이터 소비자는 일시 중지하고 공유 풀을 소진할 때마다 데이터 생산자를 기다려야 한다. 재귀적으로, 생산자는 소비자가 풀을 충분히 빨리 고갈시킬 수 없는 경우 느려지거나 속도를 잃을 수 있다.

아래의 표 1은 전형적인 UNIX 시스템에서 사용 가능한 프로세스 간 통신(IPC)의 형태를 요약한 것이다.


표 1. UNIX에서의 프로세스 간 통신
이름설명범위용도
파일데이터가 일반적인 UNIX 파일에 기록되고 그 파일에서 읽혀진다. 수에 관계없이 프로세스들끼리 상호 운용 가능하다.로컬큰 데이터 세트 공유
파이프전용 파일 디스크립터를 사용하여 두 프로세스 간에 데이터가 전송된다. 상위 프로세스와 하위 프로세스 간에만 통신이 이루어진다.로컬생산자 및 소비자와 같은 간단한 데이터 공유
이름 지정된 파이프전용 파일 디스크립터를 통해 프로세스 간에 데이터가 교환된다. 같은 호스트 상의 두 상대 프로세스 사이에서 통신이 이루어질 수 있다.로컬MySQL 서버와 이 서버의 명령행 쿼리 유틸리티로 보여줄 수 있는 것처럼, 생산자와 소비자 또는 명령과 제어
신호인터럽트가 발생하여 애플리케이션에 특정 조건을 경고한다.로컬신호로 데이터를 전송할 수 없으므로, 주로 프로세스 관리에 유용함
공유 메모리메모리의 공통 세그먼트에서 읽고 써서 정보를 공유한다.로컬특히 보안이 필수적이 경우 종류를 막론한 모든 협력 작업
소켓특수한 설정 후, 공통 입/출력(I/O) 연산을 이용해 데이터가 전송된다.로컬 또는 원격FTP, ssh 및 Apache 웹 서버와 같은 네트워크 서비스

위에서 언급한 바와 같이, 각각의 기술은 특정 요구에 적합하다. 여러 프로세스 간의 조정이 대체로 똑같이 복잡하다고 가정하면, 각각의 접근 방식에는 저마다 다음과 같은 장단점이 있다.

  • 친숙한 파일 작업을 사용하므로, 공통 UNIX 파일을 통한 데이터 공유가 간단한 방법이다. 하지만, 파일 시스템을 통해 데이터를 공유하는 것은 본래 느린데, 그 이유는 데이터 입력 및 출력 작업이 메모리의 편의성을 따라갈 수 없기 때문이다. 더욱이, 파일만 통해 읽기 및 쓰기를 조정하기는 어렵다. 궁극적으로, 루트 및 다른 권한을 가진 사용자가 파일에 저장된 정보에 액세스할 수 있기 때문에 파일에 중요한 데이터를 저장하는 것은 안전하지 않다. 어떤 점에서는, 읽기 전용 또는 쓰기 전용으로 볼 때 파일을 사용하는 것이 최선이다.
  • 파이프와 이름 지정된 파이프 역시 간단한 메커니즘이다. 둘 모두 연결의 각 끝점에서 두 개의 표준 파일 디스크립터를 사용하는데, 하나는 읽기 작업, 다른 하나는 쓰기 작업 전용이다. 그러나 파이프는 임의의 두 프로세스 간이 아니라, 상위 프로세스와 하위 프로세스 간에만 사용할 수 있다. 이름 지정된 파이프는 후자의 단점을 해결하므로, 같은 시스템에서의 데이터 교환에 적합하다. 하지만, 파이프나 이름 지정된 파이프 모두 각각 선입선출(FIFO) 장치로 작동하므로 임의 액세스를 제공하지 않는다.
  • 신호는 프로세스 간에 데이터를 전송할 수 없다. 일반적으로, 신호는 프로세스 간에 예외적 조건을 통신하는 데만 사용되어야 한다.
  • 공유 메모리는 메모리를 사용하여 빠른 임의 액세스를 허용하기 때문에 더 큰 메모리 콜렉션에 적합하다. 공유 메모리는 구현하기가 조금 더 복잡하지만, 그 밖의 점에서는 여러 프로세스 간의 호스트 내부 협업에서 진가를 발휘한다.
  • 소켓은 이름 지정된 파이프와 흡사한 기능을 수행하지만 여러 호스트를 그 대상으로 할 수 있다. 로컬 소켓(UNIX 소켓이라고도 함)은 로컬 (동일 호스트) 연결로 한정된다. 각각 IPv4 및 IPv6를 사용하는 Inet  Inet6 소켓은 원격 연결을 허용한다(그리고 로컬 시스템의 인터넷 주소 지정을 통해 로컬 연결을 허용함). 분산 처리 또는 웹 브라우저와 같은 모든 네트워킹 애플리케이션에는 분명히 소켓을 선택하는 것이 최선이다. 이름 지정된 파이프보다 코딩이 약간 더 복잡하지만, 어느 UNIX 네트워크 프로그래밍 서적에서든 패턴이 잘 확립되어 문서화되어 있다.

호스트  애플리케이션은 무시하고, 같은 호스트에서 공유 메모리의 프로세스 간 통신을 살펴보자.

공유 메모리의 작동 방식

그 이름이 암시하는 바와 같이, 공유 메모리는 메모리의 세그먼트가 두 개 이상의 프로세스에 액세스할 수 있게 만든다. 특수한 시스템 호출이나 UNIX 커널에 대한 요청으로 메모리를 할당하고 공간을 늘리며 사용 권한을 설정한다. 공통적인 읽기 및 쓰기 작업으로 해당 영역에서 데이터를 가져오거나 데이터를 기록한다.

공유 메모리는 어떤 프로세스의 자체 메모리에서 빼온 것이 아니며, 항상 비밀로 유지된다. 그 대신, 공유 메모리는 시스템의 사용 가능한 메모리 풀에서 할당되고 액세스를 원하는 각 프로세스에 의해 부가된다. 부가는 맵핑으로 불리고, 여기서 메모리의 공유 세그먼트가 각 프로세스의 자체 주소 공간에서 로컬 주소로 지정된다. 그림 1, 그림 2, 그림 3  그림 4에 프로세스가 설명되어 있다.

  1. 그림 1에 나타낸 것처럼, A와 B라는 두 프로세스가 같은 시스템에서 작동하고 있고 특히 공유 메모리를 통해 정보를 조정하고 공유하도록 코딩되었다고 가정하자. 그림에서 애플리케이션들이 동일할 필요는 없다는 점을 강조하기 위해 A와 B의 크기는 불균형하다. 

    그림 1. 한 호스트에서 작동하면서 서로 다른 코드를 실행하는 두 프로세스 
    한 호스트에서 작동하면서 서로 다른 코드를 실행하는 두 프로세스 

  2. 그림 2에서 프로세스 A는 공유 메모리의 세그먼트를 요청한다. 프로세스 A는 메모리 세그먼트를 초기화하여 사용할 준비를 한다. 또한, 이 프로세스는 다른 프로세스들이 찾을 수 있도록 세그먼트의 이름을 지정한다. 일반적으로, 세그먼트 이름은 동적으로 지정되지 않는다. 그 대신, 세그먼트 이름은 헤더 파일의 상수와 같이 잘 알려져 있고 다른 코드에서 쉽게 참조된다. 

    그림 2. 한 프로세스에서 공유 메모리 세그먼트 요청 
    한 프로세스에서 공유 메모리 세그먼트 요청 

  3. 프로세스 A는 공유 메모리 세그먼트를 자체 주소 공간으로 합병하거나 맵핑한다. 프로세스 B는 이름 지정된 파이프를 통해 세그먼트를 찾고, 이 세그먼트를 주소 공간으로 맵핑도 한다. 이것은 그림 3에도 표시되어 있다. 두 프로세스 모두 공유 메모리 세그먼트의 크기만큼 확대된다. 

    그림 3. 두 프로세스 모두 공유 메모리 세그먼트를 합병 또는 맵핑 
    두 프로세스 모두 공유 메모리 세그먼트를 합병 또는 맵핑 

  4. 마지막으로, 그림 4에서는 프로세스 A와 B가 공유 메모리 세그먼트에서 자유롭게 읽고 쓸 수 있다. 공유 메모리는 로컬 프로세스 메모리와 동일하게 취급된다. read() write()는 정상적으로 작동한다. 

    그림 4. 이제 둘 이상의 프로세스가 공통 메모리를 통해 데이터를 공유할 수 있음 
    이제 둘 이상의 프로세스가 공통 메모리를 통해 데이터를 공유할 수 있음 

위 그림들에 표시된 작업 중 많은 부분이 UNIX 공유 메모리 API에 캡처된다. 사실, 공유 메모리 API에는 POSIX API와 더 오래되었지만 그에 못지않게 효과적인 System V API라는 두 가지 변형이 있다. POSIX는 UNIX 및 Linux®와 이들로부터 파생된 시스템에서 주로 볼 수 있는 승인 표준이므로, 그 버전을 사용하자. 그 밖에도, POSIX API는 읽기 및 쓰기를 위해 간단한 파일 디스크립터를 사용하므로, 훨씬 더 친숙하게 보일 것이다.

POSIX는 공유 메모리 세그먼트를 작성, 맵핑, 동기화 및 실행 취소하기 위해 다섯 개의 시작점을 제공한다.

  • shm_open(): 공유 메모리 영역을 작성하거나 기존의 이름 지정된 영역에 연결한다. 이 시스템 호출은 파일 디스크립터를 리턴한다.
  • shm_unlink(): (shm_open()에서 리턴되는) 파일 디스크립터가 지정되어 있을 때 공유 메모리 영역을 삭제한다. UNIX의 어떤 파일과도 거의 마찬가지로, 해당 영역에 액세스하는 모든 프로세스가 종료될 때까지는 영역이 실제로 제거되지 않는다. 하지만, (일반적으로 원래 프로세스에서) shm_unlink()를 호출하면 다른 프로세스는 영역에 액세스할 수 없다.
  • mmap(): 공유 메모리 영역을 프로세스의 메모리로 맵핑한다. 이 시스템 호출은 shm_open()에서 파일 디스크립터를 요구하고 포인터를 메모리로 리턴한다. (어떤 경우에는 파일 디스크립터를 일반 파일로 맵핑하거나 다른 장치를 메모리로 맵핑할 수도 있다. 그런 옵션에 대한 논의는 본 기사의 범위를 벗어나는 주제이며, 구체적인 내용은 사용 중인 운영 체제에 대한 mmap() 문서를 참조한다.)
  • munmap(): mmap()의 반대이다.
  • msync(): 공유 메모리 세그먼트를 파일 시스템과 동기화하는 데 사용되며, 파일을 메모리로 맵핑할 때 유용한 기술이다.

공유 메모리에 대한 패턴은 shm_open()으로 세그먼트를 작성하고, write() 또는 ftruncate()로 세그먼트의 크기를 조정하고,mmap()을 이용해 세그먼트를 프로세스 메모리로 맵핑하고, 하나 이상의 추가 참가자와 함께 필요한 작업을 수행하는 것이다. 완료하기 위해, 원래 프로세스는 munmap()  shm_unlink()를 호출한 다음 종료한다.

샘플 애플리케이션

아래의 목록 1은 작은 공유 메모리 예제를 나타낸 것이다. (이 코드는 2007년 3월에 Prentice Hall Professional에서 출간한 John Fusco의 저서 The Linux Programmer's Toolbox(ISBN 0132198576)에서 유래된 것으로, 출판사의 허가를 받아 사용했다.) 이 코드는 공유 메모리 세그먼트를 통해 통신하는 상위 및 하위 프로세스를 구현한다.


목록 1. 공유 메모리 예제
	
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/file.h>
#include <sys/mman.h>
#include <sys/wait.h>

void error_and_die(const char *msg) {
  perror(msg);
  exit(EXIT_FAILURE);
}

int main(int argc, char *argv[]) {
  int r;

  const char *memname = "sample";
  const size_t region_size = sysconf(_SC_PAGE_SIZE);

  int fd = shm_open(memname, O_CREAT | O_TRUNC | O_RDWR, 0666);
  if (fd == -1)
    error_and_die("shm_open");

  r = ftruncate(fd, region_size);
  if (r != 0)
    error_and_die("ftruncate");

  void *ptr = mmap(0, region_size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
  if (ptr == MAP_FAILED)
    error_and_die("mmap");
  close(fd);

  pid_t pid = fork();

  if (pid == 0) {
    u_long *d = (u_long *) ptr;
    *d = 0xdbeebee;
    exit(0);
  }
  else {
    int status;
    waitpid(pid, &status, 0);
    printf("child wrote %#lx\n", *(u_long *) ptr);
  }

  r = munmap(ptr, region_size);
  if (r != 0)
    error_and_die("munmap");

  r = shm_unlink(memname);
  if (r != 0)
    error_and_die("shm_unlink");

      return 0;
}

다음은 코드에서 몇 가지 강조할 사항이다.

  • shm_open()에 대한 호출이 친숙해 보일 것이다. 이 호출은 세그먼트와 사용 권한을 초기화하는 방법을 포함하여, open() 함수와 매우 유사하다. 여기서, 세그먼트는 누구나 읽고 쓸 수 있다. 사용하지 않는 다음 파일 디스크립터는 호출에 성공하는 경우 리턴되고, 그렇지 않으면 -1이 리턴되고 그에 따라 errno가 설정된다.
  • ftruncate()는 파일의 크기를 이전에 시스템의 표준 페이지 크기로 설정된 region_size 바이트로 조정한다. sysconf()가 libc의 일부로 제공된다. (쉘 유틸리티 getconf를 사용하여 시스템의 구성 설정을 탐색할 수도 있다.)
  • mmap()은 공유 메모리 세그먼트를 합병하고 세그먼트에서 직접 바이트를 읽고 쓰기에 적합한 포인터를 리턴한다. PROT_READPROT_WRITE는 각각 세그먼트를 읽고 쓸 수 있는 페이지를 표시한다. MAP_SHARED는 메모리 세그먼트의 모든 변경 내용이 모든 협력 프로세스에 "공개"되어야 함을 지정한다.
  • fork()를 사용해보았다면 코드의 계산 파트가 친숙하게 느껴질 것이다. fork 후에 상위 및 하위 프로세스에는 공개된 모든 파일 디스크립터와 데이터 값의 사본이 있으므로, 둘 모두에 대해 포인터가 적용된다. 하지만, pid는 다르다. 하위 프로세스에서 0을 받고, 상위 프로세스에서는 하위 프로세스의 프로세스 ID를 받고, 변수 값에 따라 if/then/else 중 어떤 분기를 택할지 결정된다. 하위 프로세스는 포인터에 몇 바이트의 데이터를 쓴 다음 종료한다. 상위 프로세스는 하위 프로세스의 종료를 기다린 다음, 쓰인 데이터를 읽는다.
  • 하지만, 상위 프로세스가 종료할 수 있으려면 우선 공유 메모리를 해제해야 한다. munmap() shm_unlink()는 트릭을 수행한다.

이 예제는 매우 기초적인 것이다. 실제 애플리케이션에서는 세마포어나 다른 기술을 사용하여 공유 세그먼트에 대한 읽기 및 쓰기를 제어한다. 그런 제어는 일반적으로 애플리케이션마다 다른데, UNIX 유형이 오픈 소스가 아닌 경우 BSD(Berkeley Software Distribution) 및 Linux 소스에서 다양한 예제를 찾을 수 있다.

모든 것이 하나로

UNIX는 겉보기에는 많은 애플리케이션을 동시에 실행하기 때문에, 모니터링, 데이터 수집, 협력 및 분산 컴퓨팅, 클라이언트-서버 애플리케이션을 위한 이상적인 플랫폼이다. 공유 메모리는 사용 가능한 프로세스 간 통신 옵션 중에서 가장 빠르고 꽤 유연하다. 파일을 메모리로 맵핑할 수도 있으므로, 데이터 액세스를 가속화하기에 이상적인 솔루션이다.


참고자료

교육

  • The Linux Programmer's Toolbox: Linux 프로그래머 도구 상자를 찾아보자. 

  • Shared memory: 공유 메모리에 대한 입문서를 읽어보고 사용 가능한 다양한 구현 방법에 대해 배워보자. 

  • Interprocess communications: 공유 메모리와 다른 형태의 프로세스 간 통신(IPC)이 구현되는 방법에 대해 자세히 알아보자. 

  • Speaking UNIX: 본 시리즈의 다른 파트를 살펴본다. 

  • AIX와 UNIX developerWorks 영역: AIX와 UNIX 영역에서는 AIX 시스템 관리와 UNIX 스킬 확장의 모든 측면과 관련된 풍부한 정보를 제공한다.

  • AIX 및 UNIX 입문: AIX 및 UNIX 입문 페이지를 방문하면 자세한 내용을 확인할 수 있다. 

  • 기술 서점: 다양한 기술 주제와 관련된 서적을 살펴볼 수 있다. 

토론


'OS > 리눅스 & 유닉스' 카테고리의 다른 글

리눅스 명령어 모음  (0) 2012.07.05
POSIX Semaphore & System V Semaphore  (0) 2012.06.01
ibm aix polling  (0) 2012.05.31
공유 메모리 (shared memory)  (0) 2012.05.29
poll을 이용한 채팅서버  (0) 2012.05.24
:

ibm aix polling

OS/리눅스 & 유닉스 2012. 5. 31. 15:21

#include <stdio.h>

#include <stdlib.h>

#include <sys/ioctl.h>

#include <sys/poll.h>

#include <sys/socket.h>

#include <sys/time.h>

#include <netinet/in.h>

#include <errno.h>


#define SERVER_PORT  12345


#define TRUE             1

#define FALSE            0


main (int argc, char *argv[])

{

  int    len, rc, on = 1;

  int    listen_sd = -1, new_sd = -1;

  int    desc_ready, end_server = FALSE, compress_array = FALSE;

  int    close_conn;

  char   buffer[80];

  struct sockaddr_in   addr;

  int    timeout;

  struct pollfd fds[200];

  int    nfds = 1, current_size = 0, i, j;


  listen_sd = socket(AF_INET, SOCK_STREAM, 0);

  if (listen_sd < 0)

  {

    perror("socket() failed");

    exit(-1);

  }


  rc = setsockopt(listen_sd, SOL_SOCKET,  SO_REUSEADDR,

                  (char *)&on, sizeof(on));

  if (rc < 0)

  {

    perror("setsockopt() failed");

    close(listen_sd);

    exit(-1);

  }


  rc = ioctl(listen_sd, FIONBIO, (char *)&on);

  if (rc < 0)

  {

    perror("ioctl() failed");

    close(listen_sd);

    exit(-1);

  }


  memset(&addr, 0, sizeof(addr));

  addr.sin_family      = AF_INET;

  addr.sin_addr.s_addr = htonl(INADDR_ANY);

  addr.sin_port        = htons(SERVER_PORT);

  rc = bind(listen_sd,

            (struct sockaddr *)&addr, sizeof(addr));

  if (rc < 0)

  {

    perror("bind() failed");

    close(listen_sd);

    exit(-1);

  }


  rc = listen(listen_sd, 32);

  if (rc < 0)

  {

    perror("listen() failed");

    close(listen_sd);

    exit(-1);

  }


  memset(fds, 0 , sizeof(fds));


  fds[0].fd = listen_sd;

  fds[0].events = POLLIN;


  timeout = (3 * 60 * 1000);


  do

  {

    printf("Waiting on poll()...\n");

    rc = poll(fds, nfds, timeout);


    if (rc < 0)

    {

      perror("  poll() failed");

      break;

    }


    if (rc == 0)

    {

      printf("  poll() timed out.  End program.\n");

      break;

    }


    current_size = nfds;

    for (i = 0; i < current_size; i++)

    {


      if(fds[i].revents == 0)

        continue;


      if(fds[i].revents != POLLIN)

      {

        printf("  Error! revents = %d\n", fds[i].revents);

        end_server = TRUE;

        break;


      }

      if (fds[i].fd == listen_sd)

      {


        printf("  Listening socket is readable\n");


        do

        {

          new_sd = accept(listen_sd, NULL, NULL);

          if (new_sd < 0)

          {

            if (errno != EWOULDBLOCK)

            {

              perror("  accept() failed");

              end_server = TRUE;

            }

            break;

          }

          printf("  New incoming connection - %d\n", new_sd);

          fds[nfds].fd = new_sd;

          fds[nfds].events = POLLIN;

          nfds++;


        } while (new_sd != -1);

      }



      else

      {

        printf("  Descriptor %d is readable\n", fds[i].fd);

        close_conn = FALSE;


        do

        {


          rc = recv(fds[i].fd, buffer, sizeof(buffer), 0);

          if (rc < 0)

          {

            if (errno != EWOULDBLOCK)

            {

              perror("  recv() failed");

              close_conn = TRUE;

            }

            break;

          }


          if (rc == 0)

          {

            printf("  Connection closed\n");

            close_conn = TRUE;

            break;

          }


          len = rc;

          printf("  %d bytes received\n", len);


          rc = send(fds[i].fd, buffer, len, 0);

          if (rc < 0)

          {

            perror("  send() failed");

            close_conn = TRUE;

            break;

          }


        } while(TRUE);


        if (close_conn)

        {

          close(fds[i].fd);

          fds[i].fd = -1;

          compress_array = TRUE;

        }



      }  /* End of existing connection is readable             */

    } /* End of loop through pollable descriptors              */


    if (compress_array)

    {

      compress_array = FALSE;

      for (i = 0; i < nfds; i++)

      {

        if (fds[i].fd == -1)

        {

          for(j = i; j < nfds; j++)

          {

            fds[j].fd = fds[j+1].fd;

          }

          nfds--;

        }

      }

    }


  } while (end_server == FALSE); /* End of serving running.    */


  for (i = 0; i < nfds; i++)

  {

    if(fds[i].fd >= 0)

      close(fds[i].fd);

  }

}


출처 - http://publib.boulder.ibm.com/infocenter/iseries/v6r1m0/index.jsp?topic=/rzab6/poll.htm

: