'OS'에 해당되는 글 130건

  1. 2012.01.05 grep , sed, awk 정규식
  2. 2012.01.04 SED 스트림 에디터
  3. 2012.01.04 Bash 스크립팅 가이드
  4. 2011.12.30 유닉스 itoa 구현
  5. 2011.12.28 htonl() htons() ntohl() ntohs()
  6. 2011.12.27 socketpair
  7. 2011.12.27 파일 디스크립터
  8. 2011.12.23 perror
  9. 2011.12.23 write
  10. 2011.12.23 read

grep , sed, awk 정규식

OS/리눅스 & 유닉스 2012. 1. 5. 08:33
정규식이란 무엇인가 ? 
어떤 문자열의 집합을 묘사하는데 사용되는 텍스트 스트링 
정해진 구문 규칙에 따른다 
Editor, Utillity, Programming 언어에서 텍스트 패턴을 기준으로 검색, 혹은 조작하는데 사용된다 
보통 사람들이 쓰는 표현 중에도 그대로 문장을 해석하면 안 되는 관용구나, 숙어 같은 것 이 있듯이 컴퓨터도 동일하게 해석 하면 안되는 구문이 있는데, 이것을 정규식이라 한다

문자

의미

^

줄의 시작을 나타내지만 문맥에 따라서는 정규 표현식에서는 문자 집합의 의미를 반대로 해석해준다 
ex) ^root 행의 제일 처음이 root 
                [^a-z] : 소문자 제외 
           [^a-z A-Z] : 알파벳 제외

*

바로 앞의 문자열이나 정규 표현식에서 0개 이상 반복되는 문자를 나타낸다 
ex) 1133* : 113(o), stuadun(x), studenttttt(o), studenttyt(x) 
        / 1* : 아무 것도 없거나, 1이 하나 이거나, 1이 반복되거나 
find ./test* :test로 시작하는 모든 것 
            * : 전부 다 
          [ ]* : 집합 포함하고

.

새로운 라인을 제외한 오직 한 개의 글자와 일치 (space, tab 포함)
ex) st.den : .에는 아무 글자나 와도 된다 
        a..b : a로 시작하고 b로 끝나는 5글자

$

줄의 끝과 일치하며, ^$의 경우 빈 줄과 일치함

[…]

문자들을 집합으로 묶어 줌(한 음절씩 매칭)
ex) [a-z] : 소문자 중 하나라도 일치 
[a-z A-Z] : 소문자나 대문자

\

다음 사용을 위해 태그를 붙인다. (최대 9개)
ex) \$ : 정규 표현시에서 줄의 끝을 나타내는 의미대신 문자 그대로

\(……\)

다음 사용을 위해 태그를 붙인다. (최대 9개)
ex) \(pquhg\) .. .. .. .. .. \(aough\)
\1 \2

\<

단어의 시작 지시자

\>

단어의 끝 지시자

X\{n\}

문자 X를 n번 반복

X\{n,\}

문자 X를 적어도 n번 반복

X\{m,n\}

문자 X를 m번에서 n번 반복 
ex) \<[a-z]\{4,5\}\> : 소문자를 4번에서 5번 반복하는 거

GREP 
파일 전체를 뒤져 정교 표현식에 대응하는 모든 행들을 출력 
기본 형식 : grep 'word' [filename] 
ex) env | grep 'HOSTNAME' : 환경 변수 중에서 HOSTNAME을 찾음 
Grep root /etc/shadow : /etc/shadow 파일에서 root라는 단어를 찾음

문자

의미

-b

검색 결과의 행 앞에 검색된 위치의 블록 번호 표시 
검색내용이 디스크의 어디 쯤 있는지 위치를 알아내는데 유용

-c

검색 결과를 출력하는 대신, 찾아낸 행의 총수를 출력 
ex) grep -c 'woo' file : woo라는 단어가 포함된 행의 총수를 출력

-h

파일 이름을 출력하지 않음

-i

대소문자를 구분하지 않음 (동일 취급)
ex) grep -i | 'sexy' file : 문자열 sexy가 어떠한 대소문자 조합으로 이루어져 있더라도 찾는다

-l

패턴이 존재하는 파일의 이름만 출력 
ex) grep -l 'FU' * : 모든 검색 범위안에서 'FU'라는 단어가 들어가 있는 파일의 이름만 출력

-n

파일 내에서 행, 번호 출력 
ex) grep -n '^hole' file : 파일에서 시작이 hole로 시작하는 행, 번호 출력 
grep -n '^root' /etc/shadow : 루트로 시작하는 행, 번호 출력

-v

패턴이 존재하지 않는 행만 출력 
ex) grep -v 'root' file > temp 
Mv temp file : root가 포함되지 않는 모든 행 출력 (특정 내용 삭제하는데 좋다)

-w

패턴 표현식을 하나의 단어로 취급하여 검색 
ex) grep -w 'me' file : 딱 me라는 단어가 있는 경우에만 찾음

grep + 정규식 
ex) grep '[a-z]\{9\}' file : 소문자가 적어도 9개 이상 연속적으로 나오는 문자열을 포함한 모든 행을 출력 
grep '\<a-z].*h\>' file : 소문자 하나로 시작하고, 이어서 임의의 수 여러문자가 나오며 h로 끝나는 단어가 포함된 모든 행 출력 
grep '\.bak$' file : .bak으로 끝나는 행을 출력 . 작은 따음표는 $의 해석을 막는다 
grep '[A-Z]…[0-9]' file : 대문자로 시작하고 숫자로 끝나는 다섯문자의 열이 포함된 행을 출력 
ps -ef | grep "^"denodo" : user1로 시작하는 행을 검색하며 denodo앞에 0개 혹은 임의의 수 공백이 와도 상관 없다   

EGREP 
Grep에서 제공하지 않는 확장된 정규 표현식 메타 문자 사용 
기본 형식 : egrep 'word' [filename]

문자

의미

+

선행 문자와 같은 문자의 1개 혹은 임의 개수와 대응 (1개 이상)
ex) egrep '1+' file : 숫자 1이 한번 이상 등장하는 행을 출력 
Egrep 'yes+' file : yes가 한번 이상 연속해서 나오는 행 출력

?

성행 문자와 같은 문자의 0개 혹은 1개와 대응 
ex) egrep '2\.?[0-9]' file : 숫자 2 다음에 마침표가 없거나 한번 나오고, 다시 숫자 하나가 오는 행을 출력

a | b

a혹은 b와 대응 
ex) egrep 'WM|M' file : WM나 M이 포함된 행을 출력 
Egrep 'S[s|x]' file : 문자 S다음에 s나 x가 오는 행 출력

( )

정규 표현식을 묶어준다

FGREP 
fgrep은 grep명령어와 도일하게 동작하지만 정규표현식 메타문자들을 특별히 취급하지 않는다 
기본형식 : fgrep '문자열' [filename] 
ex) fgrep '[A-Z] … [0-9]' filename : 문자 [A-Z] … [0-9] 자체를 포함하는 문자열을 찾는다

AWK 
기본형식 : awk 'patten' filename 조건 
awk '{action}' filename 몇번째 필드 
awk 'pattern {action}' filename 무슨 조건에 몇 번째 필드 
1 (필드) 개행으로 구분한다 
2 자료 처리 및 리포트 생성에 사용하는 프로그래밍 언어 
3 입력 데이터로는 표준 입력, 여러 개의 파일 또는 다른 프로세스의 결과를 사용 할 수 있다 
4 사용자가 지정한 패턴 검색이나 특별한 작업수행 위해 파일을 행 단위로 조사한다 
5 $0은 모든 필드

