'Shell Script'에 해당되는 글 4건

  1. 2014.05.20 mplayer 이어서 보기 스크립트. (2)
  2. 2012.10.19 간단하지만 유용한 쉘스크립트. (2)
  3. 2008.02.04 쉘스크립트 하는데 (7)
  4. 2007.06.18 압축플때 쓰는 쉘 스크립트 (4)

mplayer 이어서 보기 스크립트.

몇일동안 써 봤는데 별 문제는 없네요.


(뭐 생기면 고치면 되고...)


원리를 간단하게 설명하자면.


1,mplayer를 터미널상에서 재생시키면, 현재 재생중인 위치가 가장 마지막 위치에 나옵니다.


2, 재생전에 로그파일에 정보가 있는지 확인하고, 있으면 그곳을 시작위치로 저장해서 mplayer를 재생.


3, 이후 계속 출력 메세지를 받아놓고,


4, mplayer가 종료되면 로그의 가장 마지막줄을 읽어서 끝난 위치를 알아내는 거죠.


5, 그리고 난 다음, 로그파일에 정보가 없으면 새로운 로그 라인에 (기록초, 파일경로) 추가, 있으면 수정합니다.


(사실 원래는 중간에 메세지를 가로채서 파이프로 보내려고 했습니다만, 아무래도 뻘짓같아서...  포기하고 있다가 AUR에 mplayer-resumer(https://aur.archlinux.org/packages/mplayer-resumer/) 패키지를 보고 힌트를 얻어서 작성. (대체 왜 나는 쓸데없이 복잡한 방법을 생각해 냈을까?)


동영상 길이도 검사해서 맨뒷부분에서 exit시에는 기록을 하지 않게 만들어 놓았습니다.


저는 mplayer를 slave mode(외부에서 파이프로 mplayer 제어) 로도 사용하기 때문에 파이프를 설정하는 옵션도 들어갔습니다만, 필요없으면 없애주세요.


길이만 길다뿐이지 별거 아닙니다. 그럼 코드.


#!/bin/bash


# 필요 패키지 : bash, mplayer, ffmpeg, perl, 기타 쉘 관련 유틸리티
MPLAYER_PATH="/home/lowid/bin/mplayer"
MPLAYER_PIPE_PATH="/tmp/mplayer_pipe"
MPLAYER_LOG_FILEPATH="/share/ani/.mplayer_position.log"

# 키 후킹법 => 실패.
#while [ 1 ];do read -n 1 CMD >/dev/null;HEX="$(echo -n "$CMD" | hexdump -e \"%d\")";echo "key_down_event $HEX" > /tmp/mplayer_pipe;done
export MPLAYER_STATUS_OK_END=0
export MPLAYER_STATUS_OK_PLAYING=1
export MPLAYER_ERROR_NOT_PLAY_FILE=2
export MPLAYER_ERROR_LOG_POSITION_GET=3
export MPLAYER_ERROR_PLAYING=4

# mplayer에서 재생할 파일경로와 옵션을 분리해 냅니다
# 주의 : 각 인자를 확장자를 기준으로 분류합니다. (파싱 오류 가능성 있음!)
function Option_Parse()
{
    local Param=""
    unset OPTION_PARSE_RETURN_FILEPATH
    unset OPTION_PARSE_RETURN_OPTIONS

    for Param in "$@";do
        if [ "$(echo "$Param" | grep -E "\.mpg|\.wvx|\.rmvb|\.avi|\.mkv|\.wmv|\.mp4")" ];then

            OPTION_PARSE_RETURN_FILEPATH="$(realpath "$Param")"
        else
            OPTION_PARSE_RETURN_OPTIONS=""$OPTION_PARSE_RETURN_OPTIONS" "$Param""
        fi
    done
}

function Mplayer_Play_Duration()
{
    local Play_filepath="$1"
    local Play_file_duration=""
    local Hour=0
    local Minute=0
    local Second=""
    unset MPLAYER_PLAY_DURATION_RETURN_SECOND

    if [ ! -f "$Play_filepath" ];then
        return 1
    fi

    Play_file_duration="$(ffmpeg -i "$Play_filepath" 2>&1 | grep '^\s*Duration: [0-9][0-9]:[0-9][0-9]:[0-9][0-9]' | perl -pe 's/^.*?\: //g,s/\..*$//g')"
    Hour="$(echo "$Play_file_duration"   | cut -d ':' -f1 | perl -pe 's/^0//g')"
    Minute="$(echo "$Play_file_duration" | cut -d ':' -f2 | perl -pe 's/^0//g')"
    Second="$(echo "$Play_file_duration" | cut -d ':' -f3 | perl -pe 's/^0//g')"

    MPLAYER_PLAY_DURATION_RETURN_SECOND=$(($Hour * 60 * 60 + $Minute * 60 + $Second))

    return 0
}

function Mplayer_Log_Position_Get()
{
    local Play_filepath="$1"
    local Log_filepath="$2"
    local Log_play_file_line=""
    MPLAYER_POSITION_GET_RETURN_PLAY_SECOND=0

    if [ ! -f "$Play_filepath" ];then
        return 1
    fi

    if [ ! -f "$Log_filepath" ];then
        touch "$Log_filepath"
    fi

    Log_play_file_line="$(fgrep -n "$Play_filepath" "$Log_filepath" | cut -d ':' -f1 2>/dev/null)"
   
    if [ -n "$Log_play_file_line" ];then
        MPLAYER_POSITION_GET_RETURN_PLAY_SECOND="$(sed -n "$Log_play_file_line"'p' "$Log_filepath" | cut -d ' ' -f1)"
    fi

    return 0
}

function Mplayer_Log_Position_Set()
{
    local Play_filepath="$1"
    local Play_second="$2"
    local Log_filepath="$3"
    local Log_play_file_line=""
    local Log_play_file_data=""
    local Temp_filepath="/tmp/mpp_$RANDOM"

    if [ ! -f "$Play_filepath" ];then
        return 1
    fi

    if [ -z "$Play_second" ];then
        return 2
    fi

    if [ ! -f "$Log_filepath" ];then
        return 3
    fi

    Log_play_file_line="$(fgrep -n "$Play_filepath" "$Log_filepath" | cut -d ':' -f1 2>/dev/null)"
   
    # 없으면 뒤에 쓰고, 없으면 치환.
    if [ -z "$Log_play_file_line" ];then
        echo "$Play_second" "$Play_filepath" >> "$Log_filepath"
    else
        Log_play_file_data=""$Log_play_file_line"c "$Play_second" "$Play_filepath""
        sed -e "$Log_play_file_data" "$Log_filepath" > "$Temp_filepath"
        mv -f "$Temp_filepath" "$Log_filepath" 2>/dev/null
    fi

    return 0
}

function Mplayer_Log_Position_Delete()
{
    local Play_filepath="$1"
    local Log_filepath="$2"
    local Log_play_file_line=""
    local Temp_filepath="/tmp/mpp_$RANDOM"

    if [ ! -f "$Play_filepath" ];then
        return 1
    fi

    if [ ! -f "$Log_filepath" ];then
        return 2
    fi

    Log_play_file_line="$(fgrep -n "$Play_filepath" "$Log_filepath" | cut -d ':' -f1 2>/dev/null)"

    if [ -z "$Log_play_file_line" ];then
        return 3
    fi

    sed -e "$Log_play_file_line"'d' "$Log_filepath" > "$Temp_filepath"
    mv -f "$Temp_filepath" "$Log_filepath" 2>/dev/null

    return 0
}

function Mplayer_Play_Continue()
{
    local Options="$1"
    local Play_filepath="$2"
    local Play_position_second="$3"
    local Play_backward_second="$4"
    local Mplayer_end_second=""
    local Mplayer_start_position_second=""
    unset MPLAYER_PLAY_RETURN_POSITION

    if [ ! -f "$Play_filepath" ];then
        return 1
    fi

    if [ -z "$Play_position_second" ];then
        return 2
    fi

    if [ -z "$Play_backward_second" ];then
        return 3
    fi

    # mplayer 경로는 전역임 주의, -ss옵션에 0이 들어가도 상관 없다
    Mplayer_end_second="$("$MPLAYER_PATH" $Options -ss "$Play_position_second" "$Play_filepath" 2>/dev/null | strings | tail -2 | egrep '^A:' | perl -pe 's/^A:\s*//g,s/ V:.*//g')"

    if [ -z "$Mplayer_end_second" ];then
        return 4
    fi

    Mplayer_start_position_second="$(echo "$Mplayer_end_second" | cut -d '.' -f1)"
    if [ -z "$Mplayer_start_position_second" ];then
        return 5
    fi

    MPLAYER_PLAY_RETURN_POSITION="$(($Mplayer_start_position_second - $Play_backward_second))"
}

function Mplayer_Pipe()
{
    local Play_filepath="$1"
    local Pipe_path="$2"
    local Pipe_option=""
    unset MPLAYER_PIPE_RETURN_OPTION

    # mkv는 fifo 사용이 불가능한듯함
    if [ -z "$(echo "$Play_filepath" | grep \.mkv)" ];then
        if [ "$(file "$Pipe_path" | cut -d ' ' -f2)" != "fifo" ];then
            mkfifo "$Pipe_path"
        fi

        Pipe_option="-slave -input file="$Pipe_path""
    fi

    MPLAYER_PIPE_RETURN_OPTION="$Pipe_option"
}

function Mplayer()
{
    local Play_filepath=""
    local Options=""
    local Played_position_second=""
    local Restart_backword_second=2
    local Playing_position_second=""
    local Playing_file_duration=""
    local Restart_last_second=10
    local Return_succeed_value=0

    Option_Parse "$@"
    Play_filepath="$OPTION_PARSE_RETURN_FILEPATH"
    Options="$OPTION_PARSE_RETURN_OPTIONS"

    if [ -z "$Play_filepath" ];then
        return $MPLAYER_ERROR_NOT_PLAY_FILE
    fi

    Mplayer_Pipe "$Play_filepath" "$MPLAYER_PIPE_PATH"
    Options=""$Options" "$MPLAYER_PIPE_RETURN_OPTION""

    Mplayer_Log_Position_Get "$Play_filepath" "$MPLAYER_LOG_FILEPATH"
    if [ $? != 0 ];then
        return $MPLAYER_ERROR_LOG_POSITION_GET
    fi

    Played_position_second="$MPLAYER_POSITION_GET_RETURN_PLAY_SECOND"

    Mplayer_Play_Continue "$Options" "$Play_filepath" "$Played_position_second" "$Restart_backword_second"
    if [ $? != 0 ];then
        return $MPLAYER_ERROR_PLAYING
    fi

    Playing_position_second="$MPLAYER_PLAY_RETURN_POSITION"

    # 동영상의 재생 길이를 알때에만 기록을 한다.
    Mplayer_Play_Duration "$Play_filepath"
    if [ $? = 0 ];then
        Playing_file_duration="$MPLAYER_PLAY_DURATION_RETURN_SECOND"

        if [ $(($Playing_position_second + $Restart_last_second )) -lt "$Playing_file_duration" ];then
            Mplayer_Log_Position_Set "$Play_filepath" "$Playing_position_second" "$MPLAYER_LOG_FILEPATH"
            Return_succeed_value=$MPLAYER_STATUS_OK_PLAYING
        else
            Mplayer_Log_Position_Delete "$Play_filepath" "$MPLAYER_LOG_FILEPATH"
            Return_succeed_value=$MPLAYER_STATUS_OK_END
        fi
    fi

    return $Return_succeed_value
}


따로 설정할수 있는 부분은 전역으로 빼놨으니까 수정하시기 편할거에요.


ps; ~/.bashrc에 다음과 같이 쓰시길 추천. 아니면 따로 빼서 쓰시던지요.

alias mp='. /path/Mplayer.sh;Mplayer'




신고
trackback 0 Comment 2

간단하지만 유용한 쉘스크립트.

엄청나게 간단하지만, 꽤 쓸만한 녀석들 모음입니다.


소스는 하도 간단해서 별로 설명할것도 없네요...


첫번째 스트립트는 터미널 영한사전처럼 간단하게(앞부분만) 위키 내용을 보여주는것.


다음 상황에서 문제가 발생하긴 해요...


1, 동의어가 발생했을때

(뭐, 이럴경우는 그냥 웹브라우저로 연결해서 보면 되긴 합니다)

2, 느리다. 특히 데이터가 많은 페이지일 경우...

(모바일페이지를 read하면 속도 향상이 있긴하겠지만, 귀찮아서...)

3, 사전에 단어가 별로 없다

(위키백과라고 해도, 단어수만 따지자면 백과사전(책)에 비해서 단어수가 후달려서 그런지 검색안되는 단어가 좀 있습니다)


[~/bin/script]$ cat wikipedia_ko.sh

#!/bin/bash

# 위키페이지는 공백대신 언더바를 쓴다
PAGE_NAME="$(echo "$*" | tr -s ' ' '_')"
LINK="http://ko.wikipedia.org/wiki/"$PAGE_NAME""
LINK_LIST_FILEPATH='/tmp/wiki_page'
BROWSER='firefox'
WIDTH=100

clear
echo '페이지 다운로드중 잠시만 기다려 주세요.'
wget "$LINK" -O "$LINK_LIST_FILEPATH" -q
clear

RESULT_DATA="$(cat "$LINK_LIST_FILEPATH" | egrep '<p>.*?<b>' | grep -v ^\\[ | head -1 | tr -d '\t' | perl -pe s/\<.*?\>//g | fmt -w "$WIDTH")"
if [ -n "$RESULT_DATA" ];then
    echo "$RESULT_DATA"
    echo
    echo "URL : "$LINK""
    echo -n '웹 브라우저에서 보시려면 <<v>> 키를 눌러주세요.'
    read -n 1 CHECKER
    echo
    if [ "$CHECKER" = 'v' ];then
        "$BROWSER" "$LINK" 1>/dev/null 2>/dev/null &
    fi
fi

rm -rf "$LINK_LIST_FILEPATH"



두번째 스크립트는 검색어/지도에서위치를 검색하는 역활을 하는겁니다.


구조는 더 간단합니다. 걍 url에 쿼리날리면 끝.


구글이나 네이버말고 다른 url query를 알면 그냥 붙여넣기 해서 쓰면 되겠죠...


일단 저는 아는게 2개밖에 없어서 일단 이렇게 만들어 봤어요.


[~/bin/script]$ cat direct_url.sh 

#!/bin/bash

BROWSER='firefox'

GOOGLE_FELLING_LUCKY_URL="http://www.google.com/search?ie=utf8&lr=lang_ko&btnI=&q="
NAVER_MAP_URL='http://map.naver.com/?query='
BASE_URL=""

while getopts 'g:m:' Option;do
    case $Option in
        g )
            BASE_URL="$GOOGLE_FELLING_LUCKY_URL"
            PARAM="$OPTARG"
            ;;
        m )
            BASE_URL="$NAVER_MAP_URL"
            PARAM="$OPTARG"
            ;;

        * )
            echo 'Usage >'
            echo ""$0" -g Query String : Google Feeling Lucky를 이용해 다이렉트 점프!"
            echo ""$0" -m Query String : Naver Map을 이용해서 주변을 검색합니다"
            ;;
    esac
