티스토리 뷰

간단한 개요

 

리눅스는 "User - 쉘 - 커널"이라는 개념으로 이루어짐 
쉘은 커널과 직접적으로 연결되어 사용자가 실행한 프로그램의 명령어를 해석하여 커널로 전달하는 역활

 

 

쉘의 종류
Bourne Shell (sh)
C Shell
Korn Shell
Bourne Agine Shell (bash)
TC Shell (tcsh)

 

Bash Shell
- 본 쉘을 업그레이드 시킨것임. 리눅스 대부분의 배포판에서 기본쉘로 지정되어 있음
- /etc/passwd 파일을 열어보면 root:x:0:0:root:/root:/bin/bash 요런식으로 정의 되어 있네
- /bin/tcsh 이런식으로 바꿀수도 있다네 ㅋ 다른 쉘로 바꿀수 있다네 ㅋ

 

sh scriptname 

chmod -x scriptname 을 준뒤 ./scriptname 으로 실행

 

보안상의 이유로 현재 디렉토리를 나타내는 "." 은 사용자의 $PATH에 들어 있지 않기 때문에 현재 디렉토리에 있는 
스크립트를 실행 시키려면 ./scriptname이라고 강제로 실행 경로를 알려줘야 합니다.

 

echo $PATH 해보면 PATH가 나오는데 스크립트에서 명령어를 실행할려면 PATH에 없는것들은 절대 경로 적어줘야 함

 

/usr/kerberos/sbin:/usr/kerberos/bin:/usr/lib/ccache:/usr/local/sbin:/usr/local/bin:/sbin:/bin:/usr/sbin:/usr/bin:/root/bin
명령어를 입력했을때 셀이 검색하는 디렉토리 보여줌 (앞에서 순서대로 검색)

 

Bash 스크립트를 sh scriptname 이라고 실행 시키게 되면 Bash 전용의 확장된 기능이 꺼져서 실행이 안될수 있음

bash scriptname 왠만하면 이걸로 실행라하는데 ㅋ

/usr/local/bin
 디렉토리로 scriptfile 옴기면 명령어 줄에서 간단히 scriptname 바로 실행할수 있다 (root권한으로)

 

vim scriptname 파일 만든후 그냥 연속적으로 실행할 명령어를 입력 해서 저장후 실행해도 잘 된다

cd /var/log
cat /dev/null > messages
cat /dev/null > wtmp
echo "로그를 정리했습니다."

 

보통 어떤님들이 만들어놓은 스크립트 파일을 보면

#! 라고 주석처리된 문자를 볼수 있는데
- 매직 넘버 "(magic number)로서, 실행 가능한 쉘 스크립트라는 것을 나타내는 특별한 표시자 라고 한네욤
- 스크립트의 제일 앞에서 이 파일이 어떤 명령어 해석기의 명령어 집합인지를 시스템에게 알려주는 역할이라고 함

#! 바로 뒤에 나오는 것은 경로명으로, 스크립트에 들어있는 명령어들을 해석할 프로그램의 위치를 나타냄
프로그램이 쉘인지, 프로그램 언어인지, 유틸리티인지를 나타냄
명시된 명령어 해석기가 주석은 무시하면서 스크립트의 첫 번째 줄부터 명령어들을 실행하게 됨

 

#!/bin/sh
#!/bin/bash
#!/usr/bin/perl
#!/usr/bin/tcl
#!/bin/sed -f
#!/usr/awk -f

 

스크립트에서 내부 쉘 지시자를 안 쓰고 일반적인 시스템 명령들만 쓴다면 #!는 안 써도 된다고 함

아래와 같이 특정 명령어를 명시하여서 만들수도 있다고 함 ㅋ
#!/bin/rm
#!/bin/more

 

echo
- 화면에 원하는 문자열을 출력시켜줌, 공백이 있을시 " " 로 묶어줍니다.

 

#!/bin/bash

echo "Red" 
echo -n "Red" # -n 옵션을 주면 자동으로 줄 바꿈하지 않는다. 기본은 줄바꿈이 된다
echo `ifconfig | grep inet` # ESC 밑에 키 역따옴표로 명령어에 대한 처리값을 출력할수도 있음

 

 

변수

형식

