#!/bin/sh
#####################################
# 전월의 로그 백업 20100701 by Donz
#####################################
echo "*** start backup ***";

eval `date "+day=%d; month=%0m; year=%Y"`
month=`expr $month - 1`
if ((month == 0)) ;then
  year=`expr $year - 1`
  month=12
fi

echo $year
echo $month

exit 0

쉘 프로그램의 제어문 : expr

1. expr 제어문

    Bourne Shell에서 모든 변수들은 문자열 type으로 처리된다.
    따라서 문자열들의 연산은 불가능하기 때문에 변수들의 연산은 불가능하다.
    그러나 Buorne Shell은 수학적 등식을 사용하여 문자열의 수학적 연산을
    수행할 수 있는 방법은 제공한다.
    이런 연산은 Bourne Shell의 expr 명령어를 이용하여 수행할 수 있다.

    expr 명령어는 수학식과 같이 그들의 인자들을 계산하고, 표준출력 장치에
    결과를 출력한다. 이 expr 명령어는 쉘 변수들의 연산을 수행하기 위해 아주
    빈번히 사용된다. expr 명령어에서 이용 가능한 연산자는 다음과 같다.

         +    더하기
         *    곱하기
         %    나머지 나누기
         -빼기
         /    나누기

    expr 명령어상에 위의 연산자들을 사용할 경우에는 연산자의 전후에
    반드시 공백을 지정해야 한다.

    expr 명령어상에서 첫번째 인자와 두번째 인자를 비교할수 있는 일치(match)
    연산자인 :도 사용할 수 있다. 그러나 이 연산자를 사용할 경우에,
    두번째 인자로는 반드시 정규 표현식을 지정해야만 한다.
    : 연산자의 연산 결과로 정규 표현식으로 지정된 문자와 일치된 문자수가
    돌려지거나 또는 일치하는 것이 없을 경우에는 0 값이 되돌려진다.
    모든 문자를의미하는 .*라는 정규 표현식을 이용하면은, 일치 연산자를
    사용하여 지정된 첫번째 인자의 인자의 길이 즉, 문자수를 확인할 수 있다.

         (주목) 역따옴표(`)로 둘러쌓인 연산식이 실행되면, 명령어의 결과가
              명령어 자체를 대치한다. 그리고 연산식내에 사용된 $ 또는 * 같은
              연산자는 expr 명령어에 처리되기 앞서 쉘에의해서 먼저 분석되기
              때문에 엉뚱한 결과를 초래할 수 있다. 이와같은 경우 사용된
              연산자를 쉘이 번역하지 못하도록 보호문자인 \를 연산자 앞에
              지정해야 한다.

    다음은 expr 명령어를 사용한 예이다.

    ┌─────────────────────────────────┐
    │ myprog                                                           │
    ├─────────────────────────────────┤
    │ a=`expr 1 + 2`        # expr 명령어의 실행 결과가 변수에 설정.   │
    │ b=`expr $a \* 4`      # *는 쉘 특수문자임으로 이를 expr 명령어의 │
    │ echo $a $b  # 인자 즉, 연산자로 전달하기 위해 \를 지정.          │
    └─────────────────────────────────┘

    $myprog
    3 12
    $VAR="Now is the time"
    $expr "$VAR" : '.*'        <----(1)
    15

    (1)번에 지정되어 있는 expr 명령어를 유심히 관찰해야 한다.
    이 예는 VAR 변수에 설장된 문자열의 문자수를 계산하기 위해
    expr 명령어를 : 연산자를 사용하여 지정하고 있다.
    그런데 변수의 참조인 첫번째 인자에 대해 쌍따옴표가 (") 지정되어 있다.
    그것은 변수 VAR에 설정되어 있는 공백을 쉘이 제거하지 못하도록 하기
    위함이다. 두번째 인자로 '.*' 라는 정규 표현식을 지정함으로써 첫번째
    인자로 지정된 변수의 문자수(공백 포함)를 계산하도록 하고 있다.

2. Korn Shell에서의 연산

    expr 명령어는 Bourne Shell에서 수행됐던 것처럼 Korn Shell에서도
    동일한 기능을 수행한다. 이전 강의에서 Korn Shell에는 문자열 type의
    변수 이외의 변수 type을 선언할수 있는 typeset 명령어에 대해 소개했다.

    이 기능말고도 Korn Shell에서는 연산을 수행할수 있는 let과 ((...))라는
    두가지의 추가 명령어를 제공한다. 이들 명령어의 형식은 다음과 같다.

              let expression
              ((expression))

    이들 두가지 명령어의 차이점을 설명하면 다음과 같다.

    ┌───┬────────────────────────────┐
    │      │ expression상에 특정한 쉘 특수문자를 사용할 경우에는    │
    │      │ 보호문자로 묶어주어야 한다.                            │
    │let   ├────────────────────────────┤
    │      │ expression상에 변수를 지정시 변수명 앞에 $를 기술할    │
    │      │ 필요가 없다.                                           │
    ├───┼────────────────────────────┤
    │      │ expression상에 사용된 쉘특수문자를 보호할 필요가 없다. │
    │      │                                                        │
    │((..))├────────────────────────────┤
    │      │ expression상에 사용된 변수에 $ 문자를 지정할 필요가    │
    │      │ 없다.                                                  │
    └───┴────────────────────────────┘

    명령어의 형식에서 expression은 변수, 상수 또는 변수 제어문을 지정할 수
    있으며, 또한 expression은 수학식, Boolean 연산식, 비트 연산식등을
    이용하여 기술할 수 있다.
    연산식에 지정 가능한 연산자들은 다음과 같다.

  ┌─────────────┬─────────────────────┐
  │ 연산자                   │  수행내용                                │
  ├─────────────┼─────────────────────┤
  │ (expression)             │ Override precedence.                     │
  ├─────────────┼─────────────────────┤
  │ -expression              │ 음수                                     │
  ├─────────────┼─────────────────────┤
  │ lexpression              │ 논리적 부정                              │
  ├─────────────┼─────────────────────┤
  │ expression * expression  │ 수학적 연산                              │
  │ expression / expression  │                                          │
  │ expression % expression  │                                          │
  │ expression + expression  │                                          │
  │ expression - expression  │                                          │
  ├─────────────┼─────────────────────┤
  │ expression << expression │ 두번째 expression에 지정된 비트수만큼    │
  │ expression >> expression │ 좌/우측으로 첫번째 expression에 지정된   │
  │                          │ 값을 shift한다.                          │
  ├─────────────┼─────────────────────┤
  │ expression <= expression │ Boolean expressions (왼쪽에서 오른쪽으로)│
  │ expression >= expression │ expression의 값이 0이 아니면 1           │
  │ expression < expression  │      그렇지 않으면 0이다.                │
  │ expression > expression  │                                          │
  │ expression == expression │                                          │
  │ expression != expression │                                          │
  ├─────────────┼─────────────────────┤
  │ expression && expression │ 논리적 AND                               │
  │ expression || expression │ 논리적 OR                                │
  ├─────────────┴──────┬──────────────┤
  │ identifier = expression                │ 할당 연산자                │
  │ identifier = identifier op expression  │                            │
  └────────────────────┴──────────────┘

    다음은 let과 ((..)) 명령어의 예제는 다음과 같다.

    KORN> let x=10*3    # 10 * 3 즉, 30이 변수 x에 설정된다.
    KORN> echo $x
    30
    KORN> ((z=x/2))     # 30 / 2 즉, 15가 z에 설정된다.
    KORN> echo $z
    15
    KORN> let z=x/2     # 30 / 2 즉, 15가 변수 z에 설정된다.
    KORN> echo $z
    15
    KORN> let y=x\ echo $y
    1
    KORN> if (($x < z)) # x가 z보다 적으면 then 문을 그렇지 않으면 else문을
    >then               # 실행한다.
    >   echo x \> z
    >   echo $x \< $z
    >else
    >   echo x is not \< z
    >   echo $x \> $z
    >fi
    x is not < z
    30 > 15



※ 이거 짜다가 머리털 뽑히는 줄 알았다..  뺑이쳤다
아뭏든 이래저래 하다보니 목적은 달성했다.

좀 가다듬어야 하는디...
# locale을 한글로
export LANG=ko_KR.eucKR

# 날짜 중 단자리의 날짜에서 0 떼어내기

DATE=`expr \`date +%d\` + 1 - 1`

# 달력 프로그램에서 년도 표시줄 떼고 요일 표시줄 떼고

cal | grep -v `date +%Y` | grep -v 월 > ./DAL

# 첫 칼럼에 ' ' 필요

sed 's@^@ @g' ./DAL > ./DAL2

# 마지막 칼럼에 ' ' 필요

sed 's@$@ @g' ./DAL2 > ./DAL

# awk로 매치되는 라인이 나올 때까지 if loop

awk '{ if ( $0 ~ / '"${DATE}"' / ) print NR }' ./DAL

쉘 스크립트에서 sqlplus 스크립트를 이용하기

쉘 스크립트안에서 sqlplus 스크립트를 실행하는 방법에 대한 팁이다.
이 팁은 데이터베이스 값을 쉘 변수로 전달하는 방법과 쉘 스크립트를
좀더 다이나믹하게 만들어주는 예이다. 어떤 사람들에게는 기초적인
것 일수 있으나 다른 사람들에게 도움이 되기 바란다. 문법은 다음과 같다:

#!/bin/sh
dummyvar=`sqlplus -s username/password  <<end
set pagesize 0 feedback off ver off heading off echo off
select  sysdate from dual;
exit;
end`
echo "system date is " $dummyvar
#end of shell script

이 예제는 오라클에서 시스템의 날짜를 받아오는 것이지만 여러분들이
데이터베이스에서 원하는 정보를 가져와 쉘 변수에 넣도록 select
스 크립트를 확장하는 방법에 대한 아이디어를 얻을 수 있다.

리눅스 에서 하루전 의 날짜 출력

YESTERDAY=$(date +%Y%m%d --date '1 days ago')
echo $YESTERDAY
20100504

unix 에서 어제 날짜 가져오기

YESTERDAY=`TZ=GMT+15 date +%Y%m%d`; echo $YESTERDAY
20100504


YESTERDAY=`TZ=KST+15 date +%Y%m%d`; echo $YESTERDAY

*. 추가 사항

일반적으로 알고 있는 그리니치 기준 동경(+), 서경(-)로 생각하면 정 반대의 계산이 됨.. 반대 부호로 생각해야됨.. 삽질했음..

우리나라의 경우 표준 시간대가 'GMT+9'이므로, 하루 전을 계산하기 위해선 TZ=GMT+24가 아니라 TZ=GMT+15임.


어제 날짜 구하는 shell source
OFFSET=${1:-1}
case $OFFSET in
  *[!0-9]* | ???* | 3? | 29) print -u2 "Invalid input" ; exit 1;;
esac
eval `date "+day=%d; month=%m; year=%Y`
typeset -Z2 day month
typeset -Z4 year
day=$((day - OFFSET))

if (( day &lt= 0 )) ;then month=$((month - 1)) if (( month == 0 )) ;then year=$((year - 1)) month=12 fi set -A days `cal $month $year` xday=${days[$(( ${#days[*]}-1 ))]} day=$((xday + day)) fi
PRE_DATE=$year$month$day echo $PRE_DATE

설명

여기서 첫번째 줄....

OFFSET=${1:-1} 
이녀석의 의미
${var:-aaa} 는 $var 가 정의되지 않았다면 aaa 값이 된다는 것 같습니다.
따라서 ${1:-1} 은 shell script의 첫번째 아규먼트가 없다면 1을 쓰라는 말인 것으로 생각되네요. 다시 말하면 아규먼트를 안 주고 프로그램을 실행시키면 default 값으로 1을 쓰라는 말인 것 같습니다. 아규먼트가 주어졌다면 그것이 사용되고요.

${parameter:-word}
If parameter is unset or null, the expansion of word is substituted. Otherwise, the value of parameter is substituted

$1이 unset or null이면 -1로 설정을 ... 아니면 그냥 그대로 ..












+ Recent posts