done

"$BROWSER" "$BASE_URL""$PARAM" 1>/dev/null 2>/dev/null &


alias에서 터미널에서 바로 검색하면 정말 편하더군여

$go 네이버 메일

이런식으로 하면 LastPass랑 연동되서 바로 이메일 확인도 할수 있고...


$map 구청

이러면 집주변의 구청위치도 알수 있고...


여튼 일일이 브라우저 열어서 검색하고 귀찮게 안하고 명령어 한줄로 끝낼 수 있다는게 굉장이 편리해요...


ps; 네이버 open API를 사용하면 인기검색어 뷰어같은 괴상망측(...)한것도 만들수 있습니다..

http://dev.naver.com/openapi/apis/search/rank

저도 만들긴 했는데 별 쓸모는 없더군요... 그냥 심심했을때 한번 쳐보는 거 정도...


이외에도 많이 있긴한데, 나머지는 xml 파싱하는 스크립트도 넣어야 해서 귀찮아서 그냥 이정도로.

신고
trackback 0 Comment 2

쉘스크립트 하는데

졸라 어렵네  ㅜㅜ

차라리 C로 파이프 써서 하는게 더 쉽겠다 (............)

맨날 C 만 해댓더니만 그쪽으로 아예 머리가 굳어버린듯 (............)