변수명=변수값
ex) korea="Seoul" # = 좌우에 공백이 있으면 안된다
ex) echo $korea


ex)
color=red
color=blue
color=yellow

color 라는 변수에 여러값을 넣었는데 echo $color 하면 제일마지막에 값을 넣은 yellow가 출력된다


ex)
color=red
say="This rose is $color"
echo $say

say변수값에 color의 변수가 값으로 이용됨 (변수안에 또 다른 변수 넣을수 있음)


변수 호출

변수호출시는 $와 변수명은 {} 로 둘러싼다? 
뭐 안해줘도 되는듯 하기도 함.

ex) 
cho = kjh
echo ${cho}



환경변수 = 전역변수 = global 변수

vim /etc/profile 을 보면 아래와 같이 환경변수가 지정되어 있음. 쉘 어디서든 호출 가능하다
export USER LOGNAME MAIL HOSTNAME HISTSIZE



read
- 사용자의 표준입력을 받아 변수로 저장하는 역활

#!/bin/bash

echo -n "age : " 
read x # 커서가 깜빡이면서 대기상태 값을 입력하면 변수 x 에 대입된다
echo -n "sex : "
read s

echo "Your age $x years old"
echo "Your sex is $s "


 

argument
- 예를 들어 스크립트 뒤에 stop | start | restart 이런걸 보고 argument 라고 한다

 

vim argu.sh

#!/bin/bash

echo "argument1 : $1" # 첫번째 argument
echo "argument2 : $2" # 두번째 argument
echo "argument3 : $3" # 세번째 argument

echo "Total argument number : $#" # $#는 전체 argument의 갯수를 나타냄
echo "This Filename : $0" # $0 은 스크립트 파일의 이름을 나타냄

[
root@localhost]# bash argu.sh red blue

argument1 : red
argument2 : red
argument3 : 

Total argument number : 2 # red blue 2개의 argument만 입력했으므로 2라고 나타남
This Filename : argu # 파일이름이 나타나네 ㅋ



관계 연산자

2가지 표현 방법이 있음

&& = AND
|| = OR

ex) if [${VAR} -gt 10]&& [${VAR} -lt 100]; then

아래것은 조건의 묶음 앞에 \ 가 있다.

-a = AND
-o = OR

ex) if [\(${VAR} -gt 10\)-a \(${VAR} -lt 100\)]; then

 

 

크기 연산자

[$A -gt $B] A값이 B값보다 크다
[$A -lt $B] A값이 B값보다 작다
[$A -ge $B] A값이 B값보다 크거나 같다
[$A -le $B] A값이 B값보다 작거나 같다
[$A -eq $B] A값과 B값이 같다
[$A -ne $B] A값과 B값이 다르다

 

 

ex)

 

argument 를 써서 뒤에 숫자를 줘서 나오게도 할수 있고 [ ] 대괄호 띠어쓰기 조심염

#!/bin/bash

if [ $1 -eq $2 ] # maybe A and B is equal
then
echo "$1 is equal to $2"
elif [ $1 -gt $2 ] # maybe A is greater than B
then
echo "$1 is greater than $2"
elif [ $1 -lt $2 ] # maybe A less than B
then
echo "$1 is less then $2"
fi


read 써서 입력값을 받아서 써볼수도 있겠다 ㅋ

#!/bin/bash
#echo -n "A : "
#read A
#echo -n "B : "
#read B
if [ $A -eq $B ] # maybe A and B is equal
then
echo "$1 is equal to $2"
elif [ $A -gt $B ] # maybe A is greater than B
then
echo "$1 is greater than $2"
elif [ $A -lt $B ] # maybe A less than B
then
echo "$A is less then $B"
fi

 

 

expr (숫자연산)

 

+ 더하기
- 빼기
* 곱하기 ('\*' 로 사용)
/ 나누기를 한 후의 몫의 값
% 나누기를 한 후의 나머지 값

ESC 밑에 있는 `` 역 따옴표 이용
*연산자와 () 앞에는 \ 를 붙인다
*만 쓴다면 모든것을 의미하는 특수문자로 인식함
\ 역 슬레시는 다음에 오는 문자의 특수의미를 없애주는 역활을 함
모든 숫자, 변수, 연산자 사이에는 공백(Space)가 있어야 함
()로 묶은 연산이 먼저 시작됨

 

 