awk '{print $1}' file

파일의 첫 번째 필드를 출력한다, 첫 번째 필드는

각 행의 맨 왼쪽 경계에서 시작 공백문자로 구분

awk '/BRAVE/{printf $1, $2}' file

파일에서 BRAVE를 포함하는 행들의 첫 번째와 두 번째 필드를 출력

df | awk '$2 > 5000 '

df ( 현재 디바이스 정보 ) 명령어를 통해 출력되는 내용 중 두 번째 필드가 5000보다 큰행을 출력

date | awk '{print "Month : $2\n Year"$6}'

date 명령어를 통해 출력되는 두 번째 필드와 여섯번 째 필드를 서로 개행 하여 출력

awk '{print NR, $1, $3|' file

NR(하나의 레코드를 처리한 뒤 1 이 증가하는 변수)을 사용하여 레코드 번호와 함께 파일의 내용대로 출력

awk -F : '/root/{print $0}' /etc/passwd

" : " 구분자를 기준으로 필드를 나누며 root를 포함하는 행을 출력

awk -F : '\^[ns]\{print $1}' file

N이나 s로 시작하는 행의 첫 번째 필드를 출력

awk -F '[\t]' '{print $1, $2, $3}' employees

Tab 으로 필드를 구분하며 첫 번째, 두 번째, 세 번째, 필드를 출력한다 (작은 따옴표는 쉘이 대괄호를 해석 할까봐)

awk '$1 ~ /[bB]ill/' employees

~는 특정 레코드나 필드 내에서 일치하는 정규 표현식 패턴이 존재하는지 검사 위해 쓰인다

awk '$1 !~ /ly$' employees

첫 번째 필드가 ly로 끝나지 않는 행들을 출력

awk '$4 ~ /Chin$/{print "The price is $"$8"."}' file

네 번째 필드가 Chin으로 끝나는 문자열 The price is$와 여덟 번째 필드 및 마침표를 함께 출력 한다

SED 
기본 형식 : sed 'comman; filename(s) 
(p : 출력, d : 삭제, r : 파일로부터 사용자 지정행만 읽음, w : 사용자가 선택한 행을 파일에 저장, -n : 변경된 행만, 
a : 내용 추가, i : 내용 삽입) 
1 대화형 기능이 없는 편집기 
2 쉘 리다이렉션을 이용하여 편집 결과를 저장하기 전 까지는 파일에 아무런 변경도 하지 않는다 
3 쉘 스크립트를 작성할 때 유용하다 
4 pattern space라는 임시 버퍼를 사용한다

sed '1,2p' file

file의 1행에서 2행까지 출력

sed -n '/root/p' /etc/passwd

기본적으로는 모든 행을 출력, root에 있는게 다시 출력되므로, -n을 통해 기본적으로 출력되는 행을 막는다

sed '3d' file

3번째 행을 삭제하여 출력한다 ( 기본적 출력에서 3개 없애는 것이므로, -n 없어야 됌 )

sed 'bash/d' /etc/passwd

bash를 포함하는 모든 행 삭제하고, 나머지 행들을 출력

sed -n 's/bash/nologin/gp' etc/passwd

bash가 nologin으로 치환되며, -n과 p로 변경된 행만 출력, g로 전역치환

sed -e '5.40d' e 's/root/chgroot/g' /file

-e 옵션이 sed 명령어 하나로 다중 편집을 가능하게 해준다 ( 결과 : 1~4만 출력)

sed '/sexy/r newfile' file

r 명령어는 파일로부터 사용자가 지정한 행을 읽어온다. 
newfile 내용은 file에서 패턴을 찾은 곳에 삽입 된다 (file에서 sexy밑에 newfile 삽입)

sed -n '/central/w outfile' file

w 명령어는 사용자가 선택한 행들을 파일에 저장한다 (file에서 central이 있으면 output에 저장된다)

sed /note/a\ > hi' file

a 명령어는 내용을 덧붙일 때, 사용한다 (append)

sed '/note/i\ > woo'file

i 명령어는 삽입 명령어임. 지정한 문장을 매칭되는 행 위에 삽입한다

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

vi 에디터 문자열 치환  (0) 2012.01.09
sed 편집기  (0) 2012.01.05
SED 스트림 에디터  (0) 2012.01.04
Bash 스크립팅 가이드  (0) 2012.01.04
유닉스 itoa 구현  (0) 2011.12.30
:

SED 스트림 에디터

OS/리눅스 & 유닉스 2012. 1. 4. 22:43

SED 스트림 에디터

Ken Pizzini

최영덕

이 문서는 유닉스 표준 유틸리티인 SED의 GNU 확장판 메뉴얼을 번역한 것입니다.

근래에 들어 SED 사용자들이 많이 줄어 드는 추세지만, SED는 간단하고 무식한(!) 치환 작업에는 참으로 유용한 유틸리티입니다. 적당한 SED 문서를 찾아다니다, 결국 못찾고 번역까지 하게되고 말았습니다. 모쪼록 SED가 여러 사용자들에게 편리하게 쓰였으면 하는 바램입니다.

원문에는 [정규표현식 개요] 부분과 [예제 스크립트] 부분이 "나중에 쓰겠다"며 생략되어 있습니다. 처음 UNIX를 접하시는 분들을 위해 제가 임의로 글을 덧붙였음을 말씀드립니다. 처음하는 번역과 SGML 문서 작업이라서 어색한 부분이 많을 것입니다. 고쳐야할 점이나 제가 덧붙인 글의 오류를 지적해주시면 수정하도록 하겠습니다. :)

고친 과정
고침 태그수정 2001.03.18 고친이 ydwolf
고침 번역 2001.03.06 고친이 ydwolf
한국어 번역판
고침 v3.0.2 1998.06.28 고친이 KP
영문 버전

1. 서론

SED는 스트림 에디터입니다. 스트림 에디터는 입력 스트림(파일이나 파이프를 통한 입력)에 대해서 단순한 텍스트 교체가 필요할 때 쓰입니다. SED는 입력물을 딱 한 번에 더 효과적이고 능률적으로 처리해주는 다른 스크립트 편집기(ED와 같은)와 비슷합니다. 하지만 다른 에디터와는 차원이 다른 파이프를 통한 텍스트 필터링이 SED만의 탁월함입니다.


2. 시작

SED는 다음과 같은 명령행 옵션을 갖습니다.

-v, --version

SED의 버젼과 저작권 정보를 보여줍니다.

-h, --help

명령행 옵션들에 대한 간략한 정보와 버그리포팅 주소를 보여줍니다.

-n, --quiet, --silent

이 옵션을 켜두면 'p'명령이 명시될 때만 출력을 생성하고 이외의 경우에는 출력을 생성하지 않게 합니다. (디폴트로 SED는 이 옵션을 끄기때문에, 스크립트를 실행하면서 각 순환의 끝마다 패턴 공간을 출력합니다.)

-e "스크립트", --expression="스크립트"

"스크립트" 입력 데이타를 처리할 명령 집합에 "스크립트"를 추가합니다.

-f "스크립트파일", --file="스크립트파일"

입력 데이타를 처리할 명령 집합에 "스크립트파일"에 포함된 명령어들을 추가합니다.

'-e', '-f', '--expression', '--file' 옵션이 주어지지 않을 경우에는 명령행 인자들의 옵션이 아닌 첫번째 인자가 처리 명령으로 받아들여집니다.