무서운데............ 이러다 딴것도 못배우는거 아녀 ;;

이거 모르는거 하나하나 언제 다 찾아가면서 하나...
신고

'Programming' 카테고리의 다른 글

nasm include  (0) 2009.01.26
qt, arm 보드에 포팅방법  (6) 2008.12.05
쉘스크립트 하는데  (7) 2008.02.04
간만에 포스팅.. 소스 고치기!  (2) 2007.10.17
Nanika를 써보고 나는 생각들  (5) 2007.06.16
X!!- key_grab  (2) 2007.02.26
trackback 0 Comment 7

압축플때 쓰는 쉘 스크립트

 1 #!/bin/bash
 2
 3 # 지원하는 파일들은 다음과 같습니다
 4 # zip,alz,rar,tar.gz,tar,tar.bz2,gz,tgz
 5 # 물론 unalz,unzip,unrar,tar등이 설치되어 있어야 합니다
 6 # (첫번째 인자의)파일의 확장자를 찾아내서 처리합니다..
 7
 8 # IFS 인자를 백업후 .을 IFS인자로 설정
 9 OLD_IFS=$IFS
10 IFS='.'
11
12 # 첫번째 인자를 변수에 넣고 .을 간격자로한 갯수를 구한다
13 ARG1=($1)
14 ARRAY_SIZE=$(expr ${#ARG1[*]} - 1)
15
16 if (( $ARRAY_SIZE == -1));then
17     echo "인자가 부족합니다.."
18     echo "사용법 : $0 파일명 (압축을 )경로"
19     exit 1
20 fi
21
22 # 파일의 확장자를 정한다 (맨뒤에꺼만 아면 된다
23 # tar.gz같은경우도 gz면 되기때문에 맨마지막만 검사한다
24 if [ "${ARG1[$ARRAY_SIZE]}" = "zip" ];then
25     EXTENSION="zip"
26 elif [ "${ARG1[$ARRAY_SIZE]}" = "rar" ];then
27     EXTENSION="rar"
28 elif [ "${ARG1[$ARRAY_SIZE]}" = "alz" ];then
29     EXTENSION="alz"
30 elif [ "${ARG1[$ARRAY_SIZE]}" = "tar" ];then
31     EXTENSION="tar"
32 elif [ "${ARG1[$ARRAY_SIZE]}" = "gz" ];then
33     EXTENSION="gz"
34 elif [ "${ARG1[$ARRAY_SIZE]}" = "tgz" ];then
35     EXTENSION="tgz"
36 elif [ "${ARG1[$ARRAY_SIZE]}" = "bz2" ];then
37     EXTENSION="bz2"
38 else
39     echo "지원되지 않는 압축파일입니다 확장자를 확인해 주세요!"
40     echo "지원되는 압축파일 : ZIP,RAR,ALZ,TAR,GZ(or tar.gz),BZ2(or tar.bz2)"
41     exit 1
42 fi
43
44 # IFS를 복원
45 IFS=$OLDIFS
46
47 # IFS를 복원했기때문에 원래 인자들이 대입된다
48 # 그리고 전체 인자 갯수를 구해서, 압축을 풀
49 # 장소가 command 에 있는지 검사하고 실행한다
50 ARG1=($1)
51 ARG2=($2)
52 ARG_NUM=$#
53
54 # (경로)인자가 존재하지 않는다면
55 if(($ARG_NUM == 1));then
56     if [ "$EXTENSION" = "zip" ];then
57         unzip $ARG1
58     elif [ "$EXTENSION" = "rar" ];then
59         unrar e -d $ARG1
60     elif [ "$EXTENSION" = "alz" ];then
61         unalz $ARG1
62     elif [ "$EXTENSION" = "tar" ];then
63         tar -xvf $ARG1
64     elif [ "$EXTENSION" = "gz" ];then
65         tar -xvzf $ARG1
66     elif [ "$EXTENSION" = "tgz" ];then
67         tar -xvzf $ARG1
68     elif [ "$EXTENSION" = "bz2" ];then
69         tar -xvjf $ARG1
70     fi
71 # 존재한다면 경로대로 압축을 해제시킨다
72 elif(($ARG_NUM == 2));then
73     if [ "$EXTENSION" = "zip" ];then
74         unzip $ARG1 -d $ARG2
75     elif [ "$EXTENSION" = "rar" ];then
76         unrar x $ARG1
77     elif [ "$EXTENSION" = "alz" ];then
78         unalz $ARG1 $ARG2
79     elif [ "$EXTENSION" = "tar" ];then
80         tar -xvf $ARG1 -C $ARG2
81     elif [ "$EXTENSION" = "gz" ];then
82         tar -xvzf $ARG1 -C $ARG2
83     elif [ "$EXTENSION" = "tgz" ];then
84         tar -xvzf $ARG1 -C $ARG2
85     elif [ "$EXTENSION" = "bz2" ];then
86         tar -xvjf $ARG1 -C $ARG2
87     fi
88 fi

간단한(?) 스크립트.
여러 압축파일을 풀때 사용합니다
제가 워낙 다운족이다보니 압축은 안하고 풀기만 합니다...
리눅스인만큼 tar.gz 같은 파일 도 많이 풀지만
애니 자막을 풀기도 하기 때문에 zip,rar,같은것두 사용해서 적어 놨습니다

사실 그냥  alias로 해결하곤 했는데 인제 ut uz ur 쓰는것도 귀찮아져서 그냥
한번에 할려구 그냥 쉘 스크립트를 하나 만든거에요..

tar.gz tar.bz2같은거 때문에 확장자 뻘짓고생을 했것만.. 어짜피 마지막 확장자로
압축을 푸니까 별로 중요하지 않더라는..

음.. 일단 그리고 인자가 없을때만 한번 테스트 해봤더니 그건 잘 돌아가는군요
.. 압축풀 경로를 정했을때는 테스트를 안해봐서 잘 모르겠습니다만.........;;;;
잘되겠져멀~~~~~~~(무책임 =3=3)
오랜만에 쉘스크립트를 만들다보니까 잘 적응이 안되서 또 해멨지만..( 무지하게)
신고
trackback 0 Comment 4
prev 1 next


티스토리 툴바