Linux_Shell

[쉘프로그래밍] 리눅스 부팅과정, 기본적인 명령어

heybrro 2017. 8. 10. 14:29

P.182 

- 2장. 리눅스 부팅과정

POST -> Boot Loader (GRUB) -> Linux Kernel Loading -> init 프로세스 생성

(1) POST (Power-On Self Test) : 전원 공급하면 가장 처음에 자가 진단프로그램 포스트가 돈다(ex. IBM컴퓨터의 경우 bios 라고 함)

(2) 부딩디스크의 가장 첫번째 섹션에 boot loader가 있다. 부트로더는 운영체제의 커널을 불러온다. 리눅스에서 사용하는 부트로더는 GRUB (GNU프로젝트의 부트로더) 이다.

(3) 해당하는 커널을 찾아 메모리에 올린다.

(4) 커널은 제일 먼저 init이라는 프로세스를 생성하여 실행한다.


그러면 init프로세스가 어떤 동작을 실행해야하는지 정의하는 곳은 어디있을까?

/etc/inittab 이다. inittab안에는 런 레벨(Run level)에 따라 실행될 쉘스크립트 파일을 지정해놓고 있다.

다음과 같은 파일들로 지정된다. 아래 rc0~6.d 파일명에서 숫자는 런 레벨을 의미한다.

/etc/rc.d/rc.sysinit

/etc/rc.d/rc0.d

/etc/rc.d/rc1.d

/etc/rc.d/rc2.d

/etc/rc.d/rc3.d

/etc/rc.d/rc4.d

/etc/rc.d/rc5.d

/etc/rc.d/rc6.d


Run Level

0 : system halt (시스템을 종료할때 사용되는 런레벨)

1 : single-user (maintenance) 싱글 유저 모드. 런레벨 1로 시작하면 디폴트로 root 로 로그인한다. 다른사용자 로그인 시도 못하고 오직 관리자만 진입하여 작업하는 용도로 사용된다.

2 : multi-user

3 : multi-user, NFS(Network File System : 로컬 머신이 아닌 다른 머신의 하드를 자신의 머신에 있는 것처럼 네트워크를 이용하여 만드는 가상파일시스템) 를 지원한다. 

  => 서버용으로 구동하려면 2번 또는 3번으로 구동해야한다. 

5 : 리눅스에서 Desktop 형태(그래픽환경, 현재 실습하고있는 부팅레벨)

6 : 리눅스에서 reboot

 => 5,6 번은 리눅스와 유닉스가 다른 용도로 사용할수있음, 0~3까지는 리눅스든 유닉스든 공통적인 용도로 사용됨


현재 몇 레벨을 사용하는지 알아보는 방법은?

[user@localhost rc.d]$ who -r

         run-level 5  2017-06-20 09:54

결과에 5라고 나온다. 즉 5번(데스크탑 모드) 런레벨로 부팅되었다는 뜻


/etc/rc.d/rc#.d 의 하위폴더 들어가보면 하위 파일들이 나온다. K로 시작하는 것과 S로 시작하는 쉘 파일들이 있다.

K~~~ 인 것 : 종료시키는 스크립트

S~~~ 인 것 : 시작시키는 스크립트


[user@localhost rc5.d]$ pwd

/etc/rc.d/rc5.d

[user@localhost rc5.d]$ ls -al *crond

lrwxrwxrwx. 1 root root 15 2016-05-20 06:41 S90crond -> ../init.d/crond

S로 시작하는 것으로보아 시작과 관련된 쉘프로그램이고 심볼릭링크로 연결되어 있음을 알 수 있다.


p185.

p194. 명령어 라인 분석 순서

p195. 

p198. pstree , 부모자식관계

p199. system call - 커널안에 


-내부에서 시스템콜 호출하면 - fork가 수행된다. 이때 어떻게 동작할까?