위의 옵션들이 처리되고 남은 명령행 인수들은 처리될 파일들의 이름으로 해석됩니다. 하이픈(-)은 표준입력스트림을 가리키며, 파일 이름이 주어지지 않았을 때에도 표준 입력 스트림으로 처리 데이타가 들어오는 것으로 간주됩니다.


3. SED 프로그램

SED프로그램은 '-e', '-f', '--expression', '--file' 옵션에 기술된 하나 이상의 명령이나 명령집합파일(또는 옵션 이외의 첫번째인자도 포함하여)에 포함된 명령어들의 집합입니다. 이 문서는 그 SED 스크립트(script : 명령이나 명령 집합 파일에 포함된 모든 것들의 순차적 연쇄적 기록)에 대해서 기술할 것입니다.

각각의 SED 스크립트는 주소와 명령어가 한쌍을 이루어 구성됩니다.(주소 혹은 주소공간들은 생략될 수 있으며, 명령어들은 관련된 코드들을 동반할 수 있습니다.)


3.1. SED에서의 행 선택 (행 지정)

'숫자'

행번호 하나를 기술하면 입력 스트림에서 그 행만 선택됩니다(SED는 연속된 입력파일들에 대해서 연속적으로 행수를 셉니다. 주의하십시요.)

'시작점~증가값'

이 GNU 확장은 '시작점'에서 시작하여 '증가값'만큼씩 더해진 행들을 선택합니다. 좀더 세밀하게는 "시작점+(N*증가값)=남은행수"를 만족하는 양수의 N이 존재할 때만 행의 선택이 이뤄집니다. 예를들어 "홀수"만 선택할 때는 '1~2', "두번째 행에서 시작하여 각 세번째 행"을 선택할 때는 '2~3'의 주소지정법을 사용할 수 있을 것이며, "열번째 라인부터 매 다섯번째 행"의 선택은 '10~5'입니다. 또한 '50~0'은 50번째 행을 가리키는 모호한(?) 방법입니다.

'$'

입력 파일의 마지막 행을 가리킵니다.

'/정규표현식/'

이것은 정규 표현식에 매치되는 어떤 행이라도 선택해 줍니다. 만약 정규 표현식 내부에 슬래쉬(/)문자가 포함된다면 각 슬래쉬 문자는 백슬러쉬 문자(\)를 선행기술하여 이스케이프(의미 탈락)시켜야 합니다('\/'처럼.)

'\%정규표현식%'

('%'문자는 다른 문자 한 개로 바꾸어 쓸 수 있습니다.) 이 방식 역시 정규 표현식에 매치되는 어떤 행이라도 선택합니다만 정규 표현식 구분자로 슬래쉬(/) 대신에 다른 문자를 쓸 수 있게 허락합니다(현재 예제에서는 '%'문자.) 이 방식은 정규 표현식 내부에 슬래쉬 문자가 많이 포함되어 모든 슬래쉬 문자를 이스케이프 시키는 지루한 작업을 피하고 싶을 때 특별히 유용합니다. 만약 정규 표현식 내부에 구분자(현재 예제에서는 '%'문자)가 들어 갈 경우에는 역시 백슬러쉬(\)로 이스케이프 시켜줘야 합니다.

'/정규표현식/I', '\%정규표현식%I'

대문자'I'의 GNU확장 수식어는 정규표현식을 case-insensitive하게(대소문자 구분없이) 적용시킵니다.

주소가 주어지지 않으면 행의 전부가 주소 공간으로 지정됩니다. 하나의 주소가 주어지면 주소와 대응되는 한 행만이 주소 공간으로 지정됩니다.

주소범위는 콤마(,)로 구분된 두 주소를 기술함으로써 지정됩니다. 주소범위는 첫번째 주소 지정부터 시작하여 두번째 주소 지정까지 계속 적용됩니다(전부 지정됨.) 만약 두번째 주소 지정이 정규표현식이라면 첫번째 주소가 적용된 행부터 시작하여 정규 표현식과 대응되는 첫 행까지가 주소공간으로 적용됩니다. 두번째 주소지정이 첫번째 주소지정보다 작거나 같은 크기의 숫자라면 단지 한 행만이 주소공간으로 적용됩니다.

느낌표(!)가 주소 기술의 마지막 문자로 오는 경우에는 적용방식이 반대로 작용합니다. 이말은 만약 느낌표(!) 문자가 주소 범위 기술 뒤에 붙으면 주소 범위와 대응되지 않는 행들만이 지정된다는 것입니다. 낱개의 주소들과 아마도 짖궂겠지만, 빈(Null) 주소에도 적용됩니다.


3.2. 정규표현식 문법 개요

'정규표현식'은 SED 뿐만 아니라 UNIX세계에서 가장 중요한 것 중 하나입니다. 하지만 어디까지를 '정규표현식'으로 볼 것인가, 혹은 '정규표준식'의 표준이라는 문제에 대해서는 의견이 분분합니다. '정규표현식'을 사용하는 프로그램마다 표현법이 조금씩 틀릴 뿐만 아니라, '확장 정규표현식'이라는 별종까지 여기저기 등장해 사뭇 혼란스럽습니다. 여기서는 SED에서 쓰이는 '정규표현식'만을 다루겠습니다. SED의 '정규표현식'을 익힌다면, 일단 어디서나 쓸 수있는 '정규표현식'의 mini-set을 익히는 것이 되겠습니다. 좀더 '정규표현식'의 세계를 느끼고 싶은 분들은 나중에 펄 문서등을 참조하시면 될 것입니다.

'정규표현식'을 간단히 말한다면, 텍스트 꾸러미에서 원하는 부분만 골라내고자 할 때 사용하는 일종의 집합(set)입니다. 몇개 되지 않으니 주욱 써보도록 하겠습니다.

'.'(점, dot)

정규표현식 내부에서 "어떤 문자이던지 상관하지 않고 단지 한 글자"를 뜻합니다.

'*'(별, asterik)

바로 이전에 나왔던 문자가 몇번이던지 연속될 때 "연속된 문자 모두"를 뜻합니다. 여기서 "몇번이던지"라는 문구에는 0번, 즉 한번도 연속되지 않은 상태도 포함된다는 것에 주의하십시요.

'^'(삿갓, carat)

행의 시작을 뜻합니다. 행의 처음에 있는 문자가 아니라 행의 논리적 처음을 가리킵니다.

'$'(달러, dollar)

행의 끝을 뜻합니다. 행의 마지막에 있는 문자가 아니라 행의 논리적 끝을 가리킵니다. SED는 입력 문자열에 대해서는 줄바꿈문자를 행의 끝으로 보지만, 패턴공간이나 홀드공간에 있는 데이타에 대해서는 '$'가 줄바꿈 문자가 아닌 데이타의 끝을 가리키는 것에 주의 하십시요.

'[문자집합]'

"'문자집합'의 원소들 중의 하나와 대응되는 한 문자"를 가리킵니다. '.'와는 달리 변역이 정해져있는 한 문자라는 뜻입니다. 문자들이 연속된 ASCII 값을 갖는다면 '-' 문자를 써서 변역의 시작과 끝을 나타낼 수도 있습니다. 예를 들어 '[0-9]'라는 것은 0부터 시작하여 9사이에 있는 모든 문자, 즉 '어떤 숫자 하나'를 가리킵니다.

'[^문자들]'

삿갓문자로 시작하는 변역 지정은 "문자들"에 포함되지 않은 문자 하나를 가리킵니다. 즉 전체 문자 집합에 대한 "문자들"집합의 차집합을 의미합니다.