ex)

 

#!/bin/bash
num=`expr \( 3 \* 5 \) / 4 + 7`
num2=`expr $num + 1`
echo $num2

 

ex)

 

#!/bin/bash
A=linux
echo "1. \$A is $A"
echo "2. \$A is $$A"
echo "3. \$A is $$$A"
echo "4. \$A is '$A'"
echo "5. \$A is "$A""

출력값

1. $A is linux
2. $A is 16261A
3. $A is 16261linux
4. $A is 'linux'
5. $A is linux

\$A 는 $A를 변수값이 아닌 문자 그대로 $A로 출력하기 위함 ( \ 는 바로뒤의 특수문자의 의미를 없애버림)
$$ 는 스크립트 파일이 실행되는 프로세스 번호를 나타냄 $$A 는 프로세스번호와 그냥 A라는 문자를 의미함
$$$A 는 프로세스번호와 $A 변수값 즉 linux를 의미함
' ' 작은 따옴표는 ' ' 자체가 문자임 ' ' 표시를 직접 출력함
" " 안에 문자를 그대로 보호해줌. space 공백, 특수문자는 특수문자로 일반문자는 문자 그대로 보호

 

 

문자열 비교

 

["string1"="string2"] # 두 문자열이 같은 경우
["string1"!="string2"] # 두 문자열이 다른 경우
[-z "string"] # 문자열의 길이가 0인 경우
[-n "string"] # 문자열의 길이가 0이 아닌 경우
공백이 없는 간단한 문자열일 경우 " " 안 써도 무방하다

 

 

 

#!/bin/bash
if [ H$1 = "Hyes" ]
then
echo "arugment is yes"
else
echo "argument is not yes"
fi


sh string1 yes 라고 넣은것과 이 외의 값을 넣은 경우 비교해보면 알겠지욤
$1 앞에 H 라는 값을 넣은이유는 argument 가 없을 경우 else 를 출력하기 위함
H 가 없다면 string1: line 3: [: =: unary operator expected 메세지 출력됨

 

 

파일 다루기

 

[-f 파일명] # 파일이 있는 경우
[-s 파일명] # 파일이 존재하고 내용이 있는 경우
[-d 파일명] # 파일이 아니고 디렉토리인 경우
[-r 파일명] # 읽기가 가능한 파일인 경우
[-w 파일명] # 쓰기가 가능한 파일인 경우
[-x 파일명] # 파일이 존재하고 실행이 가능한 경우
[!-옵션 파일명] # 옵션의 조건이 아닐경우

 

 

ex) 꿀 예제

 

#!/bin/bash
xfer=/var/log/xferlog
if [ -s $xfer ]
then
tail $xfer
fi

 

 

ex) 꿀 예제2

 

#!/bin/bash
if [ -f ./tempfile ]
then
echo "This is tempfile" > ./tempfile
else
touch ./tempfile
echo "I make tempfile" > ./tempfile
fi
cat ./tempfile

 

 

조건문

 

if / else

 

if [ 조건문 ] # [ 의 앞뒤 ] 의 앞에는 공백 (Space)가 있어야 한다
then
......
fi # if 안에 if, if를 여러개 사용가능하나 if 와 fi의 수는 동일해야함


#!/bin/bash
if [ 7 -gt 3 ]; then # 7 -gt 3 이 참이라면 then 구분을 실해한다 ' ; ' 세미콜론 표시는 라인의 끝으로 인식함
echo "7 is greater than 3"
fi


 

if [ 조건문 ]
then
......
else
if [ 조건문 ]
then
......
else
......
fi

 

 

간단예제)

 

#!/bin/bash
echo -n "Input number 1, 2, or 3 : "
read num
if [ $num -lt 1 ]
then
echo "1 than smaller number"
exit
elif [ $num -gt 3 ]
then
echo "3 than greater number"
exit
else
if [ $num -eq 1 ]
then
echo "one"
elif [ $num -eq 2 ]
then
echo "two"
elif [ $num -eq 3 ]
then
echo "three"
fi
fi

 

 

간단예제 ) 학점구하는거

 