프로세스의 내부구조는  Segment(실행하는 코드 정보가 있음), F.D.T(Fire Despriptor Table) 크게 두개 이외에도 Signal Handler, Process정보가 저장되는 영역 (PID,state 정보 등) 등으로 구성된다. 

프로세스가 외부자원을 사용할때는 <File Descriptor Table> 을 사용한다.

File Descriptor Table에 외부자원과 참조번호를 연결해두고 사용한다.

* 외부자원 : 터미널(키보드입력, 모니터출력 등), 하드디스크, 네트웍, 소켓 등


fork를 사용하면 나와 똑같은 프로세스가 하나 더 복제된다. (복제시 세그먼트, FDT, signal 핸들러 등의 정보는 나와 똑같은 정보가 복사된다.)

그러나 pid, ppid, state 같이 프로세스 정보가 저장되는 영역은 복제되지 않는다. 자식 쉘도 자기만의 정보가 저장되어 있다.

이때 나는 parent 프로세스 , 새로생긴애는 child 프로세스라고 한다. 새로생긴애의 ppid 정보에 내 프로세스 pid 값이 저장된다.

생성된 child 프로세스는 부모와 똑같은 세그먼트를 갖게 되나, 세그먼트 내에서 fork 이후의 로직부터 수행한다. (segment의 처음부분 부터 수행하는게 아니다)


exec와 물음표변수 $? 는 밀접하게 관련있다. 

exec 결과를 $? 로 확인해야하기 때문이다.


p208 변수

변수 값할당시 =사이에 공백있으면 안됨 즉, 

$name=kim (o)

$name = kim (x)


명령어 줄에서 변수 지정한 후, 쉘 스크립트 파일 (~.sh) 안에서 사용하려고 하면 안된다. 왜 일까요?

명령프롬프트에서 변수 지정하는 것은 부모 쉘인 내가 지정한 것이고, 쉘 스크립트를 실행하면 자식 쉘이 생성되어 실행하는 것이기 때문 

(부모 쉘에서 지정한 변수가 자식 쉘에게 자동으로 변수 전달 안됨)

부모쉘과 자식쉘의 환경(변수 포함)이 다르기 때문


만약, 자식쉘에도 이 정보를 전달하고 싶은 경우 export 명령어를 쓰면 된다. export란 전역화 시킨다는 의미이다.

$export name

위 명령어를 쓰고나면 env 명령어로 검색하면 다음과 같이 name 변수를 전역변수에서 찾을 수 있다.

$env 했을때

...(중략)

name=kim

..(중략)

변수를 해제하고 싶을땐? unset 명령어를 쓰면 변수의 메모리할당을 제거함

$unset name


$echo $MAIL

메일이라는 환경변수


- 프롬프트 관련 환경변수

$PS1

 프롬프트

 $PS2

 secondary 프롬프트

(명령어를 미처 완성하지 못했을때 완성할때까지 뜨는 프롬프트)

 $PS3 

 select 라는 명령어를 쓸때 나오는 프롬프트이다

(select는 나중에 살펴보겠다)

[test@localhost ~]$ echo $PS1

[\u@\h \W]\$

[test@localhost ~]$ echo $PS2

>

[test@localhost ~]$ echo $PS3



p224. 예약변수

[user@localhost ch02]$ env | grep HIST

HISTSIZE=1000                        (최근 수행 명령어 저장 개수, 기본값은 1000이다.)

HISTCONTROL=ignoredups     (중복되어지는 명령에 대한 기록 유무 지정)


명령어 기록기능

~/.bash_history 파일에 저장됨


터미널 로그아웃시 .bash_history 에 명령어 히스토리를 저장함

[user@localhost ch02]$ cat ~/.bash_history

cd

ls

cd ~

ls

alias c=clear

c

(중략)



p226. 특수파라메터 변수들  (중요하다)

$* : 인수 총 목록

$@ : 인수 총 목록

$# : 인수의 개수

$0 : 0번째 인수, 쉘스크립트 파일명 