윗목록에 포함되지 않은 텍스트들은 그냥 텍스트 자체로 해석됩니다.

정규표현식의 몇가지 예를 들어 보겠습니다.

           wolf@zizik.net]$ nl/etc/hosts
            1        231.101.9.11    ulsan           울산  101
            2        231.102.9.11    kangbyun        강변  102
            3        231.104.9.11    world           월드  104
            4        231.107.9.11    seohyun         서현  107
            5        231.108.9.11    chungju         청주  108
            6        231.109.9.11    kuri            구리  109
            7        231.111.9.11    bupyung         부평  111
            8        231.112.9.11    juyeup          주엽  112
            9        231.113.9.11    daejun          대전  113
           10        231.114.9.11    yeonsu          연수  114
           11        231.115.9.11    chunan          천안  115
           12        231.116.9.11    sangmu          상무  116
           13        231.117.9.11    saha            사하  117
           14        231.118.9.11    daegu           대구  118
           15        3.7.23.107      kwanak          관악  119
           16        3.7.23.232      pusan           부산  120
           17        3.1.2.229       ilsan           일산  121

'/./'

"어떤 문자라도 하나"라는 뜻이므로, hosts화일의 모든 텍스트와 대응됩니다.

'/.*/'

"어떤 문자라도 0번이상 나타날 때"라는 뜻이므로, hosts화일의 모든 텍스트와 대응됩니다.

'/^2/'

"행의 첫 문자로 온 2"를 뜻하므로 1행부터 14행의 처음 한문자와 대응됩니다.

'/2$/'

"행의 마지막으로 온 2"를 뜻하므로 2행, 8행의 마지막 한문자와 대응됩니다.

'/[a-z]*/'

"a부터 z까지의 문자 중에서 어떤 문자라도 0번이상 대응될 때"를 뜻하므로 각 행의 모든 영문자와 대응됩니다. (실제로는 그렇게 간단하게 대응되는 것이 아니라, "입력스트림의 a부터 z까지의 문자가 0번 출현하는 '논리적'출현이 포함되어", 입력스트림의 모든 문자 사이의 논리적 틈새와, 모든 영어문자의 연속이 대응됩니다. '*'의 사용에는 언제나 이런 난해함이 동반되지만, 잘 모르겠다는 분은, SED가 제법 똑똑하기 때문에 "모든 영문자"라고 생각하고 사용하시다가 나중에 혹시 문제가 생기면 다시 한번 생각해 보는 기회를 가지십시요. -_-;)

'/[^a-z]*/'

"a부터 z까지의 문자가 아닌 것의 0번 이상 반복"이라는 뜻이므로, 각행의 '숫자', '공백', '.', '한글'을 가리킵니다.

'/san/'

텍스트 자체인 "san"을 가리키므로 1행, 16행, 17행의 'san'과 대응됩니다.

'/107[ ]*[^ ]* *[^ ]*/'

"107공백0개이상공백이아닌문자0개이상공백0개이상공백이아닌문자0개이상"이라는 뜻입니다. 그러므로 4행의 "107.9.11젨젨 seohyun"과 "107" 그리고, 14행중에서 "107젨젨젨 kwanak젨젨젨젨젨관악"이 대응됩니다. (이부분도 실제로는 굉장히 복잡하게 해석됩니다. 시간있는 분은 한번 생각해 보시길.^^)

예제에서 보았듯이 '*'문자는 대응 범위를 예측하기 어렵습니다. 정규표현식에서는 '*'문자를 최소화하고, 정확한 실제 문자를 많이 넣어주는 것이 중요합니다.


3.3. SED가 데이타를 버퍼링시키는 곳

SED는 활성된 패턴공간(pattern space)과 외부로 확장된 홀드공간(host space)이라는 두개의 데이타 버퍼를 관리합니다. 보통의 처리에서 SED는 입력 스트림으로부터 한 행을 읽어 패턴 공간에 위치시킵니다. 이 패턴 공간은 자료의 조작이 일어나는 공간입니다. 홀드 공간은 텅 빈 채로 초기화되지만 패턴 공간과 홀드 공간 양쪽으로 데이타를 이동시키는 명령어가 존재합니다.


3.4. 자주 쓰이는 명령어들

SED를 쓰게 된다면 어떤 경우에도 다음 명령어들이 필요하게 될 것입니다.

'#'

(주소 지정 없음) '#' 명령어는 주석을 시작합니다. 주석은 행의 끝까지 이어집니다. 이식성이 중요하다면, (POSIX.2 규정을 따르지않는) 몇몇 SED 구현에서는 #으로 시작되는 한 개의 한 줄짜리 문장만을 주석으로 지원한다는 것을 알아야합니다. 경고 : SED 스크립트의 시작에 나오는 문자 두 개가 만약 #n이라면 -n(자동 출력 없음)옵션이 강제 지정됩니다. 꼭 #n으로 시작되는 행이 SED 스크립트의 처음에 와야하기때문에 이 작동을 원하지 않는다면 대문자 'N'을 쓰거나 'n' 앞에 한칸 공백을 두십시요.

's/정규표현식/교체어/플래그'

('/' 문자는 어떤 s 명령에서도 다른 한 문자로 항상 교체할 수 있습니다.) '/' 문자(혹은 그대신 편의에 따라 쓰인 문자)는 '정규표현식'과 '교체어' 안에 쓰일 때에는 '\'문자가 선행됐을 때에만 사용할 수 있습니다. 또 정규표현식 안에서 줄바꿈은 '\n'의 두 문자 집합으로 표현됩니다.

s 명령어는 주어진 정규표현식과 대응되는 패턴공간을 찾습니다. 대응이 성공하면 대응된 패턴 공간의 일부분은 '교체어'로 대체됩니다. '교체어'에는 '\N'(N은 1부터 9까지의 숫자)참조가 포함될 수 있습니다. '\N' 참조는 '정규표현식'의 N번째 '\('과 '\)'사이의 기술과 대응된 패턴공간의 내용을 가리킵니다. 또한 '교체어'는 '정규표현식'과 대응된 패턴공간 전체를 가리키는 '&' 문자를 포함할 수 있습니다. 그러나 '\', '&', 그리고 줄바꿈 등을 '교체어' 내부에 쓸때에는 반드시 '\'를 선행하여 '\\', '\&', '\n'처럼 기술하여야 합니다.

's' 명령어에는 다음과 같은 '플래그'들을 쓸 수 있습니다. (안 쓸 수도 있습니다.)

'g' : '정규표현식'과 대응되는 모든 패턴 공간을 교체합니다. ('처음 한 번만 교체'가 기본값입니다.)
'P' : 교체가 이뤄지면, 교체된 패턴 공간을 출력합니다.
'숫자 n' : n번째 대응되는 패턴 공간만을 교체합니다.
'w 파일' : 교체가 이뤄지면, 교체된 패턴 공간을 파일로 출력합니다.
'I' : (이것은 GNU 확장 기능입니다.) 정규표현식 대응을 대소문자 구분없이 작동시킵니다(case-insensitive.)

'q'

(한 개의 주소 지정만 쓸 수 있슴) SED가 더이상 처리없이 종료됩니다. 자동 출력 옵션을 꺼두지 않았다면 패턴 공간이 출력됨에 주의하십시요.

'd'

패턴 공간을 삭제하고 즉시 다음 사이클을 시작합니다.

'p'

