linux timeout 명령, mount 가 되었는지 확인.

이 모든 일은 Amarok 을 좀 더 편하게 사용하기 위해 시작됐다.
Amarok 에 등록한 음악 라이브러리 폴더는, 외부 서버를 NFS 로 연결해놓았다.
문제는 외부 서버가 켜져있을 수도, 꺼져있을 수도 있기 때문에 무작정 마운트를 할 수도 없다.

자.. 이런 단계가 필요하다.

  1. 해당 마운트 포인트(디렉토리)가 마운트 되었는가? -> mountpoint 명령으로 알아볼 수 있다.
  2. 서버가 켜져있는가? -> mount <디렉토리> 했을 때, 바로 실행이 되는지, 아니면 오류가 나는 지로 확인.

첫번째는 어려울 게 없다. mountpoint -q 를 사용하면 된다.

그리하여, 이런 bash script 를 생각해볼 수 있었다.

#!/bin/bash

if ! mountpoint -q -- /media/userx/musicdb/; then
  mount /media/userx/musicdb
fi
amarok $1

/media/userx/musicdb/ 이 디렉토리가 마운트 포인트가 아니라면, 즉 마운트 되어 있지 않다면 mount 를 하고, amarok 을 실행한다.

그런데..
문제는 서버가 죽어있을 경우, mount 명령에서 한참을 지체하며 진행하지 못한단 점이다.
서버가 살아있을 때는 바로 연결이 되는데, 그렇지 못할 땐 애매한 상황이 된다.

이럴 때 쓰는 게 timeout 이라는 명령이다.
timeout은, 명령을 실행하되, 특정시간 동안 반응이 없다면 명령을 죽여(kill)버린다.
mount 가 정상 실행이 된다면 사실 1초 정도면 되겠지만, 여유있게 4초 정도 주고 다음과 같이 바꿔봤다.

#!/bin/bash

if ! mountpoint -q -- /media/userx/musicdb/; then
        timeout 4 mount /media/userx/musicdb
        if [ $? -eq 124 ]; then
        echo "서버를 확인해봐!"
        exit 1
    fi
fi
amarok $1

timeout 4 mount /media/userx/musicdb 의 뜻은, ‘mount 를 실행한 지 4초가 지나서도 아무 반응이 없다면, mount 를 kill 하라’가 되겠다.

여기서, 거슬리는 게 두가지가 있다.
첫번째는 mountpoint -q -- 에 있는 -- 이다.
이건 End of the options 을 뜻한다.
즉, 이후로는 더 이상 옵션을 쓰지 않음을 명시해준다. 여기선 쓰지 않아도 잘 작동을 하지만, 인터넷에서 찾은 결과에 저렇게 나와 있길래 그냥 써봤다.
아래 글에 설명이 잘 나와있다.

두번째로, $? 가 뭘까???
이 부분에 관해, Linux Command Line(by William E. Shotts Jr.) p334 에선 이렇게 설명하고 있다.

Exit Status
Commands (including the scripts and shell functions we write) issue a value to the system when they terminate, called an exit status. This value, which is an integer in the range of 0 to 255, indicates the success or failure of the command’s execution. By convention, a value of 0 indicates success, and any other value indicates failure. The shell provides a parameter that we can use to examine the exit status.

정리하자면, 명령은 실행이 끝나면 특정 값을 남기는데, 이걸 Exit Status 라고 부른다.
이 값이 0 이면 프로그램은 성공했음을 뜻하고, 그 이외 값들은 모두 실패로 본다.
Bash Script 에서 exit 0 또는 exit 1 로 프로그램 종료를 명시하는 경우가 있는데, 이게 바로 Exit Status 다. 0이면 성공, 1 이면 실패.
그리고 $? 가 바로 이 Exit Status 를 담은 변수다.

그렇다면, 위에서는 왜 $? 가 124 인지를 확인했을까?
이건 timeout man page 에 답이 나와있다.

If the command times out, and –preserve-status is not set, then exit with status 124. Otherwise, exit with the status of COMMAND. If no signal is specified, send the TERM signal upon timeout. The TERM signal kills any process that does not block or catch that signal. It may be necessary to use the KILL (9) signal, since this signal cannot be caught, in which case the exit status is 128+9 rather than 124.

timeout 은, time out 이 되었을 경우, 즉 지정한 시간이 되도록 주어진 명령이 성공하지 못했을 경우(위와 같다면 4초 안에 mount 가 성공하지 못했을 때), Exit Status 로 124 를 반환한다.

따라서, $? 가 124 인지 확인하여, 다시 말해, mount 가 제 때 성공하지 못했는지를 확인한 뒤, echo 로서 서버가 작동하고 있는 지를 확인하는 작업이 필요했다.
여기서는 exit 1 로 스크립트를 종료한다. 정상 종료가 아니므로 0 이 아닌 다른 값, 1 을 줬다.

주 설명은 위로 끝났고, 나머지는 자잘한 설명.

echo “서버를 확인해봐!” 로 오류문구를 줬는데, 이건 사실 큰 의미가 없다.
왜냐하면 저 스크립트는 터미널에서 실행하는 게 아니고, 주로 org.kde.amarok.desktop 에서 실행되기 때문이다. 따라서 GUI 경고 문구가 필요하다.

KDE 에선 이런 정도면 충분하겠다.

kdialog --error "서버 확인 필요"

또는, 알림 메시지(Popup)를 사용하려면,

kdialog --passivepopup "서버 확인 필요" 5

뒤에 있는 5 는 시간(초)이다. 5초 뒤에 Popup 은 자동으로 사라진다.
kdialog 에 대한 자세한 설명은 다음 글 참고.

모두 정리하면 다음과 같다.

#!/bin/bash

if ! mountpoint -q -- /media/userx/musicdb/; then
        timeout 4 mount /media/userx/musicdb
        if [ $? -eq 124 ]; then
        kdialog --error "서버 확인 필요"
        exit 1
    fi
fi
amarok $1

그리고, org.kde.amarok.desktop 의 exec 항목을, 이 스크립트로 바꿔준다.

One Comment

안녕하세요. 글 남겨주셔서 고맙습니다.