$1 : 1번째 인수, 

$2 : 2번째 인수

$N : N번째 인수


[user@localhost ch02]$ ./crond start load 

위와 같은 명령어를 사용했을때

$0 : ./crond

$1 : start

$2 : load

$# : 2

$* : start load

$@ : start load


예)


쉘스크립트------------------------------------

[user@localhost ch02]$ cat tmp.sh 

#!/bin/bash

# positional parameter var


echo "\$0 : $0"     <---역슬래시(\)를 넣으면 특수문자를 일반 문자로 처리한다

echo "\$1 : $1"

echo "\$2 : $2"

echo

echo "\$# : $#"

echo "\$* : $*"

echo "\$@ : $@"


결과1------------------------------------

[user@localhost ch02]$ ./tmp.sh ha hoo yoon

$0 : ./tmp.sh

$1 : ha

$2 : hoo


$# : 3

$* : ha hoo yoon

$@ : ha hoo yoon


결과2------------------------------------

[user@localhost ch02]$ ./tmp.sh RED BLUE GREEN BLACK

$0 : ./tmp.sh

$1 : RED

$2 : BLUE


$# : 4

$* : RED BLUE GREEN BLACK

$@ : RED BLUE GREEN BLACK


결과3------------------------------------

[user@localhost ch02]$ ./tmp.sh

$0 : ./tmp.sh

$1 : 

$2 : 


$# : 0

$* : 

$@ : 




$?  변수는 별다섯개임

정상종료시 0, 비정상종료시 0이 아닌 값을 의미한다


- 실행중인 pid 값을 확인하는 법은 $$ 사용.

이 변수는 주로 쉘 프로그램 안에서 임시파일을 만들고, 그 파일의 삭제작업까지 원할때 많이 사용

echo $$


- 가장최근에 실행한 pid

$!


- read 커맨드. 사용자의 입력을 원할때 사용

$read 저장될변수명

쉘스크립트------------------------

[user@localhost ch02]$ cat read.sh 

#!/bin/bash

echo "what is your name?"

read myname

echo "My name is $myname"


결과화면 ------------------------

[user@localhost ch02]$ ./read.sh 

what is your name?

hyojin

My name is hyojin



p234 산술계산

- expr 명령어

각 인자 사이 정확히 공백을 띄워야 한다.

-let 명령어

 변수에 산술식을 지정할 수 있다. let이 expr보다는 좀 더 사용하기 쉽다.


[user@localhost ch02]$ expr 10 + 20

30

[user@localhost ch02]$ let num=10+20    <--let을 쓸때는 변수에 지정하므로 = 사이에 공백 없는 것을 확인할 수 있다.

[user@localhost ch02]$ echo $num

30

[user@localhost ch02]$ let num=num+1

[user@localhost ch02]$ echo $num

31

[user@localhost ch02]$ num1=`expr 10 + 20`

[user@localhost ch02]$ echo $num1

30

[user@localhost ch02]$ num1=`expr $num1 + 1`

[user@localhost ch02]$ echo $num1

31




p234 연산자

문자열의 동등관계 확인은?

test 명령어, 혹은 대괄호로  논리연산 할 수 있다. 

연산자 

 의미

 =

 같은가 

 !=

 다른가

 

 


test 명령어 사용 방법

[user@localhost ch02]$ test "kim" = "lee"  <--- 반드시 연산자 "=" 양쪽 사이로 공백을 띄워야 한다. 

[user@localhost ch02]$ echo $?

1   (거짓이라는 의미)


[user@localhost ch02]$ test "kim" != "lee"

[user@localhost ch02]$ echo $?

0   (참이라는 의미)



test 명령어 대신 대괄호를 써도 된다. 한칸 띄고 [ 내용 ]

[user@localhost ch02]$ [ "kim" = "lee" ]      <--- 반드시 연산자 "=" 양쪽 사이로 공백을 띄워야 한다. 