패턴 공간을 출력합니다(표준출력으로.) 이 명령어는 보통, -n 명령줄 옵션이 주어졌을 때 사용됩니다. 자동 출력 옵션이 꺼지지 않은 상태에서 p 명령어가 사용되면 출력이 두번 이루어지는 몇몇 SED 구현에 주의 하십시요. 또 다른 SED 구현에서는 한 번만 출력되기도 합니다. 그러나 두 구현 모두 POSIX.2 표준에 부합되기 때문에 에러라고 생각할 수 있는 것은 아닙니다. 그러므로 이식성있는 SED 스크립트는 두 구현 모두 믿어서는 안됩니다. -n 옵션을 켜고 원할 때만 정확히 출력시키거나, p 명령을 쓰지 않아야 합니다. (이것은 s 명령의 p 플래그에도 적용됩니다.)

'n'

자동 출력 옵션이 켜진 상태라면 패턴 공간을 출력하고, 패턴 공간을 무조건 다음 입력 행으로 대체합니다. 만약 다음 입력이 없다면 SED는 더이상 처리없이 종료됩니다.

'{명령어들}'

'{'와 '}' 사이에 둘러싸인 명령어들을 그룹화합니다. ('}'는 주소 지정이 필요없는 명령어 문맥에 위치해야합니다.) 명령어 그룹은 하나의 주소(혹은 주소 공간) 대응이 여러개의 명령어들을 실행시키도록 할 때 특히 유용합니다(좀더 유식하게 말하면 트리거(Trigger)라고 합니다.)


3.5. 덜 자주 쓰이는 명령어들

물론 이전 장에서 설명한 명령어들보다는 덜 자주 쓰이지만, SED 스크립트에 포함되어 더욱 유용하게 쓰일 수 있는 다음과 같은 명령어들이 있습니다.

'y/대상문자목록/대치문자목록/'

(모든 'y'명령어의 사용에서 '/'는 다른 하나의 문자로 대체될수 있습니다.) 대상문자목록에 들어있는 패턴공간의 모든 문자를 대상문자목록과 일대일로 위치대응되는 대치문자목록의 문자로 치환합니다. '/'(혹은 대체된 다른 문자), '\', 줄넘김문자들은 '\'로 이스케이프 시킨 다음에 대상문자목록과 대치문자목록에 올수 있습니다. 대상문자목록과 대치문자목록은 서로 동일한 문자수를 유지해야 합니다(이스케이프용 문자'\'는 문자수에서 제외.)

'a\<줄바꿈>텍스트'

[한 개의 주소만 지정가능] 'a\'명령어는 다음줄에 나오는 텍스트를 큐(queue)에 저장했다가 현재 사이클이 종료되거나 다음 입력데이타가 읽힐 때 출력합니다. ('\'로 끝나는 줄은 다음 문장도 계속 출력 텍스트로 인식하며, 그 줄의 마지막에 있는 '\'는 출력되지 않습니다. [줄넘김문자 이스케이프라는 소리입니다])

'i\<줄바꿈>텍스트'

[한 개의 주소만 지정가능] 'i\'명령어는 다음 줄에 나오는 텍스트를 즉시 출력합니다. ('\'로 끝나는 줄은 다음 문장도 계속 출력 텍스트로 인식하며, 그 줄의 마지막에 있는 '\'는 출력되지 않습니다. [줄넘김문자 이스케이프])

'c\<줄바꿈>텍스트'

'c\'명령어는 대응되는 주소나 주소범위를 삭제하고, 주소의 마지막 줄 위치에(주소가 지정되지 않았다면 모든 줄의 위치에) 'c\'명령어 다음 줄에 나오는 텍스트를 출력합니다. ('\'로 끝나는 줄은 다음 문장도 계속 출력 텍스트로 인식하며, 그 줄의 마지막에 있는 '\'는 출력되지 않습니다. [줄넘김문자 이스케이프]) 이 명령어가 실행되고 나면, 패턴공간이 삭제된 채로, 새로운 사이클이 시작됩니다.

'='

[한 개의 주소만 지정가능] 현재 입력의 행번호를 출력합니다. (줄바꿈 문자를 단서로 합니다.)

'l'

(영어 소문자 'l') 패턴 공간을 모호하지 않은(umambiguous) 형태로 출력합니다. 출력할수 없는 문자들은('\'문자를 포함하여) C언어스타일의 이스케이프된 형태로, 긴 문장들은 '\'문자로 구분하여 잘라서, 각 줄의 끝은 '$'문자로 출력됩니다.

'r 파일이름'

[한 개의 주소만 지정가능] 파일의 내용을 읽어 큐(queue)에 저장했다가 사이클의 마지막에 혹은 다음 입력행이 읽혀질때, 출력 스트림에 집어 넣습니다. 만약 파일을 읽을 수 없다면 SED는 어떤 경고도 없이 단지 빈 파일이 주어진 것처럼 행동한다는 것에 주의하십시요.

'w 파일이름'

패턴공간을 파일에 씁니다. 파일은 첫번째 입력 행이 읽히기 전에 생성됩니다(혹은 내용이 지워집니다.) 같은 파일이름을 쓰는 모든 w 명령어들은(s명령어가 치환이 성공한 뒤 파일로 기록하게 하는 w플래그를 포함하여) 같은 파일 스트림을 통해 출력됩니다.

'D'

패턴공간의 첫번째 줄바꿈 문자까지 지웁니다. 만약 패턴공간에 문자가 남는다면, (다음 행의 입력없이) 사이클을 다시 시작합니다. 남은 문자가 없을 시에는 정상적으로 새로운 사이클을 시작합니다.

'N'

줄바꿈문자를 패턴 공간에 더하고 입력의 다음 줄을 읽어 패턴 스페이스에 덧붙입니다. 만약 더이상 입력이 없으면 SED 는 더이상 명령어들을 처리하지 않고 종료합니다.

'P'

패턴공간의 첫번째 줄바꿈 문자까지만 출력합니다.

'h'

홀드공간의 내용을 패턴공간의 내용으로 대체합니다.

'H'

홀드공간의 내용에 줄바꿈문자를 더하고, 패턴공간의 내용을 홀드공간에 덧붙입니다.

'g'

패턴공간의 내용을 홀드공간의 내용으로 대체합니다.

'G'

패턴공간의 내용에 줄바꿈문자를 더하고, 홀드공간의 내용을 패턴공간에 덧붙입니다.

'x'

홀드공간과 패턴공간의 내용을 서로 교체합니다.


3.6. 끈질긴(die-hard) SED프로그래머들을 위한 명령어들

대부분의 경우, 아래의 명령어들을 쓰기보다는 펄(PERL)과 같은 다른 프로그래밍언어를 쓰는 편이 더 좋을 것입니다. 하지만 가끔 SED에 늘어붙어 꼼짝못하는 사람이나, 굉장히 복잡한 스크립트를 짜기를 좋아하는 사람도 있기 마련입니다.

': /레이블/'

[주소지정없음] 'b'명령어나 't'명령어를 위한 레이블의 위치를 표시합니다. 다른 요소는 없습니다.

'b 레이블'

레이블 위치로 무조건 분기를 합니다. 레이블이 생략된 경우는 다음 사이클이 시작됩니다.

't 레이블'

마지막 입력이후 혹은 직전 't'분기이후에, 치환이 성공하였다면 레이블 위치로 분기합니다. 레이블이 생략되면 다음 사이클이 시작됩니다.


4. 몇가지 예제 스크립트들

GNU SED 와 함께 배포되는 dc.sed라는 놀라운 스크립트가 있으나, 다음 예제를 한번 보십시요.

예제용 데이타
        wolf@zizik.net]$ cat /etc/hosts
        231.101.9.11    ulsan           울산  101
        231.102.9.11    kangbyun        강변  102
        231.104.9.11    world           월드  104
        231.107.9.11    seohyun         서현  107
        231.108.9.11    chungju         청주  108
        231.109.9.11    kuri            구리  109
        231.111.9.11    bupyung         부평  111
        231.112.9.11    juyeup          주엽  112
        231.113.9.11    daejun          대전  113
        231.114.9.11    yeonsu          연수  114
        231.115.9.11    chunan          천안  115
        231.116.9.11    sangmu          상무  116
        231.117.9.11    saha            사하  117
        231.118.9.11    daegu           대구  118
        3.7.23.107      kwanak          관악  119
        3.7.23.232      pusan           부산  120
        3.1.2.229       ilsan           일산  121
