블로그 이미지
GUCCI

카테고리

전체보기 (111)
여행 (1)
기기 (2)
쇼핑 (0)
게임 (0)
etc. (6)
취업이야기 (0)
업무일지 (5)
리눅스 (38)
웹프로그래밍 (2)
네트워크 (4)
JAVA (17)
Android (0)
IOS (2)
LUA (8)
C/C++ (1)
Objective C (2)
SERVER (2)
그누보드4 (1)
MSSQL (2)
Programming (1)
자바스크립트 (4)
HTML/CSS (1)
LGNAS (0)
Total
Today
Yesterday

'리눅스'에 해당되는 글 38건

  1. 2012.02.08 VI 편집기 사용법 1
  2. 2012.02.08 쉘스크립트 조건문 7
  3. 2012.02.08 getopt() 5
  4. 2012.02.08 리눅스 lspci 명령어 2
  5. 2012.02.08 리눅스 Errorno errno 4
  6. 2012.02.08 리눅스 커널의 구조 1
  7. 2012.02.08 쉘스크립트 1
  8. 2012.02.08 #!/bin/sh 3

VI 편집기 사용법

리눅스 / 2012. 2. 8. 19:38

vi 시작

 텍스트 삭제

 

 vi filename

 파일열기, 작성

 

 x

 문자 삭제

 

 vi +18 filename

 18행으로 파일 열기

 

 dw

 단어 삭제

 

 vi +/"string" fn

 "string"의 처음 발생 단어부터

 

 dd

 행 삭제

 

 vi -r filename

 손상된 파일 회복

 

 D

 커서 오른쪽 행 삭제

 

 view filename

 읽기 전용으로 파일 열기

 

 :5,10 d

 5-10 번째 행 삭제

 커서명령(이동)

 텍스트 복사 및 이동

 

 h(←)

 왼쪽으로 커서 이동

 

 yy

 행 yank 또는 복사

 

 j(↓)

 아래로 커서 이동

 

 Y

 행 yank 또는 복사 

 

 k(↑)

 위로 커서 이동

 

 dd

 행 삭제

 

 l(→)

 오른쪽으로 커서 이동

 

 P

 yank되거나 삭제된 행 현재 행 위에 삽입

 

 w

 한 단어 오른 쪽으로 커서 이동 

 

 p

 yank되거나 삭제된 행 현재 행 아래에 삽입

 

 b

 한 단어 왼쪽으로 커서 이동 

 

 :1,2 co 3

 1-2행을 3행 다음으로 복사

 

 Return

 한 행 아래로 커서 이동

 

 :4,5 m 6

 4-5행을 6행 위로 이동

 

 Back Space

 한 문자 왼쪽으로 커서 이동

 행 번호 설정

 

 Space Bar

 한 문자 오른 쪽으로 커서 이동

 

 :set nu

 행 번호 표시

 

 H

 화면의 맨위로 이동

 

 :set nonu

 행 번호 숨기기

 

 M

 화면의 중간으로 이동

 행 찾기

 

 L

 화면의 맨 아래로 이동

 

 G

 파일의 마지막 행으로 가기

 

 Ctrl + F

 한 화면 앞으로 이동

 

 21G

 파일의 21번째 행을 가기

 

 Ctrl + D

 반 화면 앞으로 이동

 탐사 및 대체

 

 Ctrl + B

 한 화면 뒤로 이동

 

 /string/

 string 탐색

 

 Ctrl + U

 반 화면 뒤로 이동

 

 ?string?

 string 역방향 탐색

 문자와 행 삽입

 

 n(N)

 string의 다음(이전) 계속 탐색

 

 a

 커서 오른쪽에 문자 삽입

 

 :g/search-string/s//replace-string/gc 

 

 A

 커서 오른쪽, 행의 끝에 문자 삽입

 

 

 각 발생 탐색 후 확인하고 대체

 

 i

 커서 왼쪽에 문자 삽입

 

 :s/srt/rep

 현재 행의 str을 rep로 대체

 

 I

 커서 왼쪽, 행의 처음에 문자 삽입

 

 :1,.s/str/rep/

 1부터 현재 행의 str을 rep로 대체

 

 o

 커서 아래에 행 삽입

 

 :%s/str/rep/g

  파일 전체 str을 rep로 전부 대체

 

 O

 커서 위에 행 삽입

 

 

 

 텍스트 변경

 화면정리

 

 cw  (종료:ESC)

 단어변경

 

 :Ctrl-1

 불필요한 화면정리 후 다시 표시

 

 cc  (종료:ESC)

 행 변경

 파일을 파일로 삽입

 

 C   (종료:ESC)

 커서 오른쪽의 행 변경

 

 :r filename

 커서 다음에 파일 삽입

 

 s   (종료:ESC)

 커서가 위치한 문자열 대체

 

 :34 r filename

 파일을 34번째 행 다음에 삽입

 

 r

 커서 위치의 문자를 다른 문자로 대체

 보관 및 종료

 

 r - Return

 행 분리

 

 :w

 변경사항 보관

 

 J

 현재 행과 아래 행 결합

 

 :w filename

 버퍼를 파일로 보관

 

 xp

 커서 위치 문자와 오른쪽 문자 교환

 

 :wq

 변경사항 보관 후 vi 종료

 

 ~

 문자형(대.소문자)변경

 

 ZZ

 변경사항 보관 후 vi 종료 

 

 u

 이전 명령 취소

 

 :q!

 변경사항 보관하지 않고 종료

 

 U

 행 변경 사항 취소

 

 

 

 

 :u

 이전의 최종 행 취소

 

 

 

 

 .

 이전 최종 명령 반복

 

 

 

'리눅스' 카테고리의 다른 글

OpenWrt The Boot Process  (5) 2012.02.09
vi 에디터 명령어  (2) 2012.02.08
getopt()  (5) 2012.02.08
리눅스 lspci 명령어  (2) 2012.02.08
리눅스 Errorno errno  (4) 2012.02.08
Posted by GUCCI
, |

1. /etc/profile - 콘 쉘이 로그인 쉘로 지정된 모든 사용자가 로그인할 때마다 이 파일을 읽는다.

2. $HOME/.profile - 콘 쉘이 로그인 쉘로 지정된 사용자가 로그인할 때마다 홈 디렉토리에 파일이 있으면 읽는다.

3. $HOME/.kshrc - 콘 쉘이 로그인 쉘로 지정된 사용자가 로그인할 때마다 $HOME/.profile파일에서 따로 설정이

                            되어 있으면 추가로 읽는 파일이다.

 

$0 - 쉘 스크립트의 이름

$1 - $9 - 첫 번째 아규먼트,두 번째 아규먼트, ... , 아홉번 째 아규먼트

${10} - ${n} - 열 번째 아규먼트, 열한 번째 아규먼트, ... ,n번째 아규먼트

$# - 아규먼트의 개수

$@ - 쉘 스크립트에 입력된 모든 아규먼트

$* - 쉘 스크립트에 입력된 모든 아규먼트

 

