시스템이야기2012. 5. 29. 18:19

bash

1. seq 명령

GNU의 coreutils패키지에는 seq명령(리눅스에 기본 설치, FreeBSD는 /usr/ports/sysutils/coreutils 포트를 설치하면 gseq명령으로 설치됨)이 있다. seq는 숫자를 순차적으로 출력해주는 명령이다. 예를 들어 1부터 5까지, 또는 1부터 10까지 2씩 증가하여 출력하고 싶다면 seq사용하면 된다.

$ seq 1 5
1
2
3
4
5
$ seq 1 2 10
1
3
5
7
9

bash 쉘스크립트의 for문에서 seq명령을 사용한 예이다. 1부터 31까지 순차적으로 출력된다.

#!/bin/bash

for i in `seq 1 31`
do
    echo $i
done


2. bash에서 순차적 숫자(sequential numbers)

bash 3.0이상 부터는 loop에 순차적 숫자를 사용할 수 있다. 아래는 seq를 썼을 때와 같은 결과가 나온다.

#!/bin/bash

for i in {1..5}
do
    echo $i
done

[ 결과 ]
1
2
3
4
5

bash 4.0이상 부터는 증가치(increment)를 지정할 수 있다.

$ echo {1..10}
1 2 3 4 5 6 7 8 9 10
$ echo {1..10..2}
1 3 5 7 9


3. seq명령과 bash 순차적 표현의 각각의 장점

* seq 명령을 사용할 때 장점

1) 실수형으로 증가할 수 있다.

$ seq 1 .1 10
1.0
1.1
1.2
1.3
1.4
1.5
1.6
... 생략 ...

2) 구분문자를 지정할 수 있다. 기본은 줄바꿈

$ seq -s " + " 1 10
1 + 2 + 3 + 4 + 5 + 6 + 7 + 8 + 9 + 10

* bash에서 순차적 숫자를 쓸 때 장점

1) {01..10} 처럼 지정하면 01 02 03 처럼 앞에 0을 붙여준다. 0001처럼 지정할 수도 있다. (bash 4.0 부터)

$ echo {01..10}
01 02 03 04 05 06 07 08 09 10
$ echo {0001..10}
0001 0002 0003 0004 0005 0006 0007 0008 0009 0010

2) 문자도 순차적으로 출력할 수 있다. {a..z} 나 {A..Z} 처럼

$ echo {a..z}
a b c d e f g h i j k l m n o p q r s t u v w x y z
$ echo {a..z..2}
a c e g i k m o q s u w y


Posted by 좋은진호
시스템이야기2008. 11. 19. 18:40
서버에 접속한 유저가 어떤 명령을 내렸는지 실시간으로 확인하려면 어떻게 해야할까? history file을 뒤진다? 이건 너무 불편하다. 명령이 실행될 때마다 특정이벤트를 발생해서, 별도 저장해주면 효과적일 것이다. 그 것도 syslog를 통해서 명령이 저장된다면 원격지 서버에서 특정 서버의 실행 명령을 모조리 확인해볼 수 있을 것이다.

몇줄의 쉘 function으로 syslog로 실행명령을 보내는 방법을 알아보자.

function logging
{
        stat="$?"
        cmd=$(history|tail -1)
        if [ "$cmd" != "$cmd_old" ]; then
                logger -p local1.notice "[2] STAT=$stat"
                logger -p local1.notice "[1] PID=$$, PWD=$PWD, CMD=$cmd"
        fi
        cmd_old=$cmd
}
trap logging DEBUG

위 스크립트에서 중요한 부분은 logger와 trap이다.

1) logger는 지정한 메시지를 syslog로 보내주는 명령이다.
   위에서는 local1 서비스종류(facility)과 notice 레밸로 syslog로 메시지를 보내준다.
   logger의 활용에 대해서는 '여러 서버의 load를 터미널에서 실시간 모니터링' (글 좋은진호, 2008.2)
   중 '2. 미리 준비되어 있어야할 사항' 부분을 살펴보기 바란다.
2) trap은 bash내부 명령으로 특정시그널이 발생할 때 지정한 명령어가 실행된다.
   형식) trap "명령" 시그널
   위에서는 DEBUG 형태로, 명령이 실행될 때마다 logging function을 호출한다.

위의 스크립트를 global하게 적용하려면 /etc/profile 에 추가하거나 /etc/profile.d/cmd_logging.sh 로 저장하면 된다. 유저별로 적용하려면 $HOME/.bash_profile 또는 $HOME/.bashrc에 넣어둔다. 이제 적용됐는지 로긴해보자.

Sep 30 17:11:32 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:32 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=    7  ls -la
Sep 30 17:11:36 cnx1 coffeenix: [2] STAT=0
Sep 30 17:11:36 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=    8  vi get_stat.sh
Sep 30 17:15:24 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:24 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=    9  chmod 700 get_stat.sh
Sep 30 17:15:28 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:28 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=   10  ./get_stat.sh
Sep 30 17:15:35 cnx1 coffeenix: [2] STAT=0
Sep 30 17:15:35 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=   11  ls
Sep 30 17:16:31 cnx1 coffeenix: [2] STAT=0
Sep 30 17:16:31 cnx1 coffeenix: [1] PID=29168, PWD=/home/coffeenix, CMD=   12  cd /var/log
Sep 30 17:16:32 cnx1 coffeenix: [2] STAT=0
Sep 30 17:16:32 cnx1 coffeenix: [1] PID=29168, PWD=/var/log, CMD=   13  ls

시간표시를 자세히 보면 [2]가 먼저 저장되고, [1]이 그 다음에 저장된다. [2] 는 이전에 실행한 명령의 실행 결과 코드이며, [1]은 방금 실행한 명령이다. 방금 실행한 결과 코드는 다음 명령이 실행되어야 결과로 저장이 된다.

실행명령만 별도 로그로 저장하고 싶다면 /etc/syslog.conf 에 다음을 추가하고, syslogd 데몬을 재실행해주면 된다.

local1.notice                           /var/log/cmd.log

보다 자세한 것은 커피닉스에 써둔 '쉘에서 실행한 명령을 syslog로 자동 보내기'를 살펴보기 바란다.

Posted by 좋은진호