43
System Programming Lab Week 4: Shell

System Programming Lab - Egloospds5.egloos.com/pds/200704/11/49/system_programming_lab... · 2007-04-11 · Background Processing •background / foreground •명령끝에& 문자를넣어실행

  • Upload
    others

  • View
    3

  • Download
    0

Embed Size (px)

Citation preview

System Programming LabWeek 4: Shell

Schedule for your own shell

• 1st

– shell 기본기능

– fork / exec

– Background Processing/ Sequential Execution

– ls, find, grep

• 2nd

– Environment variables/ Shell variables

– built-in command

• cd, exit, set, unset, alias, unalias, umask

Schedule for your own shell

• 3rd

– Signal

– Trap

– history

• 4th

– pipe / redirection

Shell

• 쉘의 시작

– Text mode : 시스템에 로그인하면 쉘 상태로 진입

– GUI mode : xterm이나 hanterm등의 터미널 실행으로 쉘 진입

• 쉘의 역할

– 명령을 해석하고 실행

• 쉘의 종류

– bash, csh, ksh, sh, tcsh, zsh…

• 리눅스 배포본 = Kernel + Shell + Application

fork()

• 새로운 프로세스 생성

– 생성된 프로세스 : 자식 프로세스(child process)

– fork()를 호출한 프로세스 : 부모 프로세스(parent process)

• fork()가 이루어지는 시점에서 두 프로세스가 동시에작업 수행

• 함수 정의

fork() Example I#include <stdio.h> #include <string.h> #include <sys/types.h>

#define MAX_COUNT 200 #define BUF_SIZE 100

int main(void){ pid_t pid; int i; char buf[BUF_SIZE]; fork(); pid = getpid(); for (i = 1; i <= MAX_COUNT; i++) {

sprintf(buf, "This line is from pid %d, value = %d\n", pid, i); write(1, buf, strlen(buf));

}return;}

fork() Example I

fork() Example II#include <stdio.h>#include <sys/types.h>

#define MAX_COUNT 200void ChildProcess(void); /* child process prototype */void ParentProcess(void); /* parent process prototype */

int main(void){

pid_t pid;

pid = fork();if (pid == 0)

ChildProcess();else

ParentProcess();return;

}

fork() Example II

void ChildProcess(void){

int i;

for (i = 1; i <= MAX_COUNT; i++){printf("This line is from child, value = %d\n", i);sleep(1);

printf(" *** Child process is done ***\n");}

void ParentProcess(void){int i;

for (i = 1; i <= MAX_COUNT; i++){printf("This line is from parent, value = %d\n", i);sleep(1);

}printf("*** Parent is done ***\n");

}

check the process tree using „pstree‟ commandrunning this example

fork() Example II

fork() Example II

fork() Example II

exec() family

• 실행 파일을 수행

• exec 계열의 함수가 사용된 뒤의 코드는 메모리에서 삭제

– exec 함수에 인자로 들어간 실행파일의 코드가 메모리에 올라감

• fork()를 항상 수반

– exec수행 후 다른 코드는 의미가 없어짐

– fork()를 이용해 child process가 exec를 수행

– exec 뒤의 코드는 parent process가 수행

exec() family

• exec family

– execl : 실행 파일 수행

– execle : 실행파일에 환경변수를 인자로 넘겨줌

– execlp : 현재 디렉토리의 실행 파일 수행

– execv : 인자를 배열에 저장해서 실행 파일 수행

– execve : 환경변수를 인자로 넘겨줌. 인자는 배열에 저장

– execvp : 현재 디렉토리의 실행파일수행, 인자는배열에 저장

• section 8.10 exec functions

– 실제 exec 함수군의 prototype 정의(다른 PPT에나와있음)

exec() family

Int execl(const char *pathname, const char *arg0, …/* (char *)0 */);

• 실행파일 수행

Int execle(const char *pathname, const char *arg0, …/* (char *)0, char *const envp[] */);

• 실행파일에 환경변수를 인자로 넘겨줌

Int execlp(const char *pathname, const char *arg0, , …/* (char *)0 */);

• 현재 디렉토리의 실행 파일 수행

Int execv(const char *pathname, *const argv[]);

• 인자를 배열에 저장해서 실행 파일 수행

execve(const char *pathname, *const argv[], …/* (char *)0, char *const envp[] */);

• 환경변수를 인자로 넘겨줌. 인자는 배열에 저장

execvp(const char *pathname, *const argc[]);

• 현재 디렉토리의 실행파일수행, 인자는 배열에 저장

exec() Example I

#include <unistd.h>

Int main(void){

puts(“exec before\n”);

execl(“/bin/ls”, “ls”, “-l”, NULL);

puts(“exec after..blahblah”);

return;

}

exec() Example II

#include <unistd.h>

Int main(void){

if(fork()==0){

execl(“/bin/ls”, “ls”, “-l”, NULL);

}

else{

wait(NULL);

puts(“Child Finished\n”);

}

}

Basic functions of Shell

• 명령어를 받아서 이를 자식 프로세스에서 생성

– 예) 두번째주 강의자료 fork & exec example