조건문

본쉘                                  콘쉘                                              의미

[-r file_name]          [[-r file_name]]           file_name의 내용을 읽을 수 있는지 검사

[-w file_name]        [[-w file_name]]          file_name의 내용을 변경할 수 있는지 검사

[-x file_name]         [[-x file_name]]           file_name을 실행할 수 있는지 검사

불가능                    [[-O file_name]]          file_name의 소유주가 스크립트를 실행하는 사람인지 검사(Owner)

불가능                    [[-G file_name]]          file_name의 그룹 소유주가 스크립트를 실행하는 사람이 속한 그룹인지 검사

[-f file_name]          [[-f file_name]]           file_name이 일반적인 파일인지 검사

[-d file_name]         [[-d file_name]]          file_name이 디렉토리인지 검사

[-c file_name]         [[-c file_name]]          file_name이 캐릭터 디바이스 파일인지 검사

[-b file_name]         [[-b file_name]]          file_name이 블록 디바이스 파일인지 검사

불가능                    [[-L file_name]]          file_name이 심볼릭 링크인지 검사

[-s file_name]         [[-s file_name]]          file_name의 크기가 0보다 큰 값인지 검사

불가능                    [[-e file_name]]          file_name이 존재하는지 검사(Exist)

 

본쉘                                       콘쉘                                               의미

[$num1 -eq $num2]        ((num1 == num2))         num1과 num2가 같은 값인지 검사(equal)

[$num1 -ne $num2]        ((num1 != num2))          num1과 num2가 다른 값인지 검사(not equal)

[$num1 -lt $num2]          ((num1 < num2))          num1이 num2보다 작은 값인지 검사(Less than)

[$num1 -gt $num2]         ((num1 > num2))          num1이 num2보다 큰 값인지 검사(greater than)

[$num1 -le $num2]         ((num1 <= num2))         num1이 num2보다 작거나 같은 값인지 검사(less than or equal)

[$num1 -ge $num2]        ((num1 >= num2))         num1이 num2보다 크거나 같은 값인지 검사(greater than or equal)

 

본쉘                               콘쉘                                   의미

[str1 = str2]             [[str1 == str2]]                 str1과 str2가 같은 값인지 검사

[str1 != str2]            [[str1 != str2]]                  str1과 str2가 다른 값인지 검사

불가능                    [[str1 == pattern]]             str1이 pattern으로 표현할 수 있는지 검사

불가능                    [[str1 != pattern]]              str1이 pattern으로 표현할수 없는지 검사

[str1 < str2]            [[str1 < str2]]                   str1과 str2를 사전 순으로 비교하여 str1이 앞서 있는지 검사

[str1 > str2]            [[str1 > str2]]                   str1과 str2를 사전 순으로 비교하여 str2가 앞서 있는지 검사

[-z str2]                 [[-z str2]]                        str1의 길이가 0인지 검사

[-n str2]                 [[-n str2]]                        str1의 길이가 1이상인지 검사

 

본쉘              콘쉘                                        의미

-o                 ||                     양쪽 조건 중 어느 하나만 만족하면 모든 조건이 만족

-a                 &&                    양쪽 조건 모두 다를 만족하면 모든 조건이 만족

!                                           조건이 결과 값을 반대로 바꿈

 

 

if문 - 조건의 진리 값이 참인 경우와 거짓인 경우로 나누어서 어느 부분을 선택하여 실행할 것인지를 결정                           

if 조건문                                          if 조건문                                      if 조건문

then                                                then                                           then

    명령어들              ->                           명령어            ->                       명령어

fi                                                    else                                           elif 조건문

                                                            명령어                                  then

                                                      fi                                                     명령어

                                                                                                       else

                                                                                                           명령어

                                                                                                        fi

Case문 : if문의 또다른 형태

case value in

pattern1|pattern2)

        명령어

         ;;

pattern3|pattern4)

        명령어

         ;;

pattern5|pattern6)

         명령어

         ;;

*)

         명령어

         ;;

esac

 

for문 : 미리 정해진 횟수를 반복할 때 사용

for var in list_of_value

do

      명령어

done

 

while문 : 조건을 만족하는 동안 반복하는데 사용

while 조건문

do

    명령어

done

 

until문 : 조건이 만족되지 않은 동안에만 반복한다.

until 조건문

do

    명령어들

done

 

select문 : 메뉴를 만들고 사용자가 메뉴에서 선택한 값에 따라서 명령어를 실행할 때 사용

select var in list_of_value

do

   명령어들

done

'리눅스 > 쉘스크립트' 카테고리의 다른 글

쉘 내장 명령어  (2) 2012.02.14
쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트  (1) 2012.02.08
#!/bin/sh  (3) 2012.02.08
Posted by GUCCI
, |

getopt()

리눅스 / 2012. 2. 8. 19:01

■ getopt 함수란

 유닉스나 리눅스에서 프로그램 실행 시 '-a', '-l' 등 별도의 옵션을 줄 수 있다. 이러한 옵션(아규먼트)을 쉽게 처리하기 위해 만들어진 함수가 getopt이다. 유닉스는 unistd.h를 리눅스는 getopt.h 헤더파일을 include하면 사용 할 수 있다. 그리고 이 함수는 main함수에서 많이 사용되고 있다.

 

모든 C(C++)로 된 프로그램은 보통 main 함수를 정의할 때 아래와 같이 두 개의 파라미터를 가진다. 프로그램이 커맨드 라인에서 인수를 받는 방법은 main 함수를 통해서만 가능하다.

 

int main(int argc, char *argv[])

argc 파라미터는 커맨드 라인에서 넘어온 인수의 개수를 뜻하며, argv 파라미터는 C 문자열 벡터이다.  argv 의 각 요소들은 공백으로 분리된 개별적인 커맨드 라인 인수 문자열이다.


만약 프로그램에서 커맨드 라인 인수들의 구분이 간단하다면, 굳이 getopt 함수를 사용하디 않고 직접 argv로부터 간단하게 하나씩 인수를 가져올 수 있다. 하지만 프로그램이 한정된 인수들의 개수를 갖지 않거나 모든 인수들을 한꺼번에 취하지 않는다면 같은 방법으로 인수들을 취할 수도 있지만 그것을 구문 분석 하기 위해 getopt()를 사용해서 인수들을 처리하는 것이 보다 효과적이다. 예를들어 흔히 사용되어 지는 ls 명령어조차도 "ls -al"과 같은 옵션을 지원한다. ls -al 에서 보듯이 이것은 ls -a -l 로도 사용될수도 있고, ls -l -a 로도 사용될수 있다. 이것을 프로그램 내에서 사용자 정의 함수를 이용해서 처리하려고 하면 보통 일이 아닐것이다. 그럼 getopt 함수 사용예제를 보자.

 

■ getopt를 이용한 프로그램 인자 처리  

 getopt 를 이용해서 다양한 옵션을 처리하는 testopt 라는 프로그램을 만들어 보도록 하겠다. 프로그램 이름은 testopt.c로 하겠다.