[user@localhost ch02]$ echo $?

1

[user@localhost ch02]$ [ "kim" != "lee" ]

[user@localhost ch02]$ echo $?

0


문자열로 저장된 변수를 숫자 대수비교하고 싶을때는 아래 비교 명령어를 쓴다. 그러나 문자를 비교는 불가하므로 문자비교시에는 "=", "!=" 이거만 써야한다

-gt ( greater than, 앞에꺼가 뒤에꺼보다 클때)

-ge ( 앞에꺼가 뒤에꺼보다 크거나, 같을때)

-lt ( less than,  앞에꺼가 뒤에꺼보다 작을때 )

-le (앞에꺼가 뒤에꺼보다 작거나, 같을때)

-eq (같을때)

-ne (같지 않을때)

[user@localhost ch02]$ num1=10

[user@localhost ch02]$ num2=20

[user@localhost ch02]$ [ $num1 -eq $num2 ]

[user@localhost ch02]$ echo $?

1 (두 값이 다르다)

[user@localhost ch02]$ [ $num1 -gt $num2 ]

[user@localhost ch02]$ echo $?

1 (거짓이다)

[user@localhost ch02]$ [ $num1 -lt $num2 ]

[user@localhost ch02]$ echo $?

0 (참이다)


not연산 (! 느낌표 주고 반드시 공백띄워야함)

[user@localhost ch02]$ [ ! $num1 -lt $num2 ]

[user@localhost ch02]$ echo $?

1



p239 test명령어 또는 대괄호를 이용하면 파일에 대한것도 체크할수있다

-z 옵션 : 변수에 값이 없으면 참,

-f 옵션 : 일반 파일인지 체크

-d 옵션 : 디렉토리인지 체크

-r 옵션 : 읽기권한있나

-w 옵션 : 쓰기권한있나

-x 옵션 : 실행권한있나


위 옵션 사용시 유의해야 할 사항! 옵션 다음에 나오는 변수는 무조껀 이중따옴표로 묶어야 한다. 왜?

시스템이 명령어를 실행하는 순서에서 치환기법을 사용하는데, 명령어에서 $변수를 값으로 치환하는 작업이 먼저 일어나므로 $변수에 값이 없다면 

[ -f  $변수 ] 라고 작성했을지라도 치환 작업에 의해 [ -f         ] 로 변해버려서 에러가 나기때문이다. 그러므로 꼭 

[ -f  "$변수" ] 로 사용해라.

-  반드시 대괄호 직후&직전 한칸띄기, 안에 변수넣을때 쌍따옴표로 묶기


[user@localhost ch02]$ [ -f /etc/hosts ]      <-- 일반 파일인가?

[user@localhost ch02]$ echo $?

0   (일반파일입니다)

[user@localhost ch02]$ [ -d /etc/hosts ]   <-- 디렉토리인가?

[user@localhost ch02]$ echo $?

1    (디렉토리아닙니다)

[user@localhost ch02]$ [ -r /etc/hosts ]   <-- read 권한이 있는가?

[user@localhost ch02]$ echo $?

0

[user@localhost ch02]$ [ -w /etc/hosts ]   <-- write 권한이 있는가?

[user@localhost ch02]$ echo $?

1

[user@localhost ch02]$ [ -x /etc/hosts ]   <-- 실행 권한이 있는가?

[user@localhost ch02]$ echo $?

1


 Q. 그런데 파일퍼미션이 rwxrwxrwx 총 3개의 권한을 표시하는데, 그중 어떤 권한을 보고 위를 판단하는건지 모르겠다 ? 


스크립트--------------------------------------------

[user@localhost ch02]$ cat test.sh 

#!/bin/bash

# . ./filecheck.sh file_name

[ -z "$1" ] && exit 1   <---- 부모에게 1이라고 신호전달

