Tag: bash

proxy 설정

음.. proxy 설정이 영 헷갈려서 적어놓는다.

$ export http_proxy=<proxy.server:port>
$ export https_proxy=$http_proxy
$ export no_proxy=google.com,naver.com,daum.net

기록은 기억보다 영원하다.


moinmoin에 지속적으로 계정 생성을 시도하는 ip 차단: 가난한 자의 ddos 방어..

본 서버에 같이 돌아가는 서비스 중에 하나가 moinmoin 입니다. 그냥 혼자 이것저것 정리한 내용들을 두서없이 적는데...

어떤 녀석들이 여기에다가 지속적으로 새로운 계정 생성을 시도하면서 스팸 짓을 합니다. 녜.. 여기 서버는 가상서버에다가 메모리도 1기가로 아주 작아서 이런 요청이 계속 들어오면 apache 프로세스그 많아서서 서버가 엄청 느려집니다.

그래서 해당 ip를 그냥 .htaccess에서 접근차단 하기로 했습니다. 아주 간단하게.~~

이 스크립트를 그냥 crontab에서 돌려 놓으세요~

물론 다른 나이스한 방법이 있겠지만.. 우선 귀찮아서... ^^;


git submodule commit

git으로 작업하면서 야심차게 submodule을 도입해봤습니다. 그런데 서브모듈에서 커밋하는 순간부터 막히기 시작하네요.

원칙으로 한다면 submodule을 커밋 & push하고 parent도 commit & push 해 줘야하겠지요. 근데 submodule을 커밋하려면 해당 모듈이 있는 디렉토리로 이동해서 해야합니다.

$ cd submodule && git commit -m 'this is submodule commit message' -a

하나라면 그런데로 할만한데.. 이게 2개 이상이면 좀 짜증이 나기 시작합니다. 그래서 간단하게 쉘 스크립트를 만들어 해봤지요.

녭.. 이런거 해주는 비슷한 것이 있습니다. git foreach 명령이죠.

$ git submodule foreach git commit -m 'this is submodule commit message' -a

그런데 커밋하면 바로 에러가 납니다. 이유는 서브 모듈 중에서 변경되지 않은, 커밋될 필요가 없는 것은 위의 git commit 명령이 오류를 내면서 정지하기 때문이죠. 그래서 모두 커밋하려면 위에서 처럼 분기가 필요한데.. 이를 foreach와 묶는 것을 한 줄로 처리하기 힘들죠..

그리고 된다고 하더리도 아마도 -m 메시지의 공백때문에 제대로 처리가 되지 않을 겁니다.

Update: gist가 좋아보여서 거기다 스크립트 넣어봤습니다. 괜찮네요.

Update: push하는 것도 적용해봤습니다.


리눅스 배포판 및 버전 확인하기: lsb_release

스크립트 작업할 때 리눅스 배포판을 확인해서 그에 따라서 작업할 경우가 있습니다. CentOS에는 어쩌구.. Ubuntu에서는 어쩌고...

배포판을 확인할 수 있는 명령은 lsb_release인데 man page에 따르면 아래와 같습니다.

FSG lsb_release v2.0 prints certain LSB (Linux Standard Base) and Distribution information.

여기서 주요하게 필요한 것이 --id(CentOS or Ubuntu), --release(5.8, 12.04)이 두가지 인데, CentOS와 Ubuntu에 약간 차이가 있습니다.

CentOS 5.8에서는

$ lsb_release -i -r -s
CentOS 5.8

Ubuntu 12.04에서는

$ lsb_release -i -r -s
Ubuntu
12.04

이를 스크립트에서 활용할 수 있게 tr 명령과 섞으면 아래와 같이 됩니다.

$ /usr/bin/lsb_release -i -r -s | tr "\\n" " " | sed "s/ *\$//g "
Ubuntu 12.04

이제 이를 이용해서 OS에 따른 대응 코드를 만들면..

#!/bin/bash
function get_dist(){
	/usr/bin/lsb_release -i -r -s | tr "\\n" " " | sed "s/ *\$//g "
}

case $(get_dist()) in
	CentOS*)
		SERVICE=/sbin/service
		SERVICE_NAME=network
		;;
	Ubuntu*)
		SERVICE=/user/sbin/service
		SERVICE_NAME=networking
		;;
	*)
		fatal "Not supported platform"
esac

$SERVICE $SERVICE_NAME restart

끄읏~


bash getopts

bash에서는 쉘 스크립트 옵션 처리를 위해서 getopts가 제공됩니다. (주의: getopt 명령과 다름)

#!/bin/bash
while getopts "ha:" opt; do
    case $opt in
        h)
            echo "h option"
            ;;
        a)
            echo "a option=$OPTARG"
            ;;
        \?)
            exit;
            ;;
    esac
done

shift $((OPTIND-1))
echo "나머지 인자: $@"

실행하는 것을 ㅂ면

$ bash opttest.sh -h -a args hello
h option
a option=args
나머지 인자: hello

간단하지요.

getopts는 bash의 builtins으로 간단한 옵션을 처리하는 것이므로 몇가지 제공하지 않는 기능이 있습니다.

  • 긴 옵션을 지원하지 않음: $ opttest.sh --long_options 안됨
  • 옵션이 뒤에 나올 수 없음: $ opttest.sh filename -h 지원하지 않음...

이런 기능을 사용하려면 getopt 명령을 사용하면 되지만... 뭔가 정말로 복잡~ 쉘 스크립트니깐 간단하게 getopts를 사용하는 것을 권장합니다.

참고: http://wiki.bash-hackers.org/howto/getopts_tutorial


OSX에서 bash auto competition 사용하기..