#include <unistd.h> 
#include <stdio.h> 
#include <string.h> 
#include <stdlib.h> 
#include <sys/types.h> 
#include <sys/stat.h> 
#include <fcntl.h> 
 
void help(); 
void version(); 
int main(int argc, char **argv) 
{  
    int opt; 
    int port_num; 
    int fp; 
    int opt_ok; 
    char file_name[16]; 
    char buf[256]; 
 
    while((opt = getopt(argc, argv, "hvf:")) != -1)  
    { 
        switch(opt)  
        {  
            case 'h': 
                help();  
                break;  
            case 'v': 
                version();   
                break; 
            case 'f': 
                memcpy(file_name, optarg, 16); 
                opt_ok = 1; 
                break; 
        } 
    }  
    if (opt_ok != 1) 
    {  
        help(); 
        exit(0); 
    }  
 
    if (access(file_name, R_OK) != 0) 
    { 
        printf("파일이 존재하지 않습니다"); 
        exit(0); 
    } 
    if((fp = open(file_name, O_RDONLY)) == -1) 
    { 
        printf("file open error"); 
        exit(0); 
    } 
 
    memset(buf, '0', 256); 
    while(read(fp, buf, 256) > 0) 
    { 
        printf("%s", buf); 
        memset(buf, '0', 256); 
    } 
} 
 
void help() 
{ 
    printf("Usage: ./testopt [OPTION] [FILE]" 
           "  -h                도움말" 
           "  -f [FILE]         파일출력" 
           "  -v                버전출력"); 
    exit(0); 
} 
 
void version() 
{ 
    printf("Version : 1.01"); 
    exit(0); 
} 
 

매우 간단하고 이해가 쉬운 예제이다. getopt 를 이용해서 프로그램의 인자를 검사 해서 '-' 가 앞에 붙어 있는 인자는 옵션으로 간주해서 "hvf" 중 어느 옵션인지를 건사해서 해당 루틴을 실행시켜준다. 단 "f" 의 경우에는 ":" 가 붙어 있는데, 이는 "f" 옵션은 반드시 뒤에 값이 따라야 함을 명시하고 있다. 여기에서 값이란 화면에 출력하고픈 파일이름이다. 
[root@localhost test]# ./testopt -h  
Usage: ./testopt [OPTION] [FILE] 
  -h                            도움말 
  -f [FILE]                     파일출력 
  -v                            버전출력 
 [root@localhost test]# ./testopt -f 
./testopt: option requires an argument -- f 
Usage: ./testopt [OPTION] [FILE] 
  -h                            도움말 
  -f [FILE]                     파일출력 
  -v                            버전출력 

[출처] getopt()|작성자 시대유감


'리눅스' 카테고리의 다른 글

vi 에디터 명령어  (2) 2012.02.08
VI 편집기 사용법  (1) 2012.02.08
리눅스 lspci 명령어  (2) 2012.02.08
리눅스 Errorno errno  (4) 2012.02.08
리눅스 커널의 구조  (1) 2012.02.08
Posted by GUCCI
, |

리눅스 lspci 명령어

리눅스 / 2012. 2. 8. 19:00

■ lspci

시스템의 모든 PCI BUS와 장치에 대한 목록과 각개 하드웨어 설정 정보를 확인할 수 있는 명령어

 

■ Option

 옵션

설명 

 (없음)

 기본적인 하드웨어 정보가 출력된다. 주로 하드웨어 장치의 모델명이 출력된다.

 -v

 verbose를 뜻하며 장치에 대한 자세한 정보를 표시합니다.

 -vv

 very verbose를 뜻하며 PCI 장치가 말할 수 있는 모든 정보를 표시합니다.

[출처] lspci|작성자 시대유감

'리눅스' 카테고리의 다른 글

vi 에디터 명령어  (2) 2012.02.08
VI 편집기 사용법  (1) 2012.02.08
getopt()  (5) 2012.02.08
리눅스 Errorno errno  (4) 2012.02.08
리눅스 커널의 구조  (1) 2012.02.08
Posted by GUCCI
, |

리눅스 Errorno errno

리눅스 / 2012. 2. 8. 18:59
errno: 0 message: Success
errno: 1 message: Operation not permitted
errno: 2 message: No such file or directory
errno: 3 message: No such process
errno: 4 message: Interrupted system call
errno: 5 message: Input/output error
errno: 6 message: No such device or address
errno: 7 message: Argument list too long
errno: 8 message: Exec format error
errno: 9 message: Bad file descriptor
errno: 10 message: No child processes
errno: 11 message: Resource temporarily unavailable
errno: 12 message: Cannot allocate memory
errno: 13 message: Permission denied
errno: 14 message: Bad address
errno: 15 message: Block device required
errno: 16 message: Device or resource busy
errno: 17 message: File exists
errno: 18 message: Invalid cross-device link
errno: 19 message: No such device
errno: 20 message: Not a directory
errno: 21 message: Is a directory
errno: 22 message: Invalid argument
errno: 23 message: Too many open files in system
errno: 24 message: Too many open files
errno: 25 message: Inappropriate ioctl for device
errno: 26 message: Text file busy
errno: 27 message: File too large
errno: 28 message: No space left on device
errno: 29 message: Illegal seek
errno: 30 message: Read-only file system
errno: 31 message: Too many links
errno: 32 message: Broken pipe
errno: 33 message: Numerical argument out of domain
errno: 34 message: Numerical result out of range
errno: 35 message: Resource deadlock avoided
errno: 36 message: File name too long
errno: 37 message: No locks available
errno: 38 message: Function not implemented
errno: 39 message: Directory not empty
errno: 40 message: Too many levels of symbolic links
errno: 41 message: Unknown error 41
errno: 42 message: No message of desired type
errno: 43 message: Identifier removed
errno: 44 message: Channel number out of range
errno: 45 message: Level 2 not synchronized
errno: 46 message: Level 3 halted
errno: 47 message: Level 3 reset
errno: 48 message: Link number out of range
errno: 49 message: Protocol driver not attached
errno: 50 message: No CSI structure available
errno: 51 message: Level 2 halted
errno: 52 message: Invalid exchange
errno: 53 message: Invalid request descriptor
errno: 54 message: Exchange full
errno: 55 message: No anode
errno: 56 message: Invalid request code
errno: 57 message: Invalid slot
errno: 58 message: Unknown error 58
errno: 59 message: Bad font file format
errno: 60 message: Device not a stream
errno: 61 message: No data available
errno: 62 message: Timer expired
errno: 63 message: Out of streams resources
errno: 64 message: Machine is not on the network
errno: 65 message: Package not installed
errno: 66 message: Object is remote
errno: 67 message: Link has been severed
errno: 68 message: Advertise error
errno: 69 message: Srmount error
errno: 70 message: Communication error on send
errno: 71 message: Protocol error
errno: 72 message: Multihop attempted
errno: 73 message: RFS specific error
errno: 74 message: Bad message
errno: 75 message: Value too large for defined data type
errno: 76 message: Name not unique on network
errno: 77 message: File descriptor in bad state
errno: 78 message: Remote address changed
errno: 79 message: Can not access a needed shared library
errno: 80 message: Accessing a corrupted shared library
errno: 81 message: .lib section in a.out corrupted
errno: 82 message: Attempting to link in too many shared libraries
errno: 83 message: Cannot exec a shared library directly
errno: 84 message: Invalid or incomplete multibyte or wide character
errno: 85 message: Interrupted system call should be restarted
errno: 86 message: Streams pipe error
errno: 87 message: Too many users
errno: 88 message: Socket operation on non-socket
errno: 89 message: Destination address required
errno: 90 message: Message too long
errno: 91 message: Protocol wrong type for socket
errno: 92 message: Protocol not available
errno: 93 message: Protocol not supported
errno: 94 message: Socket type not supported
errno: 95 message: Operation not supported
errno: 96 message: Protocol family not supported
errno: 97 message: Address family not supported by protocol
errno: 98 message: Address already in use
errno: 99 message: Cannot assign requested address
errno: 100 message: Network is down
errno: 101 message: Network is unreachable
errno: 102 message: Network dropped connection on reset
errno: 103 message: Software caused connection abort
errno: 104 message: Connection reset by peer
errno: 105 message: No buffer space available
errno: 106 message: Transport endpoint is already connected
errno: 107 message: Transport endpoint is not connected
errno: 108 message: Cannot send after transport endpoint shutdown
errno: 109 message: Too many references: cannot splice
errno: 110 message: Connection timed out
errno: 111 message: Connection refused
errno: 112 message: Host is down
errno: 113 message: No route to host
errno: 114 message: Operation already in progress
errno: 115 message: Operation now in progress
errno: 116 message: Stale NFS file handle
errno: 117 message: Structure needs cleaning
errno: 118 message: Not a XENIX named type file
errno: 119 message: No XENIX semaphores available
errno: 120 message: Is a named type file
errno: 121 message: Remote I/O error
errno: 122 message: Disk quota exceeded
errno: 123 message: No medium found
errno: 124 message: Wrong medium t