[ -f "$1" ] && echo "this is regular file" <-- 반드시 대괄호 직후,직전 한칸띄기, 안에 변수넣을때 쌍따옴표로 묶기

[ -d "$1" ] && echo "this is directory"


[ -x "$1" ] && echo "possible to execute"

[ -w "$1" ] && echo "writable"

[ -r "$1" ] && echo "readable"


실행결과 ---------------------------------------------------

[user@localhost ch02]$ ./test.sh /etc/hosts

this is regular file

readable


실행결과 ---------------------------------------------------

[user@localhost ch02]$ ./test.sh 

[user@localhost ch02]$ echo $?

1            <---자식이 exit 1로 전달한 값 확인 "아 비정상종료했구나"


실행결과 ---------------------------------------------------

[user@localhost ch02]$ ls -al ~/ls.out 

-rw-rw-r--. 1 user user 33 2017-06-20 15:40 /home/user/ls.out


[user@localhost ch02]$ ./test.sh ~/ls.out 

this is regular file

writable

readable



p235. if 조건문

if 조건

then 수행

else

fi

조건을 한줄에 쓸려면 세미콜론 이용

if 조건 ; 수행

if

then

elif

then

else

fi

스크립트 ----------------------------------------------

[user@localhost ch02]$ cat ifcheck.sh 

#!/bin/bash

# . ./ifcheck.sh file_name


if [ -z "$1" ]

then

exit 1 

fi


if [ -f "$1" ]

then

echo "this is regular file"

elif [ -d "$1" ]

then

echo "this is directory"

else

echo "unrecognized file"

fi


if [ -x "$1" ]

then

echo "possible to execute"

elif [ -w "$1" ]

then

echo "writable"

elif [ -r "$1" ]

then 

echo "readable"

fi



실행결과  ----------------------------------------------

[user@localhost ch02]$ ./ifcheck.sh /etc/hosts

this is regular file

readable 


실행결과  ----------------------------------------------

[user@localhost ch02]$ ./ifcheck.sh /var/log

this is directory

possible to execute


실행결과  ----------------------------------------------

[user@localhost ch02]$ ./ifcheck.sh /var/log

this is directory

possible to execute


실행결과  ----------------------------------------------

[user@localhost ch02]$ ./ifcheck.sh /var/log/messages 

this is regular file


실행결과  ----------------------------------------------

[user@localhost ch02]$ ls -l /var/log/messages 

-rw-------. 1 root root 360866 2017-06-21 11:41 /var/log/messages


centOS에 한글패키지( ibus-hangul) 설치하는 방법  (관리자 모드로 입장)

[root@localhost ~]# yum install ibus-hangul


언제 공백을 넣는지 반드시 체크해야함

명령과 옵션사이 반드시 공백

대괄호[ 앞뒤 공백 ] 이것도 앞뒤공백


* 이 사용자가 등록된 사용자인지 아닌지 확인은 어디서 할까?? -------------------- /etc/passwd 에서 유저를 찾으면 된다.

[user@localhost ch02]$ cat useradd.sh 

#!/bin/bash

# 사용자 계정이 존재하지 않는 경우 생성


echo "User name?"

read username


grep $username /etc/passwd >/dev/null 2>&1

if [ $? -eq 0 ]

then

echo "${username}은 이미 존재합니다"

else

useradd $username

passwd $username

fi



- case 

case 표현식 in

문자열1)

;;

문자열2)

;;

*)

;;

문자열3|문자열4)

;;

esac 


예)

[user@localhost ch02]$ cat case.sh 

#!/bin/bash


echo "1. loginuser list"

echo "2. file list"

echo "3. process list"

echo "4. all prosess list"

echo "choice ==> "

read answer


case $answer in

1)

who

;;

2)

ls

;;

3|4)

ps

;;

"start")

who

;;

*)

;;

esac



-반복문

(1) while 명령어

do

수행내용

done 


명령어가 참이면 수행내용수행

 (2) until 명령어

do

수행내용

done