쉬운 예제.

["산"이 들어가는 호스트만 찾아서 ip address 뽑아내기]

        wolf@zizik.net]$ sed -n -e '/산/ s/\([0-9.]*\) *[a-z]* *\([^ ]*\).*/\2 =====> \1/p;' /etc/hosts
        울산 =====> 231.101.9.11
        부산 =====> 3.7.23.232
        일산 =====> 3.1.2.229
좀 어려운 예제.

[호스트 구리까지 읽고 소문자 abcde 를 대문자 ABCDE 로 바꾸고 밑줄 긋기, 호스트 대구까지 읽고 나머지 소문자를 대문자로 바꾸고 밑줄긋기, 마지막행까지 읽고 숫자(0-9)를 '숫자'로 바꾸고 밑줄긋기]

        wolf@zizik.net]$ cat sample.sed
        H

        /kuri/ {
                g
                y/abcde/ABCDE/
                a \
                _______________________
                p
                n
                h
               }
        
        /daegu/ {
                g
                y/fghijklmnopqrsutvwxyz/FGHIJKLMNOPQRSUTVWXYZ/
                a \
                _______________________
                p
                n
                h
               }
        $ {
                g
                s/[0-9]/숫자/g
                a \
                _______________________
                p
               }

        wolf@zizik.net]$ sed -n -f sample.sed /etc/hosts

        231.101.9.11    ulsAn           울산  101
        231.102.9.11    kAngByun        강변  102
        231.104.9.11    worlD           월드  104
        231.107.9.11    sEohyun         서현  107
        231.108.9.11    Chungju         청주  108
        231.109.9.11    kuri            구리  109
        _______________________
        231.111.9.11    bUPYUNG         부평  111
        231.112.9.11    JUYeUP          주엽  112
        231.113.9.11    daeJUN          대전  113
        231.114.9.11    YeONSU          연수  114
        231.115.9.11    cHUNaN          천안  115
        231.116.9.11    SaNGMU          상무  116
        231.117.9.11    SaHa            사하  117
        231.118.9.11    daeGU           대구  118
        _______________________
        숫자.숫자.숫자숫자.숫자숫자숫자      kwanak          관악  숫자숫자숫자
        숫자.숫자.숫자숫자.숫자숫자숫자      pusan           부산  숫자숫자숫자
        숫자.숫자.숫자.숫자숫자숫자       ilsan           일산  숫자숫자숫자
        _______________________

5. 행길이 (무)제한에 관해

이식성 있는 SED 스크립트를 작성하기를 원하는 이들에게 몇몇 SED 구현에서는 (패턴공간과 홀드공간의) 행 길이가 4000바이트로 제한되어 있음을 알려드립니다. POSIX.2표준에서는 SED 구현이 8192바이트의 행길이를 지원해야 한다고 확실하게 명시하고 있습니다. GNU의 SED는 행길이 제한이 없기 때문에 총 (가상)메모리에 주의만 한다면, 여러분이 입력하는 모든 행들에 대해서 SED가 melloc() 하여 처리할 수 있습니다.


6. SED에 관한 다른 학습자료들

SED에 관해 쓰여진 여러책들(본격적인 책들과 쉘프로그래밍에 관해 이야기하는 중에 끼어있는 책이거나)에 덧붙여 SED에 관한 FAQ를 좀더 찾아 보고 싶은 이들은 seders(SED사용자) 메일링 리스트를 다음 사이트에서 볼 수 있습니다(몇몇 책들에 대한 추천을 포함하여.)

http://www.dbnet.ece.ntua.gr/~george/sed/sedfaq.html
http://www.ptug.org/sed/sedfaq.htm
http://www.wollery.demon.co.uk/sedtut10.txt

비공식 "SED 사용자" 메일링 리스트는 Al Aab씨가 손수 관리하고 있습니다. 구독을 원하시면 af137@tofree.net 으로 당신의 관심사를 적어서 보내주십시요.

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

sed 편집기  (0) 2012.01.05
grep , sed, awk 정규식  (0) 2012.01.05
Bash 스크립팅 가이드  (0) 2012.01.04
유닉스 itoa 구현  (0) 2011.12.30
htonl() htons() ntohl() ntohs()  (0) 2011.12.28
:

Bash 스크립팅 가이드

OS/리눅스 & 유닉스 2012. 1. 4. 19:03

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

grep , sed, awk 정규식  (0) 2012.01.05
SED 스트림 에디터  (0) 2012.01.04
유닉스 itoa 구현  (0) 2011.12.30
htonl() htons() ntohl() ntohs()  (0) 2011.12.28
socketpair  (0) 2011.12.27
:

유닉스 itoa 구현

OS/리눅스 & 유닉스 2011. 12. 30. 15:11

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

SED 스트림 에디터  (0) 2012.01.04
Bash 스크립팅 가이드  (0) 2012.01.04
htonl() htons() ntohl() ntohs()  (0) 2011.12.28
socketpair  (0) 2011.12.27
파일 디스크립터  (0) 2011.12.27
:

htonl() htons() ntohl() ntohs()

OS/리눅스 & 유닉스 2011. 12. 28. 13:56

네트워크 바이트 순서로 변환

unsigned long htonl(unsigned long hostlong);
//host to network long
unsigned long htons(unsigned long hostshort);
//host to network short

 

 

호스트 바이트 순서로 변환

unsigned long ntohl(unsigned long netlong);
//network to host long
unsigned short ntohs(unsigned short netshort);
//network to host short

 

 

성공시 : 빅 엔디안 또는 리틀 엔디안 방식으로 변환된 값

 

빅 엔디안 vs 리틀 엔디안
바이트를 실제 메모리에 기록하는 순서.

 

0x1234의 표현방식
빅엔디안 0x12 0x34 순으로, 우리가 표현하는 것과 동일하게 표현됨.
즉 가장 큰 수를 담당하는 최상위비트가 제일 왼쪽에 온다.

 

리틀엔디안 0x34 0x12 순으로, 우리가 표현하는 것과 반대로 표현됨.
즉 가장 작은 수를 담당하는 최하위비트가 제일 왼쪽에 온다.

 

표준은 없고, 시스템마다 차이를 보인다.

현재 사용하는 시스템이 리틀엔디안인지 빅엔디안인지를 가려주는 코드

 

int endian;
char *ptr;

 

endian = 0x12345678;
ptr = (int*)&endian;

 

printf("Big Endian = 0x12|0x34|0x56|0x78\n");
printf("Little Endian = 0x78|0x56|0x34|0x12\n");
printf("Your System's Byte Order\n");
printf("= 0x%x|0x%x|0x%x|0x%x\n", ptr[0], ptr[1], ptr[2], ptr[3]);


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