[출처] errno|작성자 시대유감


'리눅스' 카테고리의 다른 글

vi 에디터 명령어  (2) 2012.02.08
VI 편집기 사용법  (1) 2012.02.08
getopt()  (5) 2012.02.08
리눅스 lspci 명령어  (2) 2012.02.08
리눅스 커널의 구조  (1) 2012.02.08
Posted by GUCCI
, |

 

 일반적으로 운영체제가 관리할 자원은 크게 물리적인 자원(physical resource)과 추상적인 자원(abstract resource)으로 구분 할 수 있다. 물리적인 자원은 처리기(CPU), 메모리, 디스크, 터미널, 네트워크 등 시스템을 구성하고 있는 요소들과 주변장치 등이 있다. 추상적인 자원은 물리적인 자원을 운영체제가 관리하기 위해 추상화 시킨 객체들이다. 물리적인 자원은 하드웨어를 말하고, 추상적인 자원은 소프트웨어를 말한다. 즉 운영체제는 하드웨어를 소프트웨어로 추상화하는 역할을 한다. 위의 그림은 리눅스 커널 내부의 논리적인 구성요소를 구분하여 도식화한 것이다.

'리눅스' 카테고리의 다른 글

vi 에디터 명령어  (2) 2012.02.08
VI 편집기 사용법  (1) 2012.02.08
getopt()  (5) 2012.02.08
리눅스 lspci 명령어  (2) 2012.02.08
리눅스 Errorno errno  (4) 2012.02.08
Posted by GUCCI
, |
주석문 
'#'로 시작하는 줄. 
줄의 중간에 '#'이 와도 주석으로 인식하지만 다음과 같이 이상하게 동작하는 
경우가 발생한다. > 
코드:

    #!/bin/sh
    AA=abcd     # 여기는 주석.
    BB=${AA}kkk
    echo ${BB}

실제 원하는 출력은 "abcdkkk"이지만 실제 출력은 "abcd kkk"가 되어 버린다. 
즉, abcd뒤쪽의 공백문자가 포함되어 버린다. 
따라서 줄의 중간에 '#'을 넣어서 주석을 만들지는 말것. 
실제 test를 해보니까 그렇지 않는 것 같다(bash-2.05b). 


Shell Script 실행하기 
코드:

    1. $ source sample
    2. $ . sample
    3. $ bash sample
    4. $ chmod +rx sample;./sample  // #!/bin/bash 포함.
        모드를 변경할때 rx를 주어야 한다. shell scripts는 shell에서 읽어서
        수행해야 하므로 read 속성이 주어져야만 한다.

위에서 1, 2번 그리고 3,4번은 실행이 다르다. 1,2번은 기존에 존재하던 shell에서 
스크립트를 수행하고 3,4번은 새로운 셀을 생성해서 실행하게 된다. 이 경우에 
문제가 되는것은 스크립트 내부에서 "exit 0"과 같은 명령을 사용하면 1, 2번의 
경우는 현재 shell이 닫혀버린다. 

그리고 또하나의 문제는 1,2번의 경우는 현재 shell에서 이어져서 수행되므로 
스크립트 내부에서 사용한 변수나 함수들이 그대로 남아있다. 하지만 3,4번의 
경우는 현재 셀의 서브셀로 수행되므로 스크립트가 종료된후에는 스크립트내부의 
변수나 함수는 현재 셀에서 유효하지 않게 된다. 

따라서 수행하는 스크립트의 변수나 함수를 현재 셀에서도 유효하게 할때는 
". sample" 나 "source sample"를 사용하고 그냥 스크립트를 수행하고 종료시킬때는 
"bash sample" 나 "./sample"를 사용 



매직넘버 
리눅스에서는 기본 셀인 배쉬이외에도 다양한 종류의 셀을 사용할 수 있다. 
따라서 배쉬용 셀스크립트가 씨셀에서 실행된다면 오류가 발생할 수 있다. 
따라서 스크립트 파일의 처음 행에 파일을 실행시키는데 사용할 셀의 절대 
경로를 아래와 같이 표시하게 된다. 
코드:

    #!/bin/bash

이 매직넘버는 수행을 의미하므로 다음과 같이 사용할 수도 있다. 다음은 자기 
자신을 출력하는 shell script이다. 
코드:

    #!/bin/cat

이 파일은 스스로를 출력하는 셀스크립트이다. 



셀스크립트 확인하기 
코드:

    $ file sample

결과는 ASCII가 아니라 C 스크립트 파일로 나타난다. 



변수의 사용 
$A A라는 변수 
이렇게 사용하는 것은 지양하도록 한다. 만약 A라는 변수가 정의되지 
않았을때 완전히 공백이 되어 버리기 때문에 다음과 같은 경우에 
에러가 발생한다. 
코드:

            if [ $A = '1' ];then
                echo "A is 1"
            fi