명령어가 거짓이면 수행내용수행

 (3)

for 변수 in 값...

#for 변수 in `명령어`

#for 변수 in $*    (사용자가 입력하는 인수 목록을 넣을수도 있다)

do

수행내용

done


스크립트 ------------------------------------

[user@localhost ch02]$ cat for.sh 

#!/bin/bash

for i in 1 2 3 4 5

do

echo "$i"

done


실행결과 ------------------------------------

[user@localhost ch02]$ ./for.sh 

1

2

3

4

5


--스크립트 --

[user@localhost ch02]$ cat for.sh 

#!/bin/bash

for i in `ls /etc/*.conf`

do

echo "$i"

done


--실행결과 --

[user@localhost ch02]$ ./for.sh 

/etc/asound.conf

/etc/dnsmasq.conf

/etc/dracut.conf (중략)

--스크립트 --

[user@localhost ch02]$ cat for.sh 

#!/bin/bash

for i in $*

do

echo "$i"

done

--실행결과 --

[user@localhost ch02]$ ./for.sh aa ho joo

aa

ho

joo


--스크립트 --

[user@localhost ch02]$ cat mkdir.sh 

#!/bin/bash

for dirname in 00 01 02 03 04 05 06 07 08 09

do

mkdir unix$dirname

cd unix$dirname

touch file1 file2 file3

cd ..

done


--실행결과 -- 

[user@localhost ch02]$ ls -R unix*

unix00:

file1  file2  file3


unix01:

file1  file2  file3


unix02:

file1  file2  file3


unix03:

file1  file2  file3


unix04:

file1  file2  file3


unix05:

file1  file2  file3


unix06:

file1  file2  file3


unix07:

file1  file2  file3


unix08:

file1  file2  file3


unix09:

file1  file2  file3



p243 함수

함수 : 함수정의 먼저 하고 실행해야한다. 순서가 뒤바뀌면 안된다!!! (중요)

(1)

함수명()

{

내용

}

 (2) 

function 함수명

{

내용

}



--스크립트--

[user@localhost ch02]$ cat myfunc.sh 

#!/bin/bash

#함수정의

myprint()

{

echo "myprint"

}

#함수호출

myprint

pwd

cd /etc

myprint

pwd


--실행결과 --

[user@localhost ch02]$ ./myfunc.sh 

myprint

/home/user/shell/ch02

myprint

/etc


-함수에 인수전달방법

함수정의는 다음과 같이

함수명()

{

$1  <-첫번째 인자

}


함수호출은 다음과 같이

함수명 인자1 인자2


--스크립트 --

[user@localhost ch02]$ cat myfunc.sh 

#!/bin/bash

#함수정의

myprint()

{

echo "myprint $1"

}

#함수호출

myprint var1

pwd

cd /etc

myprint var2

pwd


--실행결과--

[user@localhost ch02]$ ./myfunc.sh 

myprint var1        <-- 인자넣음

/home/user/shell/ch02

myprint var2     <-- 인자 또넣음

/etc




외부파일 functions에 함수정의해놓고 불러다쓰기


---- 함수 정의해놓은 functions 스크립트 --- 

[user@localhost ch02]$ cat functions

#!/bin/bash


#함수정의

myprint()

{

echo "myprint $1"

}


-----외부 파일에서 함수 불러다쓰는 스크립트

[user@localhost ch02]$ cat myfunc.sh 

#!/bin/bash

#함수정의

. functions       <-- 외부에 함수저장해놓은 functions파일을 적용시키는 명령어

#함수호출

myprint var1

pwd

cd /etc

myprint var2

pwd

[user@localhost ch02]$ 


---실행결과----

[user@localhost ch02]$ ./myfunc.sh 

myprint var1

/home/user/shell/ch02

myprint var2

/etc




현재경로 저장

함수에서 종료할땐
return 0 혹은 return 1

쉘을 끌때는 
exit 1