Background Processing

• background / foreground

• 명령끝에 & 문자를 넣어 실행

– e.g) gcc shell.c &

– 작업번호와 프로세스 ID를 출력하고 background로 돌아가고, 쉘 프롬프트 출력.

– 작업번호는 background 명령에 순서대로 부여.

– 사용자 입력이 필요한 명령은 background로 보낼 수 없음

– jobs 명령을 이용하여 background process를 확인할 수있음.

– fg/bg명령을 사용하여 background/foreground 상태에서실행가능.

– kill 명령으로 background 작업 멈춤

- 20 -

setpgid()

#include <unistd.h>

int setpgid(pid_t pid, pid_t pgid);– 프로세스는 setpgid 함수를 이용하여 프로세스의 그룹을 바꿀 수 있

음.

– pid 번호를 가진 프로세스의 그룹 ID를 pgid 그룹으로 변경

– pid가 0이면 호출하는 프로세스 ID를 사용

– pgid가 0이면 pid에 해당하는 프로세스가 그룹 리더

– 리턴 값 : 0 – success

1 – fail

• New• A process that has just been created but has not

yet been admitted to the pool of executable processes by the operating system. Typically, a new process has not yet been loaded into main memory, although its process control block has been created

Five-State Process Model

RunningReady ExitNew

Blocked

Admit

TimeOut

Dispatch

Release

EventOccurs Event

Wait

• Ready• A process that is prepared to execute when given

the opportunity

Five-State Process Model

RunningReady ExitNew

Blocked

Admit

TimeOut

Dispatch

Release

EventOccurs Event

Wait

• Running• The Process that is currently being executed. For

this chapter, we will assume a computer with a single processor, so at most one process at a time can be in this state

Five-State Process Model

RunningReady ExitNew

Blocked

Admit

TimeOut

Dispatch

Release

EventOccurs Event

Wait

• Blocked• A process that is cannot execute until some event

occurs, such as the completion of an I/O operation

Five-State Process Model

RunningReady ExitNew

Blocked

Admit

TimeOut

Dispatch

Release

EventOccurs Event

Wait

• Exit• A process that has been released from the pool

of executable processes by the O/S, eithe because it halted or because it aborted for some reason

Five-State Process Model

RunningReady ExitNew

Blocked

Admit

TimeOut

Dispatch

Release

EventOccurs Event

Wait

• First-Come-First-Served• Non-preemptive

Scheduling

Ai Bi Ci Di Ei

A

B

C

D

E

• Round Robin• Preemptive

Scheduling

Ai Bi Ci Di Ei

A3

B6

C2

D1

E5

A

B

C

D

E

• Interrupt• A mechanism that peripheral devices inform an asynchronous

event to Linux

• Due to some sort of event that is external to and independent of the currently running process

• Ex) Completion of I/O operation

Interrupt

• Exception• Inform an synchronous software event to Linux

• Divided by zero

• Invalid machine code

• Overflow

• Page fault

• Segmentation fault

• Protection fault

Exception

• Trap• Relates to an error or exception condition generated within the

currently running process

• Ex) illegal file access attempt

• IDT ( Interrupt Description Table )

Trap

• divide_error()• debug()• nmi()• ….• segment_not_present()• ….• page_fault ()• ….

Common trap

handler for 80*86

• Timer_interrupt• Hd_interrupt• ….

Device interrupt

handler

• System_call()System_call vector

0x0

0x20

0x80

Signal handling

• 시그널(signal)의 개념

– 시그널

• 소프트웨어 인터럽트(interrupt)

• 프로세스들 사이에서 비동기적 사건의 발생을 젂달

– 시그널 이름

• 서로 다른 사건을 구별하기 위하여 여려 종류의 시그널을 제공

• 모든 시그널은 „SIG‟로 시작하는 이름을 갖는다

– 시그널에 대한 작업