${A} A라는 변수 
"$A" A라는 변수 
'$A' '$A'라는 스트링 
\$A '$A'라는 스트링 
`$A` A라는 변수명의 명령의 실행. 
`AA` AA라는 명령의 수행.(이식성이 강한 오래된 관습) 

다음과 같이 사용할 경우 
코드:

                AA=`AA`
                BB=$(AA)kkk
            


BB는 다음과 같이 확장된다. 
코드:

                BB=`AA`kkk
            


따라서 다음과 같이 사용하는 방법을 고려해 볼 것. 
코드:

                AA=$(shell AA)
                BB=$(AA)kkk
            


AA는 명령이 수행된후 곧바로 확장되게 된다. 

$(AA) AA라는 명령의 수행. 

$(shell AA) AA라는 명령의 수행. 


변수에 값을 대입하기 
코드:

    <case1> AA = "3333"     (X)
    <case2> BB="3333"       (O)

<case1>과 <case2>는 차이가 없어 보이지만 엄청난 차이가 존재한다. shell은 위 
명령을 수행하면서 <case1>의 경우는 'AA'라는 명령을 수행하면서 그 파라메터로 
'='와 "3333"을 대입하는 것으로 처리한다. 따라서 결과는 'AA'라는 명령이 없다고 
출력된다. 
<case2>의 경우는 shell이 'BB'라는 변수에 "3333"을 대입하는 것으로 정확하게 
인식한다. 따라서 <case2>의 경우가 정확한 표현이다. 즉 '='의 양쪽을 띄어쓰지 
않는다. 


변수의 확장의 방지 
코드:

    #!/bin/sh
    #출력이 0_tmp, 1_tmp라고나오길 기대하지만 shell은 i_tmp라는 변수가
    #존재하지 않으므로 공백을 출력하게 된다.
    for i in 0 1 2
    do
        echo $i_tmp
    done

    #정상적으로 된 경우. 변수를 확장하지 않으므로 0_tmp, 1_tmp, 2_tmp가 출력.
    for i in 0 1 2
    do
        echo ${i}_tmp
    done

    #두번째 방법
    for i in 0 1 2
    do
        echo $i{_tmp}
    done



조건 제어구문 
코드:

    if, case, while, for, until

    if test     조건
    then        명령어
    fi

    if test; then
    fi

    if test     조건
    then        명령어
    else        조건을 만족하지 않았을때 실행할 명령어
    fi

    if test     조건
    then        명령
    elif test   조건
    then        명령
    else        명령
    fi

    다음과 같은 에러메세지가 발생하는 이유는 다음과 같다.
        [: =: unary operator expected
    비교하는 파라메터를 ""로 감싸주지 않았을 때 만약 파라메터가 NULL
    String이라면 다음과 같이 취금되어 버린다.
        if [ = "yes" ]
    따라서 파라메터는 무조건 다음과 같이 ""로 감싸서 처리해주어야 한다.
        if [ "$timeofday" = "yes" ]
        if [ "" = "yes" ]



조건의 Test 
test or [] 
[]를 사용할때는 '['와 ']'와 조건사이에 빈칸을 삽입해야만 한다. 



true와 false 
셀스크립트의 조건문에서 참은 0을, 거짓은 0이 아닌값을 의미한다. 

코드:

    # true
    # echo $?
    0

    # false
    # echo $?
    1

    if true; then
    fi

    if faluse; then
    fi


조건문의 논리를 단순화하기 위해 true를 대신하는 별칭으로 ':'를 종종 
사용한다. 

코드:

    if :;then
    fi



함수의 실행결과(반환값)을 조건문에 대입하기 
잘못된 예1 > 
코드:

    exe_command
    if [ $? ]; then
        # 0이 아닌 어떤 반환값에 대해서도 들어올 것 같은데
        # 실제로는 모든 반환값에 대해서 이곳으로 들어온다. 따라서 잘못된
        # 예제이다.
        echo return value is true.
    fi


잘못된 예2 > 
코드:

    RET=`exe_command`
    if [ RET = 0 ];then
        # RET에는 exe_command의 반환값이 아니라 stdout 출력값이 들어가게 된다.
        # 따라서 위 문장은 정확한 표현이 아니다.
        echo return value is true
    fi


맞는 예1 > 
코드:

    exe_command
    if [ $? -eq 0 ]; then
        echo return value is true.
    fi


맞는 예2 > 
코드:

    if exe_command; then
        echo return value is true.
    fi


맞는 예3 > 
코드:

    exe_command
    case $? in
        0)
            echo "return zero";;
        1)
            echo "return one";;
        *)
            echo "unknown return value";;
    esac



if문 
코드:

    if [ -f ~/.bashrc ]; then
        . ~/.bashrc
    fi

    if [ -f ~/.bashrc ]
    then
        . ~/.bashrc
    fi


테스트 조건 파일 옵션 

    -b 디스크 드라이브와 같은 Block형 장치 
    -c 터미널, 프린터, 네트워크같이 Character형 장치 
    -d 디렉토리 
    -e 존재한다.(이식적이지 않으므로 -f를 사용한다.) 
    -f 일반파일 
    -k 스티키비트가 설정됨 
    -p 네임드 파이프의 형태 
    -r 읽기 권한이 허가된 상태 
    -s 사이즈가 0이 아님 
    -w 쓰기 권한이 허가된 상태 
    -x 실행 권한이 허가된 상태 
    -L 심벌릭 링크의 형태 
    -S 소켓의 형태 

만약 위 조건의 NOT일때는 "[ ! -f abcd.txt ]"가 된다.~ 


논리 연산 옵션 

    -a 논리적 AND 
    -o 논리적 OR 
    ! 논리적 NOT 


정수 비교 옵션 

    -eq Equal(=) 
    -ge Greater then or Equal to(>=) 
    -gt Greater then(>) 
    -le Less then or Equal to(<=) 
    -lt Less then(<) 
    -ne Not Equal(!=) 


문자열 비교 옵션 

    -n 문자열의 길이가 0이 아니다. 
    -z 문자열의 길이가 0이다. 
    = 두 문자열이 같다. 
    주의할점은 "=="와 혼동하지 말것. 
    != 두 문자열이 같지 않다. 


문자열 비교시 주의할 점. 
"[ $S1 = $S2 ]"와 같이 사용하면 $S1이나 $S2가 비어있다면 에러가 
발생한다. 따라서 다음과 같은 방법을 사용한다. 
"[ x$S1 = x$S2 ]" 혹은 [ "$S1"="$S2" ] 


while 문 
while 조건에 준하는 명령 
do 실행할 명령어 
done 


case 선택 제어문 
코드:

    #!/bin/sh
    case "$FLAG" in
        +)  exit;;                                  --> '+'이면 종료.
        [aeiou] ) echo -e "you inputvowel\n" ;;     --> aeiou이면 출력.
        *) echo -e "you input consonant\n" ;;       --> 그이외.
    esac


코드:

    #!/bin/sh
    echo "Is it morning? Please answer yes or no"
    read timeofday
    case "$timeofday" in
        yes | y | Yes | YES )
            echo "Good Morning";;
        n* | N* | [nN][oO])
            echo "Good Afternoon";;
        *)
            echo "Sorry, answer not recognized";;
    esac