#!/bin/bash
echo "jumsu changed hakjum"
echo -n "jumsu : "
read jumsu
if [ $jumsu -lt 0 ]
then
echo "jumsu is -?"
exit
elif [ $jumsu -gt 100 ]
then
echo "jumsu is too greater"
exit
else
if [ $jumsu -gt 90 ]
then
echo "A"
elif [ $jumsu -gt 80 ]
then
echo "b"
elif [ $jumsu -gt 70 ]
then
echo "c"
else
echo "F"
fi
fi


while

조건이 참일때 무한 반복하며 거짓일때 루프를 종료

until

조건이 거짓일때 무한 반복하며 참일때 루프를 종료

case 

전달 받은 변수값에 따라 각각 다른 수행을 하고 싶을때 사용

continue
반복문에서 continue 을 사용하면 continue 이하의 내용은 무시하고 다시 처음의 조건문으로 돌아감 (skip)

break
반복문에서 break 를 수행하면 수행된 시점에서 반복문을 강제로 종료하고 빠져 나옴


exit 명령어

- C 에서 처럼 스크립트를 끝낼때 사용 혹은 스크립트의 부모 프로세스에게 어떤 값을 돌려줄때도 사용
유닉스관례를 따르는 명령어 프로그램 유틸리티는 성공했을 때 종료상태로 0을 리턴합니다 실패시 0이 아닌수

스크립트 함수나 스크립트에서 가장 마지막에 실행된 명령어가 종료 상태스크립트에서 exit nnn 이라고 하면

nnn 이라는 종료 상태를 쉘에게 전달해 줍니다 (0 ~ 255 사이의 십진수)

스크립트가 종료한 다음에는 명령어줄에서 $?로 스크립트 마지막 명령어의 종료 상태를 알 수가 있는데 
관습적으로 0은 성공을 나타내고 1에서 255까지의 숫자는 에러나 예외 상황을 나타냅니다

 

#!/bin/bash
echo hello
echo $? # 명령어가 성공했기 때문에 종료 상태 0이 리턴됨.
lskdf # 알수없는 명령어.
echo $? # 0이 아닌 종료 상태가 리턴됨.
echo
exit 113 # 쉘에게 113을 리턴함.
# 확인해 보려면 이 스크립트가 종료된 다음에 "echo $?"라고 쳐 보세요.

 

논리적 "부정" 한정어(qualifier)인 ! 는 테스트나 명령어의 결과를 반대로 바꿔서 종료 상태에 영향을 미침 


몇몇 종료 상태 코드들은 예약되어 있어서 함부로 사용하면 않됨
- 2, 126 -

165, 255 번 종료 코드
 


 

 

특수문자

주석
- #
 로 시작하는 줄 (#! 제외)


; 명령어 구분자 [세미콜론]
- 두 개 이상의 명령어를 한 줄에서 같이 쓸 수 있게 해줍니다

echo hello; echo there

 

 

;; case 옵션 종료자. [이중 세미콜론]

 

case "$variable" in
abc) echo "$variable = abc" ;;
xyz) echo "$variable = xyz" ;;
esac

. "점"(dot) 명령어. [마침표] source 명령어와 동일합니다 (bash 내장 명령(builtin)입니다)

"점"(dot)이 정규 표현식(reqular expression)으로 해석될 때는, 한 개의 문자와 일치됩니다.

또다른 문맥에서는 그냥 ls 라고 쳤을 때, 보이지 않는 "숨김" 파일을 나타내는 파일명 접두어로도 쓰입니다.

 

bash$ touch .hidden-file
bash$ ls -l 
total 10
-rw-r--r-- 1 bozo 4034 Jul 18 22:04 data1.addressbook
-rw-r--r-- 1 bozo 4602 May 25 13:58 data1.addressbook.bak
-rw-r--r-- 1 bozo 877 Dec 17 2000 employment.addressbook
bash$ ls -al 
total 14
drwxrwxr-x 2 bozo bozo 1024 Aug 29 20:54 ./
drwx------ 52 bozo bozo 3072 Aug 29 20:51 ../
-rw-r--r-- 1 bozo bozo 4034 Jul 18 22:04 data1.addressbook
-rw-r--r-- 1 bozo bozo 4602 May 25 13:58 data1.addressbook.bak
-rw-r--r-- 1 bozo bozo 877 Dec 17 2000 employment.addressbook
-rw-rw-r-- 1 bozo bozo 0 Aug 29 20:54 .hidden-file

 

/ 파일명 경로 구분자. [슬래쉬] 파일명에 등장하는 각 요소들을 구분해 줍니다 (/home/bozo/projects/Makefile 처럼)
나누기 산술 연산자도 됩니다.


: 널 명령어(null command). 쉘의 "NOP"(no op, 아무 동작도 않함) 에 해당 쉘 내장 명령인 true의 동의어로 볼수 있음
bash 내장 명령이기 때문에 종료 상태는 0 이라는 것 ( : 자체가 명령어의 하나이므로 정상적으로 종료 상태가 됨)


무한루프

 

while :
do
첫번째 연산 
두번째 연산
...
n번째 연산
done

 

 

":"는 또한 /etc/passwd와 $PATH 변수에서 필드 구분자로도 쓰입니다

 

bash$ echo $PATH
/usr/local/bin:/bin:/usr/bin:/usr/X11R6/bin:/sbin:/usr/sbin:/usr/games

! : 테스트나 종료 상태의 의미를 반대나 부정해 줍니다. (!는 bash 키워드)
! 연산자는 해당 명령어의 종료 상태를 반대로 해 놓습니다
테스트 연산자의 의미도 거꾸로 바꿔 주는데 예를 들어, "equal"( = )을 "not-equal" ( != )로 해석하게 해 줍니다


( )

명령어 그룹

 

(a=hello; echo $a)

( ) 로 묶인 명령어들은 서브쉘에서 작동됨
스크립트의 다른 곳에서는 소괄호 안의 서브쉘에 들어 있는 변수들을 볼 수가 없습니다. 
부모 프로세스인 스크립트는 자식 프로세스(서브쉘)에서 만들어진 변수를 읽을 수가 없습니다

 

a=123
( a=321; )
echo "a = $a" # a = 123
# 소괄호 안의 "a" 는 지역변수처럼 동작합니다

 

 

배열초기화

 

Array=(element1 element2 element3)

{xxx,yyy,zzz...}


중괄호 확장

grep Linux file*.{txt,htm*}
# "fileA.txt", "file2.txt", "fileR.html", "file-87.htm" 등등의 파일에서
# "Linux"가 들어 있는 것을 모두 찾음


{ }

코드블럭

bash$ { local a; a=123; }
bash: local: can only be used in a function
a=123
{ a=321; }
echo "a = $a" # a = 321 (코드 블럭에서 설정된 값)

 

 

공백문자

명령어나 변수의 구분자 역할. 공백문자는 빈칸, 탭, 빈줄들의 어떠한 조합들로 이루어져 있습니다. 

변수 할당같은 상황에서 공백문자를 쓰면 문법 에러가 납니다.

빈줄은 스크립트 동작에 아무 영향도 주지 않기 때문에 기능별로 구분시켜서 보기 좋게 하는데 쓸 수 있습니다.

특수 변수인 $IFS는 어떤 명령어의 입력 필드를 구분해 주는데 이 변수의 디폴트값은 공백문자입니다


쿼우팅

문자열을 따옴표로 묶는 것을 말합니다. 이렇게 하는 이유는 문자열 안에 특수 문자가 들어가 있을 경우
쉘이나 쉘 스크립트에 의해 그 특수 문자가 재해석이나 확장되는 것을 방지하기 위해서 입니다.
(어떤 문자가 가진 글자 그대로의 뜻과는 다른 해석이 가능한 문자를 "특수 문자"라고 합니다. 
예를 들면, 와일드 카드 문자인 *가 특수 문자입니다.)

 

bash$ ls -l [Vv]* V 나 v 로 시작하는 파일들 검색할려고 하는듯
-rw-rw-r-- 1 bozo bozo 324 Apr 2 15:05 VIEWDATA.BAT
-rw-rw-r-- 1 bozo bozo 507 May 4 14:25 vartrace.sh
-rw-rw-r-- 1 bozo bozo 539 Apr 14 17:11 viewdata.sh

bash$ ls -l '[Vv]*' 이건 아마 문자 그대로의 [Vv]* 라는 파일을 찾는듯함 당연히 안 나올듯 ㅋ
ls: [Vv]*: No such file or directory


댓글
댓글쓰기 폼