[user@localhost ch02]$ vim functions 
[user@localhost ch02]$ cat test05.sh 
#!/bin/bash
. functions

saved
cd /tmp
pwd
cd /var/log
pwd
loadd

[user@localhost ch02]$ 


위처럼 하면 쉘에서 saved 나 loadd 를 쓸수있는데
쉘나오면 명령어 줄에서는 안먹힘. 이럴땐 
명령어줄에서 직접 . .functions 를 실행함
[user@localhost ch02]$ . functions  <- 이 쉘에 저장
[user@localhost ch02]$ saved
[user@localhost ch02]$ cd /etc
[user@localhost etc]$ 
[user@localhost etc]$ loadd  <-다시 경로로 돌아가고싶을땐
[user@localhost ch02]$ 


모든쉘에서 다 사용하고 싶을때
~/.bashrc 파일에 아예 저장
------------------------
# .bashrc

# Source global definitions
if [ -f /etc/bashrc ]; then
        . /etc/bashrc
fi

# User specific aliases and functions
alias c=clear
alias rm='rm -i'

saved()
{
        currentdir=`pwd`
}

loadd()
{
        if [ -z "$currentdir" ]
        then
                echo "saved is not called"
                return 0
        fi
        cd $currentdir
}
------------------------


p332. 변수 확장 변경자
[user@localhost ~]$ name="kim"
[user@localhost ~]$ echo ${name:-"lee"}
kim
[user@localhost ~]$ 
[user@localhost ~]$ name=
[user@localhost ~]$ echo ${name:-"lee"}
lee
[user@localhost ~]$ echo $name  <-- name에 값이 할당되진않음

[user@localhost ~]$ echo ${name:="lee"}  <--name에 값도 할당해버림
lee
[user@localhost ~]$ echo $name
lee
[user@localhost ~]$ 



p335.문자열을 자르기위한 변수 확장자

[user@localhost ~]$ filename=a.tar.gz
[user@localhost ~]$ echo $filename
a.tar.gz
[user@localhost ~]$ echo ${filename%.*}   <--끝에서부더 잘라냄
a.tar
[user@localhost ~]$ 
[user@localhost ~]$ echo ${filename%%.*}
a
[user@localhost ~]$ echo ${filename#.*}
a.tar.gz
[user@localhost ~]$ echo ${filename#*.}
tar.gz
[user@localhost ~]$ echo ${filename##*.}
gz
[user@localhost ~]$ 



[user@localhost ~]$ filename=/data/log/mylog
[user@localhost ~]$ echo ${filename##*/}
mylog  (파일명만 추출)
[user@localhost ~]$ echo ${filename%/*}
/data/log  (경로만추출)
[user@localhost ~]$ 
(확장자추출)



파일을 하나로 묶는것 tar에 c옵션
tar cvf archive명 묶을파일1 묶을파일2 묶을파일2

파일을 풀때 tar x옵션
tar xvf


-압축까지같이하고싶은경우 tar cv(z)f 처럼 옵션추가
gzip압축을 원할때 소문자 z 옵션  -> 확장자는 ~~.gz
bzip2 소문자 j 옵션  -> 확장자는 ~~.bz2
xz압축 대문자 J 옵션  -> 확장자는 ~~.xz


-압축을 풀려면
tar xvzf 파일이름
하고나면 현재 디렉토리에 풀린다??


#!/bin/bash
echo "filename?"
read filename

backupfile=${filename##*/}
echo $backupfile    <---파일명만 떼는법

extfile=${backupfile##*.}
echo $extfile  <----확장자떼는법

case $extfile in
"gz")
        option=z
        ;;
"xz")
        option=J
        ;;
"bz2")
        option=j
        ;;
*)
        echo "잘못되었습니다"
        exit 1
        ;;
esac

cd /tmp
tar xv${option}f $filename
~                                                                          
"mytar.sh" 28L, 296C 저장 했습니다  

----
[user@localhost ~]$ ./mytar.sh 
filename?
/tmp/backup.tar.bz2
backup.tar.bz2
bz2
home/user/shell/
home/user/shell/ch01/
home/user/shell/ch01/first.sh
home/user/shell/ch01/20170619.txt
home/user/shell/ch01/sample2.sh
home/user/shell/ch01/sample.sh
home/user/shell/ch02/
home/user/shell/ch02/test
home/user/shell/ch02/mkdir.sh
home/user/shell/ch02/sheellpid.sh
home/user/shell/ch02/functions
home/user/shell/ch02/read.sh
home/user/shell/ch02/test05.sh
home/user/shell/ch02/testt
home/user/shell/ch02/while.sh
home/user/shell/ch02/ifcheck.sh
home/user/shell/ch02/useradd.sh
home/user/shell/ch02/for.sh
home/user/shell/ch02/logincheck.sh
home/user/shell/ch02/myfunc.sh
home/user/shell/ch02/case.sh
home/user/shell/ch02/ifself.sh
home/user/shell/ch02/var.sh
home/user/shell/ch02/filecheck.sh
home/user/shell/ch02/hyojin
home/user/shell/ch02/tmp.sh
----


문제 실습


문제(1) 사용자의 홈디렉토리 사용량을 조사하는 쉘프로그램을 작성하세요.
단 실행시 사용자 이름이 전달되면 해당  사용자의 홈디렉토리 사용량만 조사하십시오.
예시)  ./homecheck.sh
-> 개인사용자 사용량 조사
./homecheck.sh user test
-> user, test 홈디렉토리 사용량만 조사