Bash 스크립팅 가이드  (0) 2012.01.04
유닉스 itoa 구현  (0) 2011.12.30
socketpair  (0) 2011.12.27
파일 디스크립터  (0) 2011.12.27
perror  (0) 2011.12.23
:

socketpair

OS/리눅스 & 유닉스 2011. 12. 27. 19:05

1장. socketpair(2)

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 에러
1.5절. 예제

연결된 소켓 쌍을 생성한다.


1.1절. 사용법

#include <sys/types.h>
#include <sys/socket.h>

int socketpair(int d, int type, int protocol, int sv[2]);
		


1.2절. 설명

socketpair()은 옵션으로 d영역(domain)을 가지며 protocol프로토콜을 사용하는 type의 소켓 쌍을 생성한다. 생성된 소켓 쌍은 sv를 통해서 넘어온다. 두개의 소켓은 서로 구별할 수 없다.

보통 부모 자식 프로세스간 내부 통신(IPC)를 위해서 사용한다. 소켓이므로 양방향(읽고/쓰기) 통신이 가능하다.


1.3절. 반환값

성공시 0을 반환하고 실패할 경우 -1을 반환한다.


1.4절. 에러

EMFILE

너무 많은 파일이 열려있어서 더이상 소켓을 생성할 수 없다.

EAFNOSUPPORT

지정한 주소 지정방식이 지원되지 않는다.

EPROTONOSUPPORT

지정된 프로토콜이 지원되지 않는다.

EFAULT

주소 ev가 프로세스 주소 공간의 유효한 부분을 가리키지 않는다.


1.5절. 예제

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/socket.h>
#include <sys/types.h>

int main()
{
    int pid;
    char buf[256];
    int fd;
    int sv[2];
    int num = 0;

    socketpair(AF_UNIX, SOCK_STREAM, AF_LOCAL, sv);
    pid = fork();
    if (pid == 0)
    {
        dup2(sv[0], 0);
        close(sv[1]);
        close(sv[0]);
        execl("./pipe_cl", "pipe_cl", NULL);
    }
    else if (pid > 0)
    {
        close(sv[0]);
        while(1)
        {
            write(sv[1], (void *)&num, 4);
            printf("write %d\n", num);
            read(sv[1], (void *)&num, 4);
            printf("read %d\n", num);
        }
    }
}
		
위 프로그램은 fork()한 후 자식프로세스에서 pipe_cl을 실행시킨다. 자식과 부모 프로세스는 소켓을 통하여 연결되고 이것을 통해서 데이터를 교환할 수 있다. 다음은 pipe_cl의 코드다.
#include <unistd.h>
#include <stdio.h>

int main()
{
    int num;
    while(1)
    {
        read(0, (void *)&num, 4);
        num++;
        write(0, (void *)&num, 4);
        sleep(1);
    }
}
		

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

유닉스 itoa 구현  (0) 2011.12.30
htonl() htons() ntohl() ntohs()  (0) 2011.12.28
파일 디스크립터  (0) 2011.12.27
perror  (0) 2011.12.23
write  (0) 2011.12.23
:

파일 디스크립터

OS/리눅스 & 유닉스 2011. 12. 27. 16:59

파일 디스크립터   

프로그래밍을 한다면 당연히 파일디스크립터를 모르면 안되겠죠.

File descriptor

From Wikipedia, the free encyclopedia

In computer programming, a file descriptor is an abstract indicator for accessing a file. The term is generally used in POSIX operating systems. In Microsoft Windows terminology and in the context of the C standard I/O library, "file handle" is preferred, though the latter case is technically a different object (see below).

In POSIX, a file descriptor is an integer, specifically of the C type int. There are 3 standard POSIX file descriptors which presumably every process (save perhaps a daemon) should expect to have:


파일 디스크립터에 대해서 좀더 알아 보시려면 위키피디아를 방문해 보세요. 

http://en.wikipedia.org/wiki/File_descriptor#Creating_file_descriptors


간단히 파일 디스크립터에 대해서 설명해 보도록 할께요.


정의 : 컴퓨터 프로그래밍에서 파일디스크립터란 파일에 접근하기 위해 추상화 시켜놓은 장치를 이야기 합니다.

윈도우의 핸들과 유닉스(리눅스)계열의 파일디스크립터는 같은 의미로 보시면 됩니다.

리눅스는 모든 장치를 파일로 관리 하기 때문에 파일디스크립터를 이용하여 장치에 접근 할 수 있게 (핸들링할수있게) 됩니다.


유닉스(리눅스) 계열의 시스템에서 열린파일(디바이스 장치)을 구분하는 단위이기도 합니다.

다시한번 강조하지만 일반파일 뿐만아니라 모든 외부장치도 파일로 취급한다고 했습니다. 기억하세요.


커널은 프로세스 단위로 열린파일 목록 (open()을 통해 파일 즉, 일반 파일및 모든 장치 를 열게 되면 디스크립터 번호가 부여되고 이것이

테이블로 관리됨) 을 담아 둘 수 있는 테이블을 관리하는데, 파일 디스크립터가 이 테이블에 등록되어 관리되고 있습니다.


테이블에 새로운 디스크립터를 등록하게 되면 파일디스크립터는 0부터 순차적으로 1만큼 자동으로 등록 되게 됩니다.

윈도우의 핸들과 개념은 거의 같다고 봐도 무방하지만 순차 등록되지 않는다는 차이점을 가지고 있습니다.


그럼 프로세스를 실행할 대 open함수를 통해 파일을 하나 열었다고 생각해 봅시다. 그 파일의 파일디스크립터는 0번일까요?

답은 아니오 입니다. '0', '1', '2' 의 번호는 이미 예약되어 있기 때문입니다.


'0' -> 표준입력 : 키보드

'1' -> 표준출력 : 모니터

'2' -> 표준에러 : 모니터


3번부터 번호를 부여 받겠네요. ( 일반적인 경우입니다. 간혹 필요에 의해 표준 1번이 close된 상태라면 1번을 부여 받겠죠 비어있으니까요..)


프로세서가 생성되면 개별적으로 파일디스크립터 테이블을 갖게 됩니다.

일반적으로 쉘(shell)에서 새로 실행한 프로세스가 모두 0~2가 예약되어 있으며,

어떤 프로세스에 파일 디스크립터 수가 늘어나도 새로 시작된 다른 프로세스도 모두 0~2만 사용된다는 것은 

프로세스마다 개별적으로 디스크립터 테이블을 가지고 있다는 것과 쉘에서 시작한 프로세스는 1번 프로세스(PID 1번)이자 

모든 프로세스의 부모 프로세스인 'init' 프로세스에서 fork()를 통해 파일 테이블이 복사된 것이라 추측할 수 있게 됩니다.


자신이 개발하는 프로세스에 파일 디스크립터를 추가하고, fork()를 통해 자식 프로세스를 생성하면 부모의 파일 디스크립터가 그대로

복사되는 것을 알 수 있고, 이를 통해 부모, 자식 프로세스간 IPC(PIPE나 socket으로 프로세스간 통신)을 구현 할 수 있으면

이를 통해 부모, 자식 프로세스간 파일 디스크립터를 복사 및 공유 가능한 사실도 알 수 있게됩니다.


파일 디스크립터는 일반적인 고수준 API가 아닌 저수준 API라 할 수 있는 시스템 콜에 주로 사용되며, 파일 디스크립터 생성시 '0'부터 

시작하는 만큼 '-1'은 오류가 있을 의미하게 됩니다.

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