for 반복 제어문 
코드:

    for TEMP in A B C D
    do
        echo $TEMP
    done


코드:

    # /etc/passwd의 각 행에 대해서 수행.
    for LINE in `cat /etc/passwd`
    do
        echo $LINE >> backup
        echo $LINE
    done


for문에 유용한 seq 명령어 
코드:

    # seq 1 3
    1
    2
    3


코드:

    #!/bin/sh
    for temp in `seq 1 3`; do
        echo $temp
    done



until 반복제어문 
명령을 먼저 실행한 후에 조건을 검사한다. 

코드:

    until [ "`who | grep jarrett`"]
    do
        echo "hacker is NOT logged in"
        sleep 1
    done
    echo -e "Notorious Hacker jarrett appeared at \a" `date`



and 리스트 
코드:

    statements1 && statements2 && statements3 && statements4
    if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo "there"
    then
        echo "all is true"
    else
        echo "there is one false"
    fi



or 리스트 
코드:

    statement1 || statement2 || statement3 || statement4

    if [ -f file_one ] || echo "hello" || echo "there"
    then
        echo "there is true more one.
    else
        echo "all is false"
    fi



문장블럭 
코드:

    get_confirm && {
        grep -v "$cdcatnum" $tracks_file > $temp_file
        cat $temp_file > $tracks_file
        echo 
        add_record_tracks
    }



쉘스크립트와 함수 
쉘스크립를 명령어 라인에서 직접 실행하면 서브셀이라 불리는 셀의 복사가 
기동되어 스크립트안의 처리는 서브셀에서 한다. 서브셀과 원래 셀의 현재 
디렉토리는 독립되어 있으므로 스크립트안에서 아무리 혅 디렉토리를 변경해도 원래 
쉘의 디렉토리에는 영향을 주지 않는다. 한편, 함수의 경우는 원래 쉘에서 그대로 
실행되므로 현재 디렉토리의 변경에 효과적이다. 
("source"나 "."로 쉘스크립트를 실행하면 현재 쉘에서 수행된다.) 
방법 : 함수를 저장하고 있는 파일을 ". func.txt"라고 실행시키면 함수가 현재 
쉘에 등록된다. 


함수의 사용 
함수를 사용할 때 주의 사항은 함수명과 뒤쪽의 '{'사이에는 반드시 공백이 
존재해야 한다. 
function이라는 단어는 생략이 가능하다. 
코드:

    #!/bin/sh
    # function foo() {...
    function foo(){
        echo "Function foo is executing"
    }

    echo "ScriptStarting"
    foo
    echo "Script Ended"
    exit 0


    # function foo() {...
    foo() { echo JAY;}
    result=$(foo)



함수에서 인자를 받기 
코드:

    #!/bin/sh

    function quit() {
        exit
    }

    function e() {
        echo $1
    }
    e Hello
    e World
    quit



함수의 반환값 이용하기 
1. 숫자값을 반환하기. 
코드:

    function func() {
        return 0
    }
    
    result=$(func)


2. 문자 스트링을 반환하기 
코드:

    function func() {
        echo kkk
    }

    result=$(func)


: 명령 
코드:

    while :     -> 무한 루프( while true와 동일하다)
    null 명령
        if 조건 ;then
            :
        else
            명령
        fi


local 키워드 
함수내부의 지역 변수를 선언할때 사용. 
local var="aldfjas" 

코드:
    
    #!/bin/sh
    sample_text="global variable"
    foo(){
        local sample_text="local variable"
        echo "Function foo is executing"
        echo $sample_text
    }

    echo "script starting"
    echo $sample_text

    foo



eval 
인수를 평가하게 해준다. 

    foo=10 --> foo <- 10 
    x=foo --> x <- foo 
    y='$'$x --> y <- $foo 
    echo $y --> $foo가 출력 

    foo=10 --> foo <- 10 
    x=foo --> x <- foo 
    eval y='$'$x --> y <- $foo 
    echo $y --> $foo인 10이 출력 


exec 
현재 셀을 다른 프로그램으로 대체한다. 

    exec echo "asljfasldfkasdlf" --> exec 아래의 명령은 실행되지 않는다. 



exit n 
스크립트의 반환값을 지정한다. 만약 종료상태를 지정하지 않고 종료한다면 
마지막에 실행된 명령의 반환값으로 사용될 것이다. 

    반환값 0 : 성공 
    1 ~ 125 : 스크립트에 의해 사용될 수 있는 값. 
    126 : 파일이 실행 가능하지 않다. 
    127 : 명령이 발견되지 않았다. 
    128이상 : 시그널이 발생했다. 


printf 
최신 셀에서만 유효하다. 
코드:
    
    printf "format string" paramerter1 parameter2
    printf "%s\n" hello
    printf "%s %d\t%s" "Hi There" 15 Peopel



    \\ : 백슬래쉬 
    \a : 경고 
    \b : 백스페이스 
    \f : 폼피드 
    \n : 새줄 
    \r : 개행 
    \t : 수평탭문자 
    \v : 수직탭문자 
    \000 : 8진수 값을 가지는 한 문자 


set 명령 
set 명령은 쉘을 위한 파마메터 변수를 설정한다. 이것은 빈칸으로 구분되는 
값을 출력하는 명령에서 필드를 사용하는 유용한 방법이 될 수 있다. 

코드:

    # date의 출력결과가 "2003. 06. 22. (일) 19:54:41 KST"일때.

    set $(date)



    # $0 -> date 명령을 지시하지 않고 현재 쉘스크립트의 이름을 지시한다. 
    # $1 -> "2003." 
    # $2 -> "06." 
    # $3 -> "22." 
    # $4 -> "(일)" 
    # $5 -> "19:59:06" 
    # $6 -> "KST" 


shift 
$2 -> $1 
$3 -> $2 


trap 
시그널(signal)을 받아들일 때 수행하는 동작을 지정하는 데 사용된다. 
[list] 
trap `rm -f /tmp/my_tmp_file_$$` INT 
--> INT(CTRL+C)가 발생하면 수행하는 명령. 
trap - INT --> trap해제. 
[list] 

명령의 수행 

    `명령` : 이식성이 강한 오래된 관습. 
    $(명령) : 



산술 확장 

echo $((1+1) 
echo $(( 1 + 1 )) 
echo $[1+1] 
echo $[ 1 + 1 ] 
echo `echo 1+1 | bc -l` 
코드:

    $(())

    #!/bin/sh
    # 주의할 점은 "x = $(($x+1)"이라고 '=' 양쪽을 띄어쓰지 않는다.
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        x=$(($x+1))
    done


    #!/bin/sh
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        let x = $x + 1
    done


    #!/bin/sh
    x=0
    while [ "$x" -ne 10 ]; do
        echo $x
        let x-=1
    done


    #!/bin/sh
    i=0
    while [ "$i" -ne 10 ]; do
        filename=`printf %06d.jpeg "$i"`
        echo "$filename"
        sleep 1
    done]