전체사용자할꺼냐
개인사용자로할꺼냐


사용자의 홈디렉토리 사용량
du명령

home디렉토리 아래에 개인사용자들의 홈디렉토리
/home

------homecheck.sh ----------------
#!/bin/bash

if [ $# -eq 0 ]
then
        du -sh /home/*
else
        for username in $@
        do
                if [ -d /home/$username ]
                then
                        du -sh /home/$username
                else
                        echo "wrong name"
                fi
        done
fi




문제(2) 특정 사용자 계정이 로그인하면 어떤 명령을 수행하는지
5초간격으로 모니터링하는 프로그램을 작성하십시오
(logincheck.sh 파일에 추가)

--스크립트

[user@localhost ~]$ cat logincheck.sh 

#!/bin/bash

echo "사용자를 입력하세요"

read username


while [ 1 -eq 1 ]

do

who | grep $username >/dev/null 2>&1

if [ $? -eq 0 ]

then

echo "$username 로그인했습니다"

sleep 5

ps -ef | grep ^${username}

else

echo "$username 로그인하지 않았습니다"

sleep 5

who | grep $username >/dev/null 2>&1

fi

done


[user@localhost ~]$ 

--실행결과

[user@localhost ~]$ ./logincheck.sh 

사용자를 입력하세요

test

test 로그인하지 않았습니다

test 로그인하지 않았습니다

test 로그인하지 않았습니다

test 로그인했습니다

test     34783 34773  0 11:08 ?        00:00:00 sshd: test@pts/2 

test     34784 34783  0 11:08 pts/2    00:00:00 -bash

test 로그인했습니다

test     34783 34773  0 11:08 ?        00:00:00 sshd: test@pts/2 

test     34784 34783  0 11:08 pts/2    00:00:00 -bash

test     34811 34784  0 11:09 pts/2    00:00:00 cat

test 로그인했습니다

test     34783 34773  0 11:08 ?        00:00:00 sshd: test@pts/2 

test     34784 34783  0 11:08 pts/2    00:00:00 -bash

test 로그인했습니다

test     34783 34773  0 11:08 ?        00:00:00 sshd: test@pts/2 

test     34784 34783  0 11:08 pts/2    00:00:00 -bash

test 로그인했습니다

^C

[user@localhost ~]$