2009년 2월 27일 금요일

2Day Study

2Day Study
[[[[[Shell Script 관련]]]]]
Shell 종류
sh(Bourne) => 유닉스 초기 버전의 원본 쉘
csh, tcsh, zsh => C 쉘 및 파생형 쉘 버클리 유닉스에서 사용됨
ksh, pdksh => 상당수의 상용 유직스의 기본 쉘
bash => GNU 리눅스 기본 쉘 Ksh와 유사함

명령어 결과 파일 출력
ls -l > lsoutput.txt <= New
ls -l >> lsoutput.txt <= Append

에러 정보가 화면에 나타나지 못하게 방지하며 에러 정보를 버릴때(표준 에러 파일 설명자 2)
ls -l 2> lsoutput.txt

kill 명령 결과를 killout에 저장, 에러는 killerr에 저장
kill -HUP 1234 >killout 2>killerr

양 출력을 하나의 파일로 저장
kill -1 1234 >killouterr 2>&1

표준에러 저장 안 하기
kill -1 1234 >/dev/null 2>&1

입력 리다이렉트
more < longtext

프로세서끼리 연결하기(ps의 출력을 받아서 알파벳순으로 정렬 후 uniq를 이용하여 프로세스만 추출하고 grep -v 를 이용하여 sh를 프로세서를 제거하고 more를 이용해서 페이지 단위로 보게함)
ps -xo comm | sort | uniq | grep -v sh | more

ps의 출력을 정렬 후 pssort에 저장
ps | sort > pssort

문자열에서 POSIX를 포함하고 있는 파일 이름을 출력
more 'grep -l POSIX *'
more $(grep -l POSIX *)
grep -l POSIX * | more

Shell Script FOR문
#!/bin/sh <= 시스템에게 이 줄의 인자가 이 파일을 실행시키기 위한 프로그램임을 지정(문자 32개 이하로 지정 구 버전 유닉스들이 지원 못 할 수도 있기 때문)
for file in *
do
if grep -q POSIX $file
then
echo $file
fi
done

exit 0 <= 쉘 프로그래밍에서 0은 성공을 의미한다. 스크립트 자체만으로는 어떠한 실패도 지각하지 못함으로 항상 0을 반환한다

쉘 스크립트의 기본 선언 변수는 문자열로 간주됨
쉘에서 $를 변수 이름 앞에 붙여서 변수의 내용을 액세스 할 수 있음
echo를 통해서 변수값을 화면에서 검사 가능(예: echo $data)
= 기호의 양쪽에는 어떠한 공백도 없어야 함

쓰기권한 제거
chown root ./filename
chgrp root ./filename
chmod 755 ./filename
chmod u=rwx,go=rx ./filename

사용자값 입력받기
read inputmsg
read 후 문자열 비교시 "로 꼭 싸주자
if [ $data = "yes" ] => if [ "$data = "yes" ]

쉘에서 ",',\ 차이점
#!/bin/sh
myvar="Hi there"
echo $myvar
echo "$myvar" <= 값으로 인식
echo '$myvar" <= 문자열로 인식
echo \$myvar < \을 앞에 붙여서 $ 기호의 특수한 의미를 제거
echo Enter some text
read myvar
echo '$myvar' now equals $myvar
exit 0

결과는
Hi there
Hi there
$myvar
$myvar
Enter some text
Hello World <= 키보드 입력을 받음
$myvar now equals Hello World

사용자의 환경 보기 명령어
env

환경변수 설정하는 명령어
export

환경변수
$HOME => 현재 사용자 홈 디렉토리
$PATH => PATH 디렉토리
$PS1 <= 명령어 프롬프트(예: [\u@\h \W]$는 사용자, 컴퓨터 이름, 현재 디렉토리를 보여줌
$PS2 <= 두번째 프롬프트(예: >)
$IFS => 입력 필드 구분자
$0 => 쉘 스크립트의 이름
$# => 전달된 매개변수의 갯수
$$ => 쉘 스크립느의 프로세스 ID

매개변수를 이용하는 방법
$ IFS=' '
$ set foo bar bam
$ echo "$@"
foo bar bam
$ echo "$*"
foobarbam
$ unset IFS
$ echo "$*"
foo bar bam
일반적으로 $@가 많이 쓰임

매개 변수와 환경 변수 실습 (try_var 로 저장)
#!/bin/sh
salutation="Hello"
echo $salutation
echo "$0"
echo "$2"
echo "$1"
echo "$*"
echo "$HOME"
exit 0

결과는
Hello
./try_bar
bar
foo
foo bar baz
/home/rick

쉘의 부울 검사를 할 때 쓰이는 명령어
test 혹은 [ <= [는 test이 축약형(도움말 보기는 help test)
ls -l /usr/bin/[

파일 존재 확인 스크립트(IF문 사용하기)
if test -f fred.c
then
...
elif
...
else
...
fi

if [ -f fred .c ]
then
...
elif
...
else
...
fi

if [ -f .tcsshrc ]; then ... ; elif ... ; else ... ; fi
위 3개의 if은 같은 스크립트다([ 괄호와 확인할 조건 사이에 공백을 반드시 넣어야 함)([ 명령을 사용하여 변수 내용을 테스트 한다. if 명령이 결과를 계산하고 다른 줄의 코드를 실행함)

출력값 응용(if와 elif 조건까지도 통과 된다면 else 출력 후 스크립트값을 1로 종료한다. 이 값을 사용하여 스크립트가 성공하였는지 검사를 할 수 있다)
if [ -f fred .c ];
then
...
elif
...
else
...
exit 1
fi
exit 0

문자열 비교
str1 = str2 <= 두 문자가 같으면 true
str1 != str2 <= 두 문자가 같이 않으면 true
-n str1 <= str1이 널(빈 문자열)이 아니면 true
-z str1 <= 문자열이 널(빈 문자열)이면 true

산술 비교
exp1 -eq exp2 <= 두 표현식이 같으면 true
-ne <= 두 표현식이 같지 않으면 true
-gt <= 왼쪽이 크면 true
-ge <= 왼쪽이 크거나 같으면 true
-lt <= 왼쪽이 작으면 true
-le <= 왼쪽이 작거나 같으면 true
! exp <= exp가 false면 true이고 그 역도 성립

파일 비교
-d file <= file이 디렉토리면 true
-e <= file이 존재하면 true(-e는 유닉스에서 잘 안 될수도 있기 때문에 -f가 흔히 사용됨)
-f <= 보통파일이면 true
-g <= set-group-id가 file이 설정되면 true(set-gid는 프로그램에게 자신의 그룹의 권한을 줌)
-r <= 파일을 읽을 수 있으면 true
-s <= 파일 크기가 0이 아니면 true
-u <= set-user-id가 file에 설정되면 true(set-user는 프로그램에게 자신의 사용자가 아닌 소유자의 권한을 줌)
-w <= 파일에 쓸 수 있으면 true
-x <= 파일이 실행 가능하면 true

echo 호환여부
echo -e는 모든 시스템에서 지원은 안 됨
bash는 echo -n을 지원하여 read시 줄 바꿈을 없애줌

FOR문 <= 지저분한다 다른 언어랑 좀 틀리다 ㅡㅡ; 버려!
#!/bin/sh
for foo in bar1 bar2 bar3
do
echo $foo
done
exit 0

결과는
bar1
bar2
bar3

#!/bin/sh
for foo in "bar1 bar2 bar3"
do
echo $foo
done
exit 0

결과는(bar1 bar2 bar3를 한 문자로 인식)
bar1 bar2 bar3

WHILE문
문자비교
#!/bin/sh
while [ "$data" = "true" ]
do
...
done

숫자비교 <= 우리가 일반적으로 쓰는 FOR문 대체
#!/bin/sh
data=1
while [ "$data" -le 20 ]
do
...
data=$(($data+1))
done

UNTIL문(명령줄에서 전달한 로그인 이름을 가진 사용자가 로그온 할 때 작동하도록 알람을 설정)
#!/bin/sh
until who | grep "$1" > /dev/null
do
sleep 60
done

echo "**** $1 has just logged in ****"
exit 0

CASE문(다른 언어에서는 switch문 이라고도 함)
case "$data" in
yes | zz ) echo "yes or zz";;
no ) echo "no";;
y ) echo "y";;
n ) echo "n";;
p* ) echo "p char start string";;
* ) echo "etc default";;
esac

AND 리스트
touch file_one
rm -f file_two
if [ -f file_one ] && echo "hello" && [ -f file_two ] && echo " there"
then
echo "in fi"
else
echo "in else"
fi
exit 0

결과는(file_one는 있으므로 hello를 출력하고 file_two는 없으므로 there를 출력하지 않고 else이 in else를 출력함)
hello
in else

OR 리스트
rm -f file_one
if [ -f file_one ] || echo "hello" || echo "there"
then
echo "in if"
else
echo "in else"
fi
exit 0

결과는(file_one가 없지만 OR 조건이므로 hello를 출력하고 in if를 출력함
hello
in if

SUB함수 쓰는 방법
#!/bin/sh

foo() {
echo "Function"
}
echo "script start"
foo
echo "script end"
exit 0

결과값
script start
Function
script end

SUB함수에서 지역변수는 local data="hahaha" 로 선언함

SUB함수 결과값 return 하기
#!/bin/sh
yes_or_no() {
echo "Is your name $* ?"
while true
do
echo -n "Enter yes or no: "
read x
case "$x" in
y | yes ) return 0;;
n | no ) return 1;;
* ) echo "Answer yes or no"
esac
done
}
echo "Rriginal parameters are $*"
if yes_or_no "$1" <= Rick Neil에서 첫번째 Rick만 넘김
then
echo "Hi $1, nice name"
else
echo "Naver mind"
fi
exit 0

결과값은
$ ./my_name Rick Neil
Original parameters are Rick Neil
Is your name Rick ?
Enter yes or no: yes
Hi Rick, nice name

댓글 없음:

댓글 쓰기