How to write a shell script


A shell is a command line interpretor. It takes commands and executes them. As such, it implements a programming language. The Bourne shell is used to create shell scripts -- ie. programs that are interpreted/executed by the shell. You can write shell scripts with the C-shell; however, this is not covered here.

Creating a Script

Suppose you often type the command

    find . -name file -print

and you'd rather type a simple command, say

    sfind file

Create a shell script

    % cd ~/bin

    % emacs sfind

    % page sfind

    find . -name $1 -print

    % chmod a+x sfind

    % rehash

    % cd /usr/local/bin

    % sfind tcsh



This quick example is far from adequate but some observations:

  1. Shell scripts are simple text files created with an editor.
  2. Shell scripts are marked as executeable

3.      %chmod a+x sfind

  1. Should be located in your search path and ~/bin should be in your search path.
  2. You likely need to rehash if you're a Csh (tcsh) user (but not again when you login).
  3. Arguments are passed from the command line and referenced. For example, as $1.


All Bourne Shell scripts should begin with the sequence


From the man page for exec(2):

"On the first line of an interpreter script, following the "#!", is the name of a program which should be used to interpret the contents of the file. For instance, if the first line contains "#! /bin/sh", then the con- tents of the file are executed as a shell script."

You can get away without this, but you shouldn't. All good scripts state the interpretor explicitly. Long ago there was just one (the Bourne Shell) but these days there are many interpretors -- Csh, Ksh, Bash, and others.


Comments are any text beginning with the pound (#) sign. A comment can start anywhere on a line and continue until the end of the line.

Search Path

All shell scripts should include a search path specifica- tion:

    PATH=/usr/ucb:/usr/bin:/bin; export PATH

A PATH specification is recommended -- often times a script will fail for some people because they have a different or incomplete search path.

The Bourne Shell does not export environment variables to children unless explicitly instructed to do so by using the export command.

Argument Checking

A good shell script should verify that the arguments sup- plied (if any) are correct.


    if [ $# -ne 3 ]; then

         echo 1>&2 Usage: $0 19 Oct 91

         exit 127


This script requires three arguments and gripes accordingly.

Exit status

All Unix utilities should return an exit status.

    # is the year out of range for me?


    if [ $year -lt 1901  -o  $year -gt 2099 ]; then

         echo 1>&2 Year \"$year\" out of range

         exit 127





    # All done, exit ok


    exit 0

A non-zero exit status indicates an error condition of some sort while a zero exit status indicates things worked as expected.

On BSD systems there's been an attempt to categorize some of the more common exit status codes. See /usr/include/sysexits.h.

Using exit status

Exit codes are important for those who use your code. Many constructs test on the exit status of a command.

The conditional construct is:

    if command; then



For example,

    if tty -s; then

         echo Enter text end with \^D


Your code should be written with the expectation that others will use it. Making sure you return a meaningful exit status will help.

Stdin, Stdout, Stderr

Standard input, output, and error are file descriptors 0, 1, and 2. Each has a particular role and should be used accordingly:

    # is the year out of range for me?


    if [ $year -lt 1901  -o  $year -gt 2099 ]; then

         echo 1>&2 Year \"$year\" out of my range

         exit 127





    # ok, you have the number of days since Jan 1, ...


    case `expr $days % 7` in


         echo Mon;;


         echo Tue;;



Error messages should appear on stderr not on stdout! Output should appear on stdout. As for input/output dialogue:

    # give the fellow a chance to quit


    if tty -s ; then

         echo This will remove all files in $* since ...

         echo $n Ok to procede? $c;      read ans

         case "$ans" in


    echo File purge abandoned;

    exit 0   ;;


         RM="rm -rfi"


         RM="rm -rf"


Note: this code behaves differently if there's a user to communicate with (ie. if the standard input is a tty rather than a pipe, or file, or etc. See tty(1)).

Language Constructs

For loop iteration

Substitute values for variable and perform task:

    for variable in word ...




For example:

    for i in `cat $LOGS`


            mv $i $i.$TODAY

            cp /dev/null $i

            chmod 664 $i


Alternatively you may see:

    for variable in word ...; do command; done

  • Case

Switch to statements depending on pattern match

    case word in

    [ pattern [ | pattern ... ] )

         command ;; ] ...


For example:


    case "$year" in




            years=`expr $year - 1901`



            years=`expr $year - 1901`



            echo 1>&2 Year \"$year\" out of range ...

            exit 127



  • Conditional Execution

Test exit status of command and branch

    if command



    [ else

         command ]


For example:

    if [ $# -ne 3 ]; then

            echo 1>&2 Usage: $0 19 Oct 91

            exit 127


Alternatively you may see:

    if command; then command; [ else command; ] fi

  • While/Until Iteration

Repeat task while command returns good exit status.

    {while | until} command




For example:

    # for each argument mentioned, purge that directory


    while [ $# -ge 1 ]; do

            _purge $1



Alternatively you may see:

    while command; do command; done

  • Variables

Variables are sequences of letters, digits, or underscores beginning with a letter or underscore. To get the contents of a variable you must prepend the name with a $.

Numeric variables (eg. like $1, etc.) are positional vari- ables for argument communication.

    • Variable Assignment

Assign a value to a variable by variable=value. For example:

    PATH=/usr/ucb:/usr/bin:/bin; export PATH


    TODAY=`(set \`date\`; echo $1)`

    • Exporting Variables

Variables are not exported to children unless explicitly marked.

    # We MUST have a DISPLAY environment variable


    if [ "$DISPLAY" = "" ]; then

            if tty -s ; then

     echo "DISPLAY (`hostname`:0.0)? \c";

     read DISPLAY


            if [ "$DISPLAY" = "" ]; then



            export DISPLAY


Likewise, for variables like the PRINTER which you want hon- ored by lpr(1). From a user's .profile:

    PRINTER=PostScript; export PRINTER

Note: that the Cshell exports all environment variables.

    • Referencing Variables

Use $variable (or, if necessary, ${variable}) to reference the value.

    # Most user's have a /bin of their own


    if [ "$USER" != "root" ]; then





The braces are required for concatenation constructs.


The value of the variable "p_01".


The value of the variable "p" with "_01" pasted onto the end.

    • Conditional Reference

o    ${variable-word}

If the variable has been set, use it's value, else use word.





If the variable has been set and is not null, use it's value, else use word.

These are useful constructions for honoring the user envi- ronment. Ie. the user of the script can override variable assignments. Cf. programs like lpr(1) honor the PRINTER environment variable, you can do the same trick with your shell scripts.


If variable is set use it's value, else print out word and exit. Useful for bailing out.

    • Arguments

Command line arguments to shell scripts are positional vari- ables:

$0, $1, ...

The command and arguments. With $0 the command and the rest the arguments.


The number of arguments.

$*, $@

All the arguments as a blank separated string. Watch out for "$*" vs. "$@". 
And, some commands:


Shift the postional variables down one and decrement number of arguments.

set arg arg ...

Set the positional variables to the argument list.

Command line parsing uses shift:

    # parse argument list


    while [ $# -ge 1 ]; do

            case $1 in

         process arguments...




A use of the set command:

    # figure out what day it is


    TODAY=`(set \`date\`; echo $1)`


    cd $SPOOL


    for i in `cat $LOGS`


            mv $i $i.$TODAY

            cp /dev/null $i

            chmod 664 $i


    • Special Variables

o    $$

Current process id. This is very useful for constructing temporary files.


         trap "rm -f $tmp /tmp/cal1$$ /tmp/cal2$$"

         trap exit 1 2 13 15

         /usr/lib/calprog >$tmp



The exit status of the last command.


         # Run target file if no errors and ...


         if [ $? -eq 0 ]





  • Quotes/Special Characters

Special characters to terminate words:

      ; & ( ) | ^ < > new-line space tab

These are for command sequences, background jobs, etc. To quote any of these use a backslash (\) or bracket with quote marks ("" or '').

Single Quotes

Within single quotes all characters are quoted -- including the backslash. The result is one word.


         grep :${gid}: /etc/group | awk -F: '{print $1}'

Double Quotes

Within double quotes you have variable subsitution (ie. the dollar sign is interpreted) but no file name generation (ie. * and ? are quoted). The result is one word.

         if [ ! "${parent}" ]; then



Back Quotes

Back quotes mean run the command and substitute the output.


         if [ "`echo -n`" = "-n" ]; then








         TODAY=`(set \`date\`; echo $1)`

  • Functions

Functions are a powerful feature that aren't used often enough. Syntax is

    name ()




For example:


    # Purge a directory




            # there had better be a directory


            if [ ! -d $1 ]; then

     echo $1: No such directory 1>&2






Within a function the positional parmeters $0, $1, etc. are the arguments to the function (not the arguments to the script).

Within a function use return instead of exit.

Functions are good for encapsulations. You can pipe, redi- rect input, etc. to functions. For example:

    # deal with a file, add people one at a time




            while parse_one







    # take standard input (or a specified file) and do it.


    if [ "$1" != "" ]; then

            cat $1 | do_file




  • Sourcing commands

You can execute shell scripts from within shell scripts. A couple of choices:

sh command

This runs the shell script as a separate shell. For example, on Sun machines in /etc/rc:

         sh /etc/rc.local


This runs the shell script from within the current shell script. For example:

         # Read in configuration information

         .  /etc/hostconfig

What are the virtues of each? What's the difference? The second form is useful for configuration files where environment variable are set for the script. For example:

    for HOST in $HOSTS; do


      # is there a config file for this host?


      if [ -r ${BACKUPHOME}/${HOST} ]; then




Using configuration files in this manner makes it possible to write scripts that are automatically tailored for differ- ent situations.

Some Tricks

  • Test

The most powerful command is test(1).

    if test expression; then



and (note the matching bracket argument)

    if [ expression ]; then



On System V machines this is a builtin (check out the com- mand /bin/test).

On BSD systems (like the Suns) compare the command /usr/bin/test with /usr/bin/[.

Useful expressions are:

test { -w, -r, -x, -s, ... } filename

is file writeable, readable, executeable, empty, etc?

test n1 { -eq, -ne, -gt, ... } n2

are numbers equal, not equal, greater than, etc.?

test s1 { =, != } s2

Are strings the same or different?

test cond1 { -o, -a } cond2

Binary or; binary and; use ! for unary negation.

For example

    if [ $year -lt 1901  -o  $year -gt 2099 ]; then

         echo 1>&2 Year \"$year\" out of range

         exit 127


Learn this command inside out! It does a lot for you.

  • String matching

The test command provides limited string matching tests. A more powerful trick is to match strings with the case switch.

    # parse argument list


    while [ $# -ge 1 ]; do

            case $1 in

            -c*)    rate=`echo $1 | cut -c3-`;;

            -c)     shift;  rate=$1 ;;

            -p*)    prefix=`echo $1 | cut -c3-`;;

            -p)     shift;  prefix=$1 ;;

            -*)     echo $Usage; exit 1 ;;

            *)      disks=$*;       break   ;;






Of course getopt would work much better.

  • SysV vs BSD echo

On BSD systems to get a prompt you'd say:

    echo -n Ok to procede?;  read ans

On SysV systems you'd say:

    echo Ok to procede? \c; read ans

In an effort to produce portable code we've been using:

    # figure out what kind of echo to use


    if [ "`echo -n`" = "-n" ]; then

            n="";  c="\c"


            n="-n";     c=""





    echo $n Ok to procede? $c; read ans

  • Is there a person?

The Unix tradition is that programs should execute as qui- etly as possible. Especially for pipelines, cron jobs, etc.

User prompts aren't required if there's no user.

    # If there's a person out there, prod him a bit.


    if tty -s; then

         echo Enter text end with \^D


The tradition also extends to output.

    # If the output is to a terminal, be verbose


    if tty -s <&1; then





Beware: just because stdin is a tty that doesn't mean that stdout is too. User prompts should be directed to the user terminal.

    # If there's a person out there, prod him a bit.


    if tty -s; then

         echo Enter text end with \^D >&0


Have you ever had a program stop waiting for keyboard input when the output is directed elsewhere?

  • Creating Input

We're familiar with redirecting input. For example:

    # take standard input (or a specified file) and do it.


    if [ "$1" != "" ]; then

            cat $1 | do_file




alternatively, redirection from a file:

    # take standard input (or a specified file) and do it.


    if [ "$1" != "" ]; then

            do_file < $1




You can also construct files on the fly.

    rmail bsmtp <<$>

    rcpt to:


    from: <$>


    Subject: Signon $2


    subscribe $2 Usenet Feeder at UWO




Note: that variables are expanded in the input.

  • String Manipulations

One of the more common things you'll need to do is parse strings. Some tricks


    TIME=`date | cut -c12-19`


    TIME=`date | sed 's/.* .* .* \(.*\) .* .*/\1/'`


    TIME=`date | awk '{print $4}'`


    TIME=`set \`date\`; echo $4`


    TIME=`date | (read u v w x y z; echo $x)`

With some care, redefining the input field separators can help.



    # convert IP number to name



    {    set `IFS=".";echo $1`

         echo $4.$3.$2.$



    if [ $# -ne 1 ]; then

         echo 1>&2 Usage: bynum IP-address

         exit 127



    add=`name $1`


    nslookup < < EOF | grep "$add" | sed 's/.*= //'

    set type=any



  • Debugging

The shell has a number of flags that make debugging easier:

sh -n command

Read the shell script but don't execute the commands. IE. check syntax.

sh -x command

Display commands and arguments as they're executed. In a lot of my shell scripts you'll see

    # Uncomment the next line for testing

    # set -x

Based on An Introduction to Shell Programing by:

Reg Quinton

Computing and Communications Services

The University of Western Ontario

London, Ontario N6A 5B7


Press here to return to the General Unix Software Menu.

Posted by 두장

a : "am" or "pm" 표시
A : "AM" or "PM" 표시
d : 오늘이 몇일인지 표시 "01" to "31"
D : 영문으로 요일을 표시 "Mon", "Fri"
F : 영문으로 달을 표시 "January", "July"
h : 12시간을 표시. 오후 3시라도 03으로 표시. "01" to "12"
H : 24시간을 표시. 오후 3시 경우 15로 표시. "00" to "23"
g : 12시간을 표시. h와 다른 점은 0이 없다. "1" to "12"
G : 24시간을 표시. H와 다른점은 0이 없다. "0" to "23"
i : 분을 표시. "00" to "59"
j : 오늘이 몇일인지 표시. d와 다른 점은 0이 앞에 없다. "1" to "31"
l(소문자 엘) : "Friday"식으로 표시
m : 달(month)을 표시. "01" to "12" 
n : 달을 표시. 0없이 "1" to "12"
M : "Jan"으로 표시
s : 초(sec)를 표시 "00" to "59"
t : 이번 달의 마지막 표시 "28" 부터 "31"일 까지
U : 기준 시점(GMT 1970년 1월 1일 00:00:00)으로부터 지난 시간을 초로 표시
w : 이번 주를 숫자로 표시 "0"(일요일) 부터 "6"(토요일)로 표시
Y : 연도(year)를 4자리로 표시. "2001"
y : 연도를 2자리로 표시. "01"
z : 올해부터의 날(day) 표시. "0" 부터 "365" 로 표시
Posted by 두장

vi /etc/gdm/custom.conf


AllowRemoteRoot=true    => root로 로그인 허용

Enable=1                      => xmanager 접속 허용





Posted by 두장
snort 사이트 에서  snort 소스를 다운 받아 압축을 푼다.

snort를 mysql에 연동하지 않고 컴파일 할때는 
[root@localhost ~]# ./configure
[root@localhost ~]# make
[root@localhost ~]# make install
위와 같이 특별한 옵션 없이 컴파일후 사용하면 된다.

하지만 mysql에 연동을 하기 위해서는 
[root@localhost ~]# ./configure --with-mysql
[root@localhost ~]# make
[root@localhost ~]# make install
위와 같이 mysql 옵션을 포함시켜서 configure를 해야 한다.
하지만 mysql의 위치를 제대로 찾지 못할경우..
[root@localhost ~]# ./configure --with-mysql="/usr/lib/mysql"

snort에서 제공하는 create_mysql을 통해 snort database에 table을 작성한다.
mysql -u root -p snort < schemas/create_mysql
Posted by 두장
2009.05.26 17:36
Linux Run Level

RunLevel 0 : 시스템 종료(halt)
RunLevel 1 : 단일 사용자, 싱글 모드
RunLevel 2 : NFS를 지원하지 않는 다중 사용자 모드
RunLevel 3 : 모든 기능을 포함한 다중 사용자 모드(X윈도우 지원안함)
RunLevel 4 : 사용되지 않는 실행모드(사용자가 직접정의하여 사용)
RunLevel 5 : X윈도우 부팅, GUI환경
RunLevel 6 : 시스템 재부팅

RunLevel 3이라면 /etc/rc.d/rc3.d 디렉토리에 있는 심볼릭 링크 스크립트(실제 스크립트 파일은 /etc/rc.d/init.d 디렉토리에 있음)를 실행함.

init 명령어를 사용하여 RunLevel을 전환 할수 있다.

 [root@localhost ~]#  init 3

기본적으로 부팅되는 RunLevel을 변경하기 위해서는 /etc/inittab 파일을 수정해야 한다.


# inittab       This file describes how the INIT process should set up

#               the system in a certain run-level.


# Author:       Miquel van Smoorenburg, <>

#               Modified for RHS Linux by Marc Ewing and Donnie Barnes



# Default runlevel. The runlevels used by RHS are:

#   0 - halt (Do NOT set initdefault to this)

#   1 - Single user mode

#   2 - Multiuser, without NFS (The same as 3, if you do not have networking)

#   3 - Full multiuser mode

#   4 - unused

#   5 - X11

#   6 - reboot (Do NOT set initdefault to this)


id:5:initdefault:     # 부팅시 기본적으로 적용되는 RunLevel


# System initialization.


 l0:0:wait:/etc/rc.d/rc 0

l1:1:wait:/etc/rc.d/rc 1

l2:2:wait:/etc/rc.d/rc 2

l3:3:wait:/etc/rc.d/rc 3

l4:4:wait:/etc/rc.d/rc 4

실행 레벨 설정 (chkconfig 명령어)

 [root@localhost ~]#  chkconfig --list 
모든 데몬들의 실행 레벨을 확인

 [root@localhost ~]#  chkconfig --list httpd
httpd 데몬의 실행 레벨을 확인

 [root@localhost ~]#  chkconfig --level 2345 httpd on
httpd 데몬의 실행 레벨 2,3,4,5 번 활성화 시킴

Linux Root 계정의 PassWord를 잊어버렸을 경우 Linux 부팅시 RunLevel 1로 전환 후 부팅을 하면
Linux 부팅후 로그인 과정 없이 접속할수 있다.
 Linux 를 부팅시 커널 버전을 선택할수 있는 Grub 화면이 뜨면
부팅 하고자 하는 커널 버전을 선택한후 'e'를 입력하면
RunLevel을 수정할수 있는 화면이 나온다..
kernel /vmlinuz-2.6.9-34.EL ro root=LABEL=/ 1
여기서 위와 같이 "root=LABEL=/" 뒤에 원하는 RunLevel "1"을 추가한후 부팅하면 된다

Posted by 두장
2009.04.28 20:50

시스템이 시작할 때 불필요하거나 사용하지 않는 서비스를 실행하지 않게 하는 방법 중 최근에 많이 쓰이는 명령어로 chkconfig가 있다. chkconfig 명령어를 이용하면 시스템에 설치되어 있는 모든 서비스 데몬을 확인할 수 있고, 특정 서비스를 쉽게 활성화하거나 해제할 수 있다.

예를 들어보자.

#chkconfig --list

//시스템에 설치되어 있는 모든 서비스 데몬을 확인할 수 있다.

#chkconfig --level 2345 sendmail off

//런레벨 2~5에서 sendmail을 해제한다.

#chkconfig --level 2345 nfs on

//런레벨 2~5에서 nfs 서비스를 활성화한다.

#chkconfig rlogin off

//xinetd 기반의 서비스인 rlogin을 해제한다.

--add와 --del 스위치를 사용해서 서비스를 추가하거나 삭제할 수 있다. chkconfig는 단지 설정 파일을 변경하여, 시스템을 부팅했을 때 해당 서비스 데몬의 실행 여부만 결정하는 것이므로, 다앙 서비스를 시작시키거나 중지시키려면 반드시 service 명령을 사용해야 한다. 참고로 service 명령어는 다음과 같이 사용한다.

service 서비스명 {start | stop | restart | reload}

레드햇에는 chkconfig외에도 ntsysv라는 조금은 오래된 툴이 있다. 이 툴은 시스템을 재시작할 때 자동으로 시작할 데몬을 *로 체크해서 손쉽게 지정할 수 있다. 



  chkconfig - updates and queries runlevel information for system services


  chkconfig --list [name]

  chkconfig --add name

  chkconfig --del name

  chkconfig [--level levels] name <on|off|reset>

  chkconfig [--level levels] name


  chkconfig  provides  a  simple  command-line  tool  for maintaining the /etc/rc[0-6].d directory hierarchy by relieving system administrators of the task of directly manipu-lating the numerous symbolic links in those directories.

  This  implementation of chkconfig was inspired by the chkconfig command present in the IRIX operating system. Rather than maintaining configuration  information  outside  of the  /etc/rc[0-6].d  hierarchy, however, this version directly manages the symlinks in /etc/rc[0-6].d. This leaves all of the configuration information regarding  what  ser-vices init starts in a single location.

  chkconfig  has  five  distinct functions: adding new services for management, removing services from management, listing the current startup information for services, chang- ing the startup information for services, and checking the startup state of a particu- lar service.

  When chkconfig is run without any options, it displays usage information.  If  only  a service  name is given, it checks to see if the service is configured to be started in the current runlevel. If it is, chkconfig returns true; otherwise  it  returns  false.

  The  --level option may be used to have chkconfig query an alternative runlevel rather than the current one.

  If one of on, off, or reset is specified after the service name, chkconfig changes the startup information for the specified service.  The on and off flags cause the service to be started or stopped, respectively, in the runlevels  being  changed.   The  reset flag  resets  the  startup information for the service to whatever is specified in the init script in question.

  By default, the on and off options affect only runlevels 2, 3, 4, and 5,  while  reset affects  all  of  the runlevels.  The --level option may be used to specify which run-levels are affected.

  Note that for every service, each runlevel has either a start script or a stop script.

  When  switching runlevels, init will not re-start an already-started service, and will not re-stop a service that is not running.

  chkconfig also can manage xinetd scripts  via  the  means  of  xinetd.d  configuration files. Note that only the on, off, and --list commands are supported for xinetd.d ser-vices.

  --level levels
    Specifies the run levels an operation should pertain  to.  It  is  given  as  a string  of  numbers  from 0 to 7. For example, --level 35 specifies runlevels 3 and 5.

  --add name
    This option adds a new service for management by chkconfig.  When a new service is added, chkconfig ensures that the service has either a start or a kill entry in every runlevel. If any runlevel is missing such an entry, chkconfig  creates the  appropriate  entry  as specified by the default values in the init script.
  Note that default entries in LSB-delimited ’INIT INFO’ sections take precedence over the default runlevels in the initscript.

  --del name
    The  service  is  removed  from chkconfig management, and any symbolic links in /etc/rc[0-6].d which pertain to it are removed.

    Note that future package installs for this service  may  run  chkconfig  --add, which will re-add such links. To disable a service, run chkconfig name off.

  --list name
    This  option lists all of the services which chkconfig knows about, and whether they are stopped or started in each runlevel. If name is specified, information in only display about service name.

  Each service which should be manageable by chkconfig needs two or more commented lines added to its init.d script. The first line tells chkconfig what runlevels the  service should be started in by default, as well as the start and stop priority levels. If the service should not, by default, be started in any runlevels, a -  should  be  used  in place  of the runlevels list.  The second line contains a description for the service, and may be extended across multiple lines with backslash continuation.

  For example, random.init has these three lines:
  # chkconfig: 2345 20 80
  # description: Saves and restores system entropy pool for \
  #              higher quality random number generation.
  This says that the random script should be started in levels 2, 3, 4, and 5, that  its start  priority  should be 20, and that its stop priority should be 80.  You should be able to figure out what the description says; the \ causes the line to  be  continued.
       The extra space in front of the line is ignored.

Posted by 두장

리눅스에서 현재 시스템 시간 확인

# date

시스템의 하드웨어에 입력되어 있는 시간 출력

# clock

시스템 시간을 하드웨어 시간에 입력

# clock -w

실제 현재 시간과 시스템에 설정된 시간이 다를 경우가 있다.
이때 보라넷 서버 시간과 일치시키기 위해 아래와 같이 하면된다.
(보라넷 서버 시간은 실제 현재 시간과 일치하기때문에)

# rdate -s && clock -w

아래와 같이 하면 리눅스의 시간을 임의로 설정 할수도 있다.

다음은 2009년 06월 30일 15시 55분으로 시스템의 시간을 설정하는 명령어이다. 

# date 063015522009

Posted by 두장
정규표현식 (Regular Expression) 이란 무엇인가? 이 질문은 진짜 어렵다. 너도 나도 정규표현식을 얘기하지만 정작 정규표현식이 뭔지는 잘 안 나와 있다. (오토마타 수업을 들은 풍월로 굳이 얘기하자면 정규 문법에 의해 생성되는 정규 언어를 표현할 수 있는 표현식..이라고 하면 되려나) 어쨌거나, "하나 이상의 문자열을 한 번에 나타낼 수 있는 패턴"이 정규 표현식이다. 아래는 UNIX 서적이나 웬만한 웹사이트에 다 나오는 기본 정규 표현식이다.
a : 말 그대로 "a", b 는 당연히 "b", c 는...
. : 임의의 한 글자. 따라서 a.d 는 aad abd acd add aed afd...
[list] : list 중의 한 글자. 
  [adf] 는 a 또는 d 또는 f
  [a-f] 는 a, b, c, d, e, f
  [^adf] 는 a, d, f 를 제외한 나머지 중 한 글자. list 앞에 "^" 이 오면 뒤에 오는 것을 제외한 것을 의미한다.
  [^a-f] 는.. 말 안 해도 되겠지
 그러면 "^ 또는 a 또는 b"를 의미하고 싶을 때는? "^"를 list 의 제일 앞이 아닌 곳에 두면 된다.
  [ab^] - 마찬가지로 "-" 나 "]" 역시 [ab-] []df] 와 같이 쓴다.
* : 0번 이상의 임의 번 반복. a* 는 null string, a, aa, aaa, aaaa...

그런데 아무래도 저것만 가지고는 좀 불편하다. 그래서 "확장 정규 표현식"이 등장했다.

+ : 1번 이상의 임의 번 반복. a+ 는 a, aa, aaa, ... 즉 aa* 와 동일.
| : a|b 는 a 또는 b
() : group, (ab|cd)ef 는 abef 또는 cdef
? : 없거나 하나 있거나. ab? 는 a 또는 ab

위의 확장 정규 표현식은 Perl에서는 그냥 쓰면 되고, ViEditor 에서는 앞에 백슬래쉬를 붙여 a\+ 와 같이 사용한다.

임의 번 반복 대신이 구체적으로 숫자를 줄 수도 있다.

{n,m} : n번 이상 m번 이하 반복 (가능한 많이)
{n} : n번 반복
{n,} : n번 이상 반복 (가능한 많이)
{,m} : m번 이하 반복 (가능한 많이)
{} : 0 번 이상. * 와 동일

{-n,m} : n번 이상 m번 이하 (가능한 적게)
{-n} : n번
{-n,} : n번 이상 (가능한 적게)
{-,m} : m번 이하 (가능한 적게)
{-} : 0번 이상 (가능한 적게)

역시 vi 에서는 앞에 백슬래쉬를 붙여서 a\{2,5} 등과 같이 사용한다.

위에서 "가능한 많이"와 "가능한 적게"는 뭔가? abcdebcdebcde 라는 예로 들면, a.*d 는 abcdebcdebcd 에 매칭되고, a\{-}d 는 abcd 에 매칭된다.


Posted by 두장
linux vi 에디터에서 문자(열)을 찾아서 바꾸기

- 시작줄, 끝줄 : 바꾸기를 할 범위를 행번호로 지정한다. "."는 현재 커서가 있는 행을 의미, "$"는 제일 마지막 행을 의미한다.
- 찾을 패턴, 바꿀 스트링 : 찾을 패턴은 정규 표현식으로 지정하고, 바꿀 스트링은 string지정한다.
- 옵션 : 
g (global) - 한줄에 일치하는 패턴이 여러개 나오면 모두 바꾼다. 지정하지 않으면 첫번째 패턴만 바꾼다.
i (ignore case) - 대소문자 구분을 하지 않는다
c (confirm) - 검색된 문자열에 대해서 바꿀지 말지를 물어본다.

 :5,10s/a/b/      - 5번째 행부터 10번째 행까지 각 행의 첫번째 "a"를 "b"로 바꾼다.
 :.,.+10s/a/b/g  - 현재 행부터 (현재 행 번호 + 10)번째 행까지 모든 "a"를 "b"로 바꾼다.
 :1,$s/a/b/c     - 첫번째 행부터 마지막 행까지 (즉 문서 전체) 각 행의 "a"를 "b"로 바꾸되, 바꾸기 전 확인을 받는다.
 :%s/a/b/gi      - 문서 전체에서 "a"와 "A"를 "b"로 바꾼다.

Posted by 두장
보통의 경우그래픽 카드가 설치되어 있는 컴퓨터나 머신에는 직접 모니터를 연결하여 리눅스를 설치 할 것이다..

그럴 경우 시디롬으로 부팅한 후 부팅 옵션을 입력하는 화면이 나왔을 때 단지 Enter를 입력하거나 

"linux"라고 입력하고 GUI를 통해 리눅스를 설치한다.

하지만 그래픽 카드가 없는 컴퓨터나 머신에서 리눅스를 설치하기 위해서 모니를 직접 연결 할수 없으므로

콘솔을 터미널 서버에 연결해서 리눅스를 설치해야한다. 이때는 GUI를 통해 리눅스를 설치하는 것이 불가능하다..

이때도 똑같이 리눅스 시디를 시디롬에 넣고 시디롬 부팅을 한 후

부팅 옵션을 입력하라는 화면이 나오면 단순히 "linux"라고 해서는 안되고

이때 "linux text console=ttyS0,115200n8" 라고 부팅 옵션을 입력하면
("ttyS0, 115200n8" < -- 이부분은 각각의 머신마다 변경 될수 있다.)

텍스트 형식으로 화면을 보면서 리눅스를 설치할 수 있다.

이때는 설치 과정이 GUI로 마우스로 클릭할수 있는 화면이 아니라

설치과정이 text형식으로 나오기때문에 설치과정에 좀더 유의해야 한다...

Posted by 두장
이전버튼 1 2 이전버튼