MacBook을 이제 메인으로 쓰면서 Ubuntu에서 자연스럽게 되된 bash의 자동완성이 안되서 불편한 점이 있습니다. 그래서 간단히 찾아서 설정해봤군요.

먼저 Homebrew를 이용해서 bash completion 패키지를 설치하여 자동완성 지원 파일들을 설치합니다.

$ brew install bash-completion

이제 ~/.bash_profile에 다음 라인을 추가하여 자동완성이 되도록합니다.

if [ -f /usr/local/etc/bash_completion ]; then
        . /usr/local/etc/bash_completion
fi

자.. 다시 쉘을 열고 "ssh "를 입력한 다음에 탭을 두번 누르면 자동완성으로 .ssh/config, .ssh/known_hosts에 있는 호스트들이 쫘악~~

끄읏~


ec2 instance start/ stop scripts

클라우드 관련 일을 하니 역시나 사실상 표준인 ec2를 분석할 일이 생겼고, 인스턴스를 만들고 하는 일이 생겼습니다. 콘솔에서 작업하는 것이 너무 귀찮아서 간단하게 모든 region의 instance에 대해서 start/ stop/ status를 보는 스크립트를 만들어봤네요.

물론 이런 일을 해주는 뭔가가 있겠지만, 아주 간단한 일이라 찾는것도 귀찮아서...

#!/bin/bash
export EC2_PRIVATE_KEY=<YOUR EC2 PRIVATE KEY FILE HERE>
export EC2_CERT=<YOUR EC2 CERT FILE HERE>

this=$0
cmd="$1"
shift

function check_expire(){
	f=$1
	EXPIRETIME=$2

	[ ! -f $f ] && return

	NOW=`date +%s`                              # get current time
	FCTIME=`stat -c %Y ${f}`                    # get file last modification time
	let "AGE=$NOW-$FCTIME"
	if [[ $AGE -gt $EXPIRETIME ]] ; then
		rm -f $f                                # this file age is more than the EXPIRETIME above, we can delete it
	fi
}

case "$cmd" in
	stop)
		$this | while read region instance etc; do
			ec2-stop-instances --region $region $instance
		done
		;;

	start)
		$this | while read region instance etc; do
			ec2-start-instances --region $region $instance
		done
		;;

	regions)
		let expire_time=60*60*24*7	# expire in a week
		region_cache='/var/tmp/ec2-region-cache'
		check_expire $region_cache $expire_time

		if [ ! -f $region_cache ]; then
			ec2-describe-regions | awk '{print $2}' > $region_cache
		fi

		cat $region_cache
		;;

	*)
		for region in `$this regions`; do
			ec2-describe-instances --region=$region | grep INSTANCE | awk "{print \"$region \" \$2 \" \" \$4 \" \" \$6}"
		done
		;;
esac

흠.. ec2 api .. 엄청 느리군요.. ㅡㅡ


bash: simple job control

bash에서 child process를 돌릴 필요가 생겨서 잠깐 테스트 삼아 작성해본 background로 프로세스 돌리고, 죽이기 스크립트

#!/bin/bash
set -m

function sig_int(){
        echo "sig_int"

        kill `jobs -p`
}

function child_process() {
        echo "enter child pid:$$, $1"
        sleep 5
        echo "exit someting $1"
}

# run several jobs
for x in {1..3}; do
        #(something $x &) # parallel executation
        child_process $x & # background executation
done

trap sig_int SIGINT

wait

* $$는 shell의 pid로 child process에서 같은 값이 나온다.
* parallel executation은 child process가 아닌 현재 스크립트와 동일한 레벨로 생성된다.


fork(?) in bash

shell script에서 fork와 비슷한 같은 작업을 하는 것은 간단하다. 함수를 호출뒤에 &를 넣어주면 되니깐... 이게 정확하게 fork와 같은 역할을 하는 지는 잘 모르겠지만, 비슷한 역할을 한다.

#!/bin/bash
function foo() {
    echo "function foo $1"
    sleep 5
    echo "exiting foo $1"
}

for x in {1..5}; do
    foo $x &
done

echo 'waiting...'
wait

foo 함수를 5개 호출하면서 child process로 호출하고, parent에서는 child process가 종료할 때 까지 기다린다. 다음은 실행 결과

$ bash fork.sh
function foo 1
function foo 2
waiting...
function foo 3
function foo 5
function foo 4
exiting foo 1
exiting foo 4
exiting foo 3
exiting foo 5
exiting foo 2

이걸 어디에 사용하냐구요? 그래요 snapshot를 뜨는데, 하나하나 하기가 너무 느려서 백그라운드로 돌릴려구요.. 잘 될려나..


shell script: “set -e”가 뭐하는 것일까?

쉘 스크립트를 보면 시작부분에 아래와 같은 문장이 있는 것을 자주 확인할 수 있다.

set -e

그냥 무심결에 넘겨왔었는데, 오늘 찾아봤다.  http://julipedia.meroh.net/2010/01/set-e-and-set-x.html

내용은 간단하다. set -e로 설정되어 있으면 쉘 스크립트가 실행될 때 모든 라인의 실행 결과를 검사해서 실패할 경우는 바로 스크립트 실행을 종료한다.

예를들어 아래의 스크립트를 보면

#!/bin/sh
set -e
echo 'hello'
false               # 여기서 스크립트 실행이 끝남..
echo 'world'

그냥 hello만 출력하고 실행을 끝낸다.

그리고 set -x는 trace로 shell이 실행하는 모든 명령을 화면에 출력한다. 디버그용으로 좋겠다.


  • Copyright © 1996-2010 Your wish is my command. All rights reserved.
    iDream theme by Templates Next | Powered by WordPress