htonl() htons() ntohl() ntohs()  (0) 2011.12.28
socketpair  (0) 2011.12.27
perror  (0) 2011.12.23
write  (0) 2011.12.23
read  (0) 2011.12.23
:

perror

OS/리눅스 & 유닉스 2011. 12. 23. 13:39

perror

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 예제

시스템 에러 메시지를 출력한다.


1.1절. 사용법

#include <stdio.h>
 
void perror(const char *s);
		


1.2절. 설명

perror() 함수는 표준 에러메시지를 화면에 출력(표준출력) 시켜준다. 출력되는 에러 메시지는 시스템콜 혹은 라이브러리 함수를 호출하면서 발생한 마지막 에러에 대한 설명을 나타낸다.

아규먼트로 주어지는 s 는 사용자가 먼저 출력시켜줄 사용자정의 메시지 이며, colon(":") 이 붙은후에 표준에러 메시지가 출력된다. 표준에러 메시지의 마지막에는 자동적으로 개행 처리('\n')을 하게 된다. s 는 주로 디버깅용도로 주로 사용되는데, 해당 코드를 포함하는 함수이름 등을 적는다.


1.3절. 반환값

반환값 없음


1.4절. 예제

#include <unistd.h>
#include <stdio.h>
 
int main(int argc, char **argv)
{
    if (access(argv[1], F_OK) != 0) 
        perror("파일이 존재하지 않음");
    else
        printf("파일 존재함\n");
}
		
이프로그램을 컴파일하고 실행시켰는데, 만약 아규먼트로 존재하지 않는 파일이름을 주었다면 다음과 같은 에러메시지를 출력할것이다.
[root@localhost test]# ./access hee
파일이 존재하지 않음 : No such file or directory
		

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

socketpair  (0) 2011.12.27
파일 디스크립터  (0) 2011.12.27
write  (0) 2011.12.23
read  (0) 2011.12.23
open  (0) 2011.12.23
:

write

OS/리눅스 & 유닉스 2011. 12. 23. 13:24

write(2)

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 에러
1.5절. 예제

파일기술자가 가리키는 파일에 쓴다. 이 파일기술자는 open(2), socket(2) 등으로 얻을수 있다.


1.1절. 사용법

#include <unistd.h>

ssize_t write(int fd, const void *buf, size_t count);
		


1.2절. 설명

첫번째 아규먼트인 fd 는 열린파일 기술자이다. 이것은 보통 open(2), socket(2) 등으로 만들어지며, 때때로 pipe(2) 등으로 만들어지기도 한다.

두번째 아규먼트는 fd 로 쓸 데이타이며, count 는 fd 쓸 데이타의 크기이다.


1.3절. 반환값

성공할경우 쓰여진 바이트 만큼이 리턴된다. 0이면 쓰여진것이 없음을 나타내며, -1 일경우는 에러가 발생했을 경우이다. 에러가 발생했을경우에는 errno 에 적당한 값이 설정된다.


1.4절. 에러

다양한 원인에 의해서 에러가 발생할수 있으며 아래와 같은 에러 메시지들이 있다.

EBADF

fd 가 유효한 파일 기술자가 아니거나 쓰여질수 없도록 열려있을경우

EINVAL

fd 가 쓰기에 적당하지 않은 객체와 연결되어 있을경우

EFAULT

buf 가 접근할 수 없는 주소 공간을 가리키고 있을때

EPIPE

fd 가 끝이 닫혀진 소켓이나 파이프에 연결되어 있을때. 쓰고 있는 프로세스가 SIGPIPE signal를 받았을때 발생한다.

EAGAIN

fd 가 비봉쇄(O_NONBLOCK) 로 열렸을경우, 데이터를 쓰기 위해 fd 와 연결된 파이프나 소켓에 공간이 없을때, 발생한다. 봉쇄로 열렸을경우에는 연결된 파이프나 소켓에 공간이 있을때까지 봉쇄된다.

EAGAIN

fd 가 비봉쇄(O_NONBLOCK) 로 열렸을경우, 데이터를 쓰기 위해 fd 와 연결된 파이프나 소켓에 공간이 없을때, 발생한다. 봉쇄로 열렸을경우에는 연결된 파이프나 소켓에 공간이 있을때까지 봉쇄된다.


1.5절. 예제

#include <fcntl.h>

#include <unistd.h>
#include <stdio.h>

struct data
{
    int         age;
    char        name[25];
};
int main()
{
    int fd;
    int n;
    struct data mydata, readdata;

    fd = open("data.txt", O_CREAT|O_RDWR);
    if (fd == -1)
    {
        perror("open error : ");
    }


    mydata.age = 25;
    strcpy(mydata.name, "hello");
    n = write(fd, (void *)&mydata, sizeof(mydata));
    close(fd);
}

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

파일 디스크립터  (0) 2011.12.27
perror  (0) 2011.12.23
read  (0) 2011.12.23
open  (0) 2011.12.23
fcntl 을 이용한 파일제어  (0) 2011.12.23
:

read

OS/리눅스 & 유닉스 2011. 12. 23. 13:23

 read(2)

차례
1.1절. 사용법
1.2절. 설명
1.3절. 반환값
1.4절. 에러
1.5절. 예제

열린 파일기술자로 부터 데이타를 읽어들인다.


1.1절. 사용법

#include <unistd.h>

ssize_t read(int fd, void *buf, size_t count);
		


1.2절. 설명

socket(2) 혹은 open(2) 등으로 열린 파일에서 원하는 데이타를 읽어들인다. fd 가 socket, open 으로 열린 파일기술자이다. fd 에 읽을 데이타가 있다면 buf 에 담아서 가져온다. count 는 buf 에서 한번에 가져올 데이타의 크기를 나타낸다.


1.3절. 반환값

성공할경우 0이상의 값을 반환한다. 0이라면 파일의 끝을 의미하며, 0 보다 큰 양수라면 이는 읽어들인 buf 의 크기를 나타낸다. 파일 끝이 아닌상태에서 파일에서 데이타를 가져오는데 성공했다면, 파일 포인터의 위치는 읽은 데이타의 크기만큼 이동하게 된다.

에러가 발생할경우 -1 을 되돌려주며 errno 는 적당한 값으로 설정된다. 에러가 발생했을경우 파일 포인터의 위치가 어떻게 바뀔지는 예측할수 없다.


1.4절. 에러

다양한 원인에 의해서 에러가 발생할수 있으며 아래와 같은 에러 메시지들이 있다.

EINTR

데이타를 읽기전에 함수가 신호(signal)에 의해 인터럽트 되었다.

EAGAIN

비봉쇄로 열린 파일지시자에 즉시 읽을 데이타가 없을 경우.

EIO

I/O 에러.

EISDIR

파일지시자 fd 가 디렉토리를 가르킬경우.

EBADF

파일지시자 fd 가 유효한 파일기술자가 아니거나 읽기 위해 열려있지 않을경우

EINVAL

fd 가 읽기에 적당하지 않은 객체와 연결되어 있다.

참고) errno.h 를 include 해야함. 


1.5절. 예제

#include <unistd.h>

#include <stdio.h>
#include <string.h>

#define STDIN 1

int main()
{
    char buf[80];

    memset(buf, 0x00, 80);
    if (read(STDIN, buf, 80) < 0) 
    {
        perror("read erro : ");    
        exit(0);
    }

    printf("%s", buf);
}
		

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

perror  (0) 2011.12.23
write  (0) 2011.12.23
open  (0) 2011.12.23
fcntl 을 이용한 파일제어  (0) 2011.12.23
mktime 날짜를 Unix Time으로 전환  (0) 2011.12.08
: