BashLecture1

From KBase

Jump to: navigation, search

Contents

[edit] Specifying Interpreter

Magic number 라는 것이 있는데, Windows 는 전통적으로 파일의 종류를 확장자로 구분하지만, unix 에서는 이 magic number 라는 것을 이용하여 파일을 구별하기도 한다. 예를 들어 ELF executable 은 파일의 맨 앞이 MZ 이고 GIF 파일은 GIF87 혹은 GIF89a 등이며, JPEG 파일은 파일의 앞부분에 JFIF 란 문자열이 들어 있다.

실행가능한 script 파일은 파일의 맨 앞 두글자가 #! 이고, 이후 newline 까지의 문자열이 해당 script 파일의 interpreter 로 사용된다. 따라서 bash script 는 #!/bin/bash 로 시작하며, perl script 는 #!/usr/bin/perl 로 시작하는 식이다. 내가 interpreter 를 만들었다면 #!/path/to/my/interpreter/mine 과 같이 지정해 줄 수도 있다.

bash 는 sh 를 기반으로 하고 있으므로 bash 만의 extension 을 사용했으면 #!/bin/bash 를 쓰면 되고, sh 와 호환 가능한 내용만을 썼으면 #!/bin/sh 를 쓰면 된다.

[edit] Command Sequence

command line 으로 입력할 명령어들을 나열하는 것만으로도 훌륭한 script 가 될 수 있다. 예를 들면 directory 를 바꾸고, 특정 파일을 삭제하고, 다시 원래 directory 로 돌아가서 특정 파일을 만드는 등의 역할을 수행하는 script 는 다음과 같다

#!/bin/sh
cd subdir
rm *.bak
cd ..
echo babo > babo.txt

[edit] Pipelines

두 개 process 사이의 file 을 연결해 주는 것을 pipeline 이라고 한다. shell 에서는 두 개의 프로그램을 실행시키고 그 중 하나의 stdout 과 나머지 하나의 stdin 을 연결하는 것을 뜻하게 된다. pipeline 은 vertical bar ( | ) 를 사용하여 다음과 같이 사용한다

/bin/ls | sed 's/^/file: /'

[edit] Comment

  1. 으로 시작하는 줄은 comment 로 처리된다. 라인의 중간부터 시작해도 된다. 맨 앞에 있는 #! 는 magic number 로 사용되므로 중간부터 시작하면 안된다.

[edit] Conditional Execution

Shell script 도 명색이 프로그램인데, 위와 같이 단순한 명령어의 나열에서 탈피하여 조건부로 실행되는 코드를 만들어 본다.

[edit] Exit status

process 가 종료할 때 보고하는 값이다. C 로 프로그램을 만들었다면 main() 이 리턴하는 값 (혹은 exit() 의 인자) 이다. 이 값을 이용하여 프로그램이 정상적으로 종료했는지, 혹은 어떤 비정상적인 이유로 종료했는지를 알 수 있다.

$ cat xx.c
#include <stdio.h>
int main(void)
{
		  return 123;
}
$ ./a.exe
$ echo $?
123

위에서 보는 것과 같이 main 이 리턴한 0 이 $? 에 출력되는 것을 볼 수가 있다.

전통적으로, exit status 가 0 이면 에러가 없는 것으로, 0 이 아니면 에러 코드인 것으로 간주된다. 파일을 복사하는 cp 의 예를 들어보자

$ cp xx.c kkk.c
$ echo $?
0
$ cp notexist.c kk.c
cp: cannot stat `notexist.c': No such file or directory
$ echo $?
1

copy 를 잘 했을 경우는 $? 값이 0 이지만 없는 파일을 복사하려고 시도했을 때는 $? 값이 1 인 것을 볼 수 있다.

[edit] &&, ||

단순한 나열을 했을 때는 앞에 실행한 것이 실패했을 때도 다음 것을 시도하기 때문에 문제가 된다. 이럴 때는 다음과 같이 하나의 command 를 실행한 후 그 결과에 따라 다음 command 를 실행하도록 한다.

$ cp notexist.c kk.c && echo babo
cp: cannot stat `notexist.c': No such file or directory
$ cp xx.c kk.c && echo babo
babo

위에서처럼 cp 가 성공했을 때만 echo 를 실행하게 된다.

=&&= 는 앞의 것이 성공했을 때 뒤의 것이 실행되며 || 는 앞의 것이 실패했을 때 뒤의 것이 실행된다.

[edit] if

=&&= 나 || 를 좀 더 구조적으로 쓰고 싶으면 if 를 쓴다

if test-commands; then
  consequent-commands;
[elif more-test-commands; then
  more-consequents;]
[else alternate-consequents;]
fi

[edit] case

echo -n "Enter the name of an animal: "
read ANIMAL
echo -n "The $ANIMAL has "
case $ANIMAL in
  horse | dog | cat) echo -n "four";;
  man | kangaroo ) echo -n "two";;
  *) echo -n "an unknown number of";;
esac
echo " legs."

* case 의 끝은 그 글자들을 뒤집은 esac 이다. 이것은 위에 나오는 if 도 그렇다. * pattern 은 ) 로 구분지으며, 명령어를 나열한 후 ;; 로 끝마친다.

[edit] select

select fname in *;
do
	 echo you picked $fname \($REPLY\)
	 break;
done

[edit] Loop

반복을 하고 싶을 때 사용한다

[edit] for / expression

$ for ((n=1;n<10;n++)); do echo $n; done
1
2
3
4
5
6
7
8
9

[edit] for / words

$ for fname in babo kakaka *.c; do echo $fname; done
babo
kakaka
kk.c
kkk.c
xx.c
yy.c
zz.c

[edit] Quotes

single quote (') 에서는 interpolation (shell expansion) 이 일어나지 않는다. double quote (") 에서는 가능하다. back quote 는 실행 결과를 의미한다

$ a=`ls`
$ b='a is: $a'
$ c="a is: $a"
$ echo $a
C++Lect/ a.exe kk.c kkk.c scribble.GIF xx.c xx.exe yy.c yy.exe zz.c zz.exe
$ echo $b;
a is: $a
$ echo $c
a is: C++Lect/ a.exe kk.c kkk.c scribble.GIF xx.c xx.exe yy.c yy.exe zz.c zz.exe

[edit] Variables and Functions

[edit] Variable

=name=[value]= 와 같은 형태로 지정하고 앞에 $ 를 붙여서 읽는다

[edit] Function

syntax:

[edit] [ function ] name () compound-command [ redirections ]

[edit] Shell Parameters

[edit] Positional Parameters

$1, $2 와 같이 parameter 에 번호를 붙일 수 있다. $0 은 실행시킨 script 자신을 의미한다.

$ cat babo.sh
#!/bin/sh
echo 0: $0
echo 1: $1
echo 2: $2
$ ./babo.sh a b c
0: ./babo.sh
1: a
2: b

[edit] Special Parameters

$ cat ./babo.sh
#!/bin/sh
echo *: $*
echo @: $@
echo \#: $#
echo ?: $?
echo -: $-
echo \$: $$
echo !: $!
echo 0: $0
echo _: $_
$ ./babo.sh a b c d
*: a b c d
@: a b c d
#: 4
?: 0
-: hB
$: 3252
!:
0: ./babo.sh
_: ./babo.sh

[edit] Shell Expansions

[edit] Brace

bash$ echo a{d,c,b}e
ade ace abe

[edit] Tilde

ls ~ ~scgyong

[edit] Parameter

$ a=babo
$ unset b
$ echo ${a}, ${b}
babo,
$ echo ${a:-kakaka}
babo
$ echo ${b:-kakaka}
kakaka
$ echo ${a:1}
abo
$ echo ${a:1:2}
ab
$ echo ${a#ba}
bo

[edit] Command Substitution (Back quote)

=$(command)= 혹은 `command`

[edit] Arithmetic

[edit] $((expression))

[edit] Filename

  • , ?, [abc], [a-c]

[edit] Redirection

stdout (file descriptor 1)과 stderr (file descriptor 2) 를 모두 dirlist 로 redirect 하려면 다음과 같이 한다

  ls > dirlist 2>&1

다음은 stdout 만을 dirlist 로 보내는데, stdout 이 dirlist 로 redirect 되기 전에 stderr 가 stdout 으로 duplicate 되기 때문이란다.

  ls 2>&1 > dirlist
Personal tools
Wiki Help (mediawiki.org)