• 시그널의 발생, 젂달, 처리

signal handling

• 시그널의 종류

– <sys/signal.h>에 정의

– e.g)

– #define SIGHUP 1

– #define SIGINT 2

– …

signal handling

• 시그널의 발생(generation)

– 터미널에서 특수키를 누르는 경우

– 하드웨어의 오류

• 0으로 나눆 경우, 잘못된 메모리를 참조하는 경우 등

– kill함수의 호출

• 특정 프로세스나 프로세스 그룹에서 원하는 시그널을발생/젂달한다

• 대상프로세스에 대한 권한이 있어야 한다.

– kill명령의 실행

• 내부적으로 kill함수를 호출한다

– 소프트웨어적 조건

• 네트워크에서의 데이터 오류(SIGURG), 파이프 작업에서의 오류(SIGPIPE), 알람의 종료(SIGALRM)등

signal handling

• 시그널의 젂달(delivery)

– 발생된 시그널이 수싞되어 정해진 방법대로 처리되는 것

– 지연(pending) : 발생된 시그널이 젂달되지 못한상태

• 시그널의 블록(block)

– 블록이 해제되거나 무시하도록 변경될 때까지 지연된 상태로 남는다.

– 시그널 마스크(signal mask) : 블록될 시그널 집합

signal handling

– 시그널의 처리(disposition, action)

• 시그널을 무시한다(ignore)– SIGKILL과 SIGSTOP 시그널을 제외한 모든 시그널을 무시할 수

있다.

– 하드웨어 오류에 의해 발생한 시그널에 대해서는 주의해야 한다.

• 시그널을 처리한다(catch)– 시그널이 발생하면 미리 등록된 함수(handler)가 수행된다

– SIGKILL과 SIGSTOP 시그널에는 처리할 함수를 등록할 수 없다.

• 기본처리 방법에 따른다. (default)– 특별한 처리방법을 선택하지 않은 경우

– 대부분 시그널의 기본 처리방법은 프로세스를 종료시키는 것이다.

signal handling

• 시그널 처리 방법의 선택

– typedef void(*sighandler_t)(int signo);

– sighandler_t signal(int signum, sighandler_thandler);

– 지정한 시그널에 대한 세 가지 처리 방법 중 하나를 선택한다.

– signo 인자 : 시그널 번호

signal handling

– handler 인자

• SIG_IGN : 지정한 시그널을 무시한다.

• SIG_DFL : 기본 처리 방법에 따라 처리한다.

• 사용자 정의 함수(signal handler) : 시그널이 발생하면호출될 함수의 주소

– 리턴값 : 지정한 시그널에 대한 이젂까지의 처리방법

Signal handling

• When you press….

– Ctrl + z

• SIGSTOP is sent to the process.

• 프로세스는 blocked 상태에 머물게 됨.

– Ctrl + c

• SIGINT is sent to the process.

• 프로세스는 Terminate

Signal handling Example#include “errhdr.h”

static void sig_usr(int);

int main(void){

if(signal(SIGUSR1,sig_usr)==SIG_ERR)err_sys(“can‟t catch SIGUSR1”);

if(signal(SIGUSR2,sig_usr)==SIG_ERR)err_sys(“can‟t catch SIGUSR2”);

for(;;)pause();

}static void sig_usr(int signo){

if(signo==SIGUSR1)printf(“received SIGUSR1\n”);

else if(signo==SIGUSR2)printf(“received SIGUSR2\n”);

elseerr_dump(“received signal %d\n”,signo);

}

순차실행

• 입력된 명령어를 순차적으로 실행

• 입력 서식

– command1; command2; command3 …

– e.g)mkdir test ; pwd ; ls -l

Assignment #3

• Requirements

– shell 실행으로 쉘 시작

• 커맨드 프롬프트는 “사용자이름@현재위치 $”

• ex)root@splab $

• 제작한 ls, find, grep 수행 가능

• Shell에서 exec으로 수행하도록

• 하나의 프로젝트로 묶어서 사용하도록

– background 수행 가능

– 순차실행가능

– Ctrl+C(SIGINT) 시그널 처리

• 프로그램 종료되지 않음

• 커맨드실행주에는 SIGINT 가능하게 처리

Makefile Tips

• 프로젝트 디렉토리 구조

• Makefile에서 다른 디렉토리의 Makefile호출

– kwsh/makefile의 경우 “make –C kwls”를 사용하면 해당 디렉토리의 makefile을 호출

Makefile Tips

• Makefile