toggle 상태 만들기. 
코드:

    val=0
    while true; do
        echo $val
        # 주의할 점은 '=' 양쪽에 공백이 들어가서는 안된다.
        val=$(( 1 - $val))
        # 혹은 "let val= 1 - $val"
        sleep 1
    done



파라미터 변수 
[list] 
$1,$2,... 스크립트에 주어진 파라미터 
"$9"보다 큰 매개변수는 "${10}"와 같이 "{}"로 감싸주어야 한다. 

$* 환경변수 IFS의 첫문자로 구분되고, 하나의 변수에 저장되는 모든 
파라미터의 목록, 만약 IFS가 NULL이면 모든 파라메터가 붙어서 
나온다. 

$@ IFS 환경변수를 사용하지 않는 $*에 대한 변형 
"$*"와 "$@"중에서 "$@"를 사용하는 것을 권장한다. 

echo `basename $0` 
실행된 스크립트에 "./"가 붙어있는 경우에 떼어내고, 스크립트 
이름만을 출력한다. 
[list] 

파라메터 확장 

    ${param:-default} 
    param이 널이 아니면 param을 반환하고 널(혹은 존재하지 않으면)이면 
    default의 값을 반환한다. 이 경우에도 param의 값은 변하지 않는다. 
    ${param:=bar} 
    만약 param이 널이 아니면 param을 반환하고 널이면 param에 bar를 넣고 
    param을 반환한다. 이 경우에 param의 값이 bar로 변경된다. 
    ${param:+bar} 
    param이 존재하고 널이 아니면 bar의 값으로 설정하고 널이면 널을 반환한다. 
    어떤 경우에도 param값은 변경되지 않는다. ${param:-default}와 반대로 
    동작한다. 
    ${#param} 
    param의 길이를 제공한다. 
    ${param#word} 
    앞에서부터 가장 먼저 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param##word} 
    앞에서부터 가장 나중에 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param%word} 
    끝에서부터 가장 먼저 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param%%word} 
    끝에서부터 가장 나중에 word가 일치하는 부분까지를 제거한 나머지 부분을 
    반환한다. 
    ${param:?bar} 
    param이 널이 아니면 param을 반환하고 param이 널이면 "param: bar"를 
    출력하고 현재 셀이 종료된다. 만약 기존의 셀에서 서브셀로 수행된 
    스크립트라면 현재 셀이 종료되고 그렇지 않고 기존의 셀에서 이어져서 
    수행되었다면 "param: bar"를 출력하고 계속 수행한다. 


예제. 
코드:
    
        #!/bin/bash

        unset foo
        echo ${foo:-bar}

        foo=fud
        echo ${foo:-bar}

        foo=/usr/bin/X11/startx
        echo ${foo#*/}          // *는 0이상의 어떤 문자를 의미한다.
        echo ${foo##*/}

        bar=/usr/local/etc/local/networks
        echo ${bar%local*}
        echo ${bar%%local*}

    출력
        bar
        fud
        usr/bin/X11/startx
        startx
        /usr/local/etc/
        /usr/



shell script에서 2진수 계산하기 
코드:

    # 128과 180의 OR값 구하기
    let 'result = 128 & 180'
    echo $result

    # bc로 리다이렉션해서 x180을 2진수로 변환한 결과를 출력한다.
    # ibase : 입력의 진수(2|8|10|A)
    # obase : 출력의 진수(2|8|10|A)
    echo 'ibase=A;obase=2;180'|bc



Here Document 
코드:

    cat << !FUNKY!      --> Here document로 cat에 전달한다.
    hello
    this is a here
    document
    !FUNKY!             --> Here document끝.


>>>> 동작은 cat으로 "!FUNKY!"사이의 글자를 전달하는 역할을 한다. 


ed a_test_file << !FunkyStuff! --> ed editor Here document로 입력한다. 


.,\$s/is/was/ 


!FunkyStuff! --> here document끝. 



Scrip 디버깅 
코드:

    sh -n <script>      set -o noexec       형식에러만을 확인한다.
                        set -n              명령을 실행하지 않는다.
    sh -v <script>      set -o verbose      실행하기 전에 명령을 출력한다.
                        set -v
    sh -x <script>      set -o xtrace       명령라인에서 처리한 후에 명령을
                        set -x              출력한다
                        set -o nounset      정의되지 않은 변수가 사용될
                        set -u              때 에러 메시지를 제공한다.



조건 제어관련 셀명령 

    break for, until, while 루프를 빠져 나온다. 
    continue 루프를 계속 진행. 
    echo 표준 출력(1)으로 입력된 내용을 출력. 
    exec 현재의 셀을 이용해서 명령어를 실행시킨다. 
    exit 현재의 셀을 종료한다. 
    let 산술연산과 논리연산을 수행한다. 
    read 표준 입력(0)을 통해서 입력을 받는다. 
    return 함수를 종료한다. 
    test [] 조건을 검사한다. 
    `명령어` 명령어를 실행하고 그 결과를 대입한다. 


exit와 return 
exit는 현재 쉘스크립트를 종료하는 역할을 하고 return은 함수나 sourced 
script(?)에서만 반환하는 경우에 사용한다. 


배열의 사용 
bash의 새 버전부터는 1차원 배열을 지원한다. variable[xx]처럼 선언할 수도 있고 
'declare -a variable'처럼 직접적으로 지정해 줄 수도 있다. 배열 선언을 
역참조하려면(내용을 알아내려면) ${variable[xx]}처럼 중괄호 표기법을 사용하면 
된다. 


재지향 
파일 디스크립터 

    0 : 표준 입력 
    1 : 표준 출력 
    2 : 표준 에러 


코드:

    cat 2>&1    # 표준 에러를 표준출력으로 같이 보낸다.

    make 1>a.a 2>&1
        make의 결과를 a.a로 그리고 error 출력도 a.a로 보낸다.
    



C style의 문자열의 해석 
코드:

    # echo '111\n222\n333\n'
    111\n222\n333\n

코드:

    # echo $'111\n222\n333\n'
    111
    222
    333

위 예제에서 볼 수 있듯이 $"" 안에 들어간 문자열은 C의 문자열에서와 같이 
\t,\n,\r등이 해석된다. 
따라서 다음과 같이 사용할 수 있다. 
코드:

    # find . -type f -exec vi -c $'20,30d\nwq\n' \{} \;

파일에 대해서 20~30행을 제거하는 명령이다. 


예약된 종료코드 


    정상종료. 


    광범위한 일반적 에러 
    let "var1 = 1/0" 
    "divide by zero"같은 잡다한 에러 


    bash 문서에 명시되어 있는 쉘 내장명령어의 오사용 
    거의 보기 힘들고 보통은 디폴트로 1번 종료 코드로 나타남 

    126 
    실행 불가능한 명령어의 구동 
    퍼미션 문제거나 실행 허가가 없는 명령어 

    127 
    "command not found" 
    $PATH 문제거나 오타일 가능성 있음 

    128 
    exit에 잘못된 인자 넘김 
    exit 3.14159 
    exit는 0에서 255사이의 정수만 받음 

    128+n 
    치명적 에러 시그널 "n" 
    kill -9 스크립트의 $PPID 
    $?는 137 (128 + 9)을 리턴 

    130 
    스크립트가 Control-C에 의해 종료됨 
    Control-C 는 치명적 에러 시그널 2번(130 = 128 + 2, 바로 위 참고) 

    255 
    종료 상태 범위 초과 
    exit -1 
    exit는 0에서 255사이의 정수만 받음 


저자가 제안하는 방법은 사용자 정의 종료 코드를 64 - 113(성공시 0도 
포함)으로 제한해서 C/C++ 표준을 따르는 것입니다. 이렇게 해도 사용자는 
여전히 50개의 코드를 쓸 수 있는 있기 때문에 나중에 스크립트의 문제를 좀 더 
깔끔하게 해결할 수 있습니다. 


지역화(Localization) 
지역화된 쉘스크립트는 시스템의 로케일에 따라 정의된 언어로 텍스트를 
출력하게 해준다. 

코드:

    #!/bin/bash
    # localized.sh
    E_CDERROR=65
    error()
    {
      printf "$@" >&2
      exit $E_CDERROR
    }
    cd $var || error $"Can't cd to %s." "$var"  #문자열들을 $""로 묶어준다.
    read -p $"Enter the value: " var


    bash$ bash -D localized.sh
    "Can't cd to %s."
     "Enter the value: "
    # -D옵션은 스크립트를 수행하지 않고 $뒤에서 큰따옴표로 묶인 문자열을
    # 보여준다.


    bash$ bash --dump-po-strings localized.sh
    #: a:6
    msgid "Can't cd to %s."
    msgstr ""
    #: a:7
    msgid "Enter the value: "
    msgstr ""
    # --dump-po-strings 옵션은 -D와 닮았지만 gettext의 "po" 포맷을 사용한다.


    # ko.po 파일 내용.
    #: a:6
    msgid "Can't cd to %s."
    msgstr "%s 디렉토리로 옮겨갈 수 없습니다."
    #: a:7
    msgid "Enter the value: "
    msgstr "값을 넣으세요: "
 

    # msgfmt실행.
    bash$msgfmt -o localized.sh.mo ko.po


    # localized.sh.mo 파일을 /usr/local/share/locale/ko/LC_MESSAGES 디렉토리에
    # copy.


    # 이제 스크립트에 첫부분에 다음의 두줄을 추가.
    # TEXTDOMAIN과 TEXTDOMAINDIR 변수는 전체 환경으로 export되어야 한다.
    TEXTDOMAINDIR=/usr/local/share/locale
    TEXTDOMAIN=localized.sh



error string 
: bad interpriter 
이 에러는 쉘스크립트파일이 UNIX형식이 아닌 DOS 형식일때 이러한 에러가 
발생한다. 주의할 것. 


생각해 볼 문제 
코드:

    test -d package || ( echo 'Wrong working directory.'; exit 1 )
    [ -d package ] || ( echo 'Wrong working directory.'; exit 1 )

위 문장이 어떻게 동작할 것인가. 단순하게 생각할때는 package라는 디렉토리가 
존재한다면 문장이 출력되지 않을 것이다. 그리고 package라는 디렉토리가 존재하지 
않는다면 문장을 출력하고 스크립트를 종료하게 될 것이다. 하지만 문장을 출력하고 
종료되지 않는다. '('와 ')'로 묶인곳이 실행되면서 현재 shell이 새롭게 하나 
생성되어서 실행된다. 따라서 exit를 수행할때는 새롭게 생성된 shell이 종료되고 
현재 shell은 종료되지 않는다. 따라서 exit로 종료되지 않고 계속 수행되게 된다. 

따라서 다음과 같이 수정한다. 
코드:

    # if문 대체하기.
    if [ -d package ];then
        echo 'Wrong working directory.'
        exit 1
    fi

    # 문장 블럭 사용하기.
    # 주의할 점은 'exit 1' 다음에 ';'가 들어가 주어야 한다.
    [ -d package ] || { echo 'Wrong working directory.'; exit 1; }

    # 그냥 '('')'를 없애기
    # '||'와 ';'중에 '||'가 우선순위가 더 높아서 의도한 대로 수행된다.
    # 하지만 블럭의 구분이 모호해진다. 따라서 문장 블럭을 사용하는것이 좋을 것
    # 같다.
    [ -d package ] || echo 'Wrong working directory.'; exit 1


임시파일의 생성 

    $$ : 임의의 난수를 발생한다. 
    이 숫자값은 현재 shell에서는 계속동일한 값을 가진다. 

코드:

    #!/bin/sh

    echo "temp file" > temp_$$
    rm -f temp_$$

'리눅스 > 쉘스크립트' 카테고리의 다른 글

쉘 내장 명령어  (2) 2012.02.14
쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트 조건문  (7) 2012.02.08
#!/bin/sh  (3) 2012.02.08
Posted by GUCCI
, |

#!/bin/sh

리눅스/쉘스크립트 / 2012. 2. 8. 18:47

sh는 쉘 프로그램 해석기이다. 쉘 스크립트를 보면 첫 줄에 아래와 같은 구문을 볼 수 있다.

 

#!/bin/sh

#!/usr/bin/perl

 

해당 스트립트를 #! 뒤에 나오는 절대경로에 위치하는 쉘 프로그램의 구문 문법을 통해 해석하고 실행하나는 뜻이다. 이런 전처리 작업을 해주는 이유는 보통 스크립트는 종류도 많고 그에 따른 문법도 제각각이기 때문이다. 

 

sh는 bone shell이라고도 하며 가장 기본적인 쉘이다.

쉘이란 커널과 사용자를 연결해주는 하나의 매개체 역할을 한다고 보면 된다.

쉘은 여러가지 형태로 만들어지지만 크게 csh 계열과 ksh 계열로 나뉜다.

csh는 c 언어를 기초로 관리자 중심으로 만들어진 쉘이고

ksh는 korn shell이라고 불리며 사용자 중심으로 만들어진 쉘이다.

csh는 후에 tcsh으로 확장된다.

리눅스는 bash라는 쉘을 사용하며 이 의미는 born again shell의 의미를 가지고 있다.

bash는 csh의 관리적인 측면과 ksh의 사용자 편의성 측면을 모두 고려하여 만들어진 쉘이다.

리눅스는 대부분의 쉘을 호환하여 사용할 수 있다.

[출처] #!/bin/sh|작성자 시대유감

'리눅스 > 쉘스크립트' 카테고리의 다른 글

쉘 내장 명령어  (2) 2012.02.14
쉘 프로그래밍 강좌  (2) 2012.02.09
쉘스크립트 조건문  (7) 2012.02.08
쉘스크립트  (1) 2012.02.08
Posted by GUCCI
, |

최근에 달린 댓글

글 보관함