Linux의 모든 프로세스에 적용될 수 있도록 timezone 설정 코드

yhcheon의 이미지

Linux system에서 timezone 설정을 변경하는 코드를 작성하고 있는 사람입니다.
제가 알기에 TZ라는 환경변수를 적절하게 setting해서 timezone을 바꿀 수 있는데, 이 경우에는 해당 프로세스 이외의 다른 프로세스에서는 변경된 timezone 정보가 적용되지 않는다는 문제점이 있습니다. 여러가지 찾아본 결과, Unix에서는 환경변수를 바꾸는 것이 해당 프로세스 혹은 해당 프로세스의 child process에만 적용된다는 점을 알게 되었습니다. 이런 방법으로는 많은 무리가 있습니다.
그래서 저는 timezone 설정을 변경했을 때, 그것이 system 전체의 linux date에 영향을 미칠 수 있도록 코드를 작성하고자 합니다.
그 방법 중의 하나로 /etc/localtime 이라는 파일(timezone information file)을 제가 원하는 내용으로 바꿔서 시스템 전체에 적용될 수 있을 것 같기도 합니다. 그런데, 제가 정작 궁금한 것은
1) /etc/localtime의 내용을 어떻게 채울 수 있는가?(저는 ROK 등은 사용하지 않고, UTC 기준으로 +1, -1 등의 방법으로만 적용될 수 있으면 됩니다.)
2) /etc/localtime 의 내용 중에서 daylight saving time(일광절약시간제)에 대한 정보는 어떻게 넣을 수 있는지가 궁금합니다. 참고로 말씀드리면 daylight saving time에 대한 정보는 현재 설정된 시간 기준으로 했을 때 얼마나 차이가 나느냐를 나타내는 offset 과 언제부터 언제까지 일광절약시간제를 적용할 것인가를 나타내는 것입니다.
(제가 관심있는 부분은, offset과 몇월 몇 째 주 무슨 요일 부터 몇월 몇째 주 무슨 요일까지 적용할 것인가에 대한 내용들을 어떻게 timezone information file에 집어 넣을 수 있을 것인가 하는 겁니다.)

또한 혹시 제가 위에서 언급한 방법 이외에, 프로그램을 직접 짜서 timezone을 설정하는 방법에 관한 좋은 정보가 있으신 분들은 말씀해 주시면 정말 감사하겠습니다.
고맙습니다.

dreamer의 이미지

/etc/localtime에 대한 timezone값들이 실제로 이미 컴파일되어 바이너리로

ls /usr/share/zoneinfo/
Africa       Cuba         GMT+0        Kwajalein    Pacific      W-SU
America      EET          GMT-0        Libya        Poland       WET
Antarctica   EST          GMT0         MET          Portugal     Zulu
Arctic       EST5EDT      Greenwich    MST          ROC          iso3166.tab
Asia         Egypt        HST          MST7MDT      ROK          posix
Atlantic     Eire         Hongkong     Mexico       Singapore    posixrules
Australia    Etc          Iceland      Mideast      SystemV      right
Brazil       Europe       Indian       NZ           Turkey       zone.tab
CET          Factory      Iran         NZ-CHAT      UCT
CST6CDT      GB           Israel       Navajo       US
Canada       GB-Eire      Jamaica      PRC          UTC
Chile        GMT          Japan        PST8PDT      Universal

존재 하는 것은 알고 계시죠?
그래서 실제로 /etc/localtime가 원하는 time 파일을 가리키도록 하면 되죠..

죄송하게도 직접 구현이나...정확한 방법에대해서는 저도...
다른 분들이 답변을 해주시기를 바라고..
혹 사이즈 등의 문제가 아니라면 위처럼 단순히 링크를 사용해도 되죠..

pynoos의 이미지

TIMEZONE이 UTC+- 등으로 될 수 있는 것은 사실이지만, 말씀하신 일광시간절약제는 위도상의 구분이 아닌 국가별로 다르므로
국가와 지역을 선택하는 구현이 가장 좋은 것 같습니다.

man tzset
man tzfile

익명 사용자의 이미지

dreamer 님과 pynoos 님 모두 친절한 답변 감사드립니다.
제가 어제 질문을 올린 후에 실제로 시험을 해 봤는데, 물론 Redhat은 아니었고, Hardhat 상황이었습니다.
즉, /usr/share/zoneinfo/[특정 timezone info file] 을 /etc/localtime 으로
copy해 보는 시험을 했습니다.
그 결과가 다소 이상한데, 해당 작업을 하고 있는 telnet process에서는 date 등으로 날짜,시간을 확인했을 때 timezone이 적용되지 않은 UTC 기준으로 여전히 보이고 있었고, 기존 떠 있던 telnet에서도 역시 바뀐 timezone이 적용되지 않은 날짜를 보이고 있다는 겁니다.
단, 새로운 telnet을 띄워서 date를 해 보면 거기에는 timezone이 적용된 값으로 보였습니다.
물론 장비를 껐다가 켜면, timezone이 적용되는 것으로 보이는데, 제가 원하는 건 해당 terminal을 포함해서 기존에 떠 있던 모든 process들의 localtime도 바뀌어 보이는 겁니다.
고수님들의 의견을 부탁드립니다.

dude7853의 이미지

yhcheon wrote:
그 결과가 다소 이상한데, 해당 작업을 하고 있는 telnet process에서는 date 등으로 날짜,시간을 확인했을 때 timezone이 적용되지 않은 UTC 기준으로 여전히 보이고 있었고, 기존 떠 있던 telnet에서도 역시 바뀐 timezone이 적용되지 않은 날짜를 보이고 있다는 겁니다.

이경우는 TZ환경변수가 이미 설정되어있기 때문인듯 합니다. 현재 쉘에 TZ환경변수가 지정되어 있으면 localtime보다 그 설정을 따르게 되어 있으니까요.

yhcheon wrote:
1) /etc/localtime의 내용을 어떻게 채울 수 있는가?(저는 ROK 등은 사용하지 않고, UTC 기준으로 +1, -1 등의 방법으로만 적용될 수 있으면 됩니다.)

zoneinfo파일은 zic라는 timezone file compiler를 이용해서 만들수가 있습니다.
저같은 경우는 각 지역을 모두 포함하면 몇 메가에 달하는 파일들이 부담 스러워서, 그냥 UTC+9이런 식으로 zoneinfo파일을 적당히 만들어준 적도 있습니다.

yhcheon wrote:
2) /etc/localtime 의 내용 중에서 daylight saving time(일광절약시간제)에 대한 정보는 어떻게 넣을 수 있는지가 궁금합니다. 참고로 말씀드리면 daylight saving time에 대한 정보는 현재 설정된 시간 기준으로 했을 때 얼마나 차이가 나느냐를 나타내는 offset 과 언제부터 언제까지 일광절약시간제를 적용할 것인가를 나타내는 것입니다.
(제가 관심있는 부분은, offset과 몇월 몇 째 주 무슨 요일 부터 몇월 몇째 주 무슨 요일까지 적용할 것인가에 대한 내용들을 어떻게 timezone information file에 집어 넣을 수 있을 것인가 하는 겁니다.)

http://stone.backrush.com/sunfaq/f00031.html
문서의 3번 항목을 살펴보시면 되겠네요. (zic컴파일러 사용법도 이문서를 참고하세요)
yhcheon의 이미지

dude7853 님, 정말 감사합니다.
님의 답변 많은 도움이 되었습니다.

그런데, 첫번째로 답해 주신 부분에 대해서는 제가 TZ 환경변수를 따로 setting한 상황이 아니었기 때문에 님의 추측은 맞지 않는 것으로 보입니다. 아마도
hardhat과 redhat의 차이든지, 하는 뭔가 다른 이유가 있겠지요.

두번째, 세번째로 도움 주신 부분에 대해서는 제가 직접 해 보고 나서 다시 결과를 말씀드리거나 추가로 여쭤 보는 것이 좋을 것 같습니다.

그리고, 제가 redhat의 utility 중에서 redhat-config-date 라는 것을 보고 있는데, 이것을 이용하면 현재 띄워진 창 뿐만 아니라 모든 창에서 date 정보가 timezone 정보 반영된 것으로 보임을 확인했습니다.
그래서 redhat-config-date 가 하는 일이 뭔가를 알아볼려고 하는데, 아마도 python 으로 기술되어 있는 것으로 보이고, 그래서 정확하게 이해하기기 어렵습니다.
그래서 혹시 python에 대해서 어느 정도 알고 계시는 분이 있으시다면 제게 메일을 보내 주시면, 제가 궁금한 source(.py)를 보내 드릴테니, 대략적으로 어떤 일을 하는 것인지 가르쳐 주시면 감사하겠습니다.

Yoonho Cheon
ZPSYS Co., Ltd.
yhcheon@zpsys.com

atie의 이미지

----
I paint objects as I think them, not as I see them.
atie's minipage

dude7853의 이미지

yhcheon wrote:
dude7853 님, 정말 감사합니다.
님의 답변 많은 도움이 되었습니다.

그런데, 첫번째로 답해 주신 부분에 대해서는 제가 TZ 환경변수를 따로 setting한 상황이 아니었기 때문에 님의 추측은 맞지 않는 것으로 보입니다. 아마도
hardhat과 redhat의 차이든지, 하는 뭔가 다른 이유가 있겠지요.

두번째, 세번째로 도움 주신 부분에 대해서는 제가 직접 해 보고 나서 다시 결과를 말씀드리거나 추가로 여쭤 보는 것이 좋을 것 같습니다.

그리고, 제가 redhat의 utility 중에서 redhat-config-date 라는 것을 보고 있는데, 이것을 이용하면 현재 띄워진 창 뿐만 아니라 모든 창에서 date 정보가 timezone 정보 반영된 것으로 보임을 확인했습니다.
그래서 redhat-config-date 가 하는 일이 뭔가를 알아볼려고 하는데, 아마도 python 으로 기술되어 있는 것으로 보이고, 그래서 정확하게 이해하기기 어렵습니다.
그래서 혹시 python에 대해서 어느 정도 알고 계시는 분이 있으시다면 제게 메일을 보내 주시면, 제가 궁금한 source(.py)를 보내 드릴테니, 대략적으로 어떤 일을 하는 것인지 가르쳐 주시면 감사하겠습니다.

제가 timezone을 설정하면서 참고한 소스가 바로 redhat-config-date입니다. 8)

redhat의 경우 /etc/sysconfig/clock이라는 파일을 부팅시에 읽어서 처리합니다.

clock파일의 내용은 다음과 같습니다.

ZONE="Asia/Seoul"
UTC=false
ARC=false

rc.sysinit에 보면 이 clock파일을 읽어서 처리하는 부분이 들어있습니다.

redhat-config-date가 하는 일은 선택한 시간대에 따라,
/usr/share/zoneinfo에서 파일을 골라서 /etc/localtime으로 복사하고
그 지역의 이름을 clock파일의 ZONE에
UTC로 설정 옵션에 따라서 UTC에 false/true값을
(당연히 true가 UTC로 맞추는 것입니다)
ARC는 특별한 일이 없으면 false로 써주는 것입니다.

제가 작업했던 시스템에서는 이런 식으로 zoneinfo 파일을 localtime으로 링크를 걸어주고, clock파일을 수정하는 것만으로 date명령어를 실행시에 시간대가 잘 적용되었습니다.

hardhat 어떤 버전을 사용하시는 지 알려주시면, 좀더 자세한 도움을 드릴수있을 듯합니다. 사용하시는 시스템이 부팅시에 어떤 식으로 시간대를 설정하는지를 알아야 할거 같습니다. /etc이하를 통채로 압축해서 보내주시는 것도 좋습니다. :D

yhcheon의 이미지

dude7853 님 정말 감사드립니다.

제가 관심을 가지고 있는 hardhat은 version 2.0 이고, 지금 redhat 환경에서 cross compile하여 장비에 실제로 올려서 시험하고 있는 중입니다.

Redhat 경우에는 redhat-config-date 를 수행한 후에는, 기존 떠 있던 shell이나 새로 띄운 shell이나 혹은 remote로 접속한 shell에 상관없이 설정한 timezone이 적용된 상태로 date 명령 결과가 나옵니다.

그런데, 제가 대상으로 하고 있는 hardhat 에서는, 님께서 말씀하신 대로 /etc/localtime을 적당한 timezone info file로 link하고, /etc/sysconfig/clock을 적당하게 ediiting 하더라도, 그것이 이미 떠 있는 shell 이나 telnet에서는 적용이 되지 않고, 대신 새로운 telnet 등을 열었을 때 설정한 timezone이 적용되어 date 명령 결과가 나옵니다.
물론 장비 power를 껐다가 켜면 timezone이 적용되어서 date가 읽힙니다.

그러나 제가 원하는 것은 power를 off, on 하지 않고, timezone을 설정하기 전에 이미 떠 있던 process들에게도 설정한 timezone이 바로 적용되는 것입니다.(redhat 처럼)

이렇게 할 수 있는 방법은 없을까요? 정말 알고 싶습니다.
혹시 hardhat에서는 달리 할 수 있는 방법이 없는 건가요? 꼭 껐다가 켜야 되는 건가요?

Yoonho Cheon
ZPSYS Co., Ltd.
yhcheon@zpsys.com

세이군의 이미지

redhat-config-date의 소스를 잘 살펴보면

timezoneBackend.py 파일의 내용에는 /etc/localtime의 파일을 어떻게 변경하는가에 대한 부분이 있는데요..

이 파일 말고 dateBackend.py파일에서 하는 일이 원하시는 정보인 것으로 보입니다.
이 파일은 /bin/date 명령을 이용하여 시스템의 시간을 설정하고 /bin/hwclock명령을 이용하여 시간을 하드웨어 시각과 동기화시켜줍니다.

이 부분을 참고해서 확인해 보는 것이 좋을 듯 합니다.

dude7853의 이미지

smjang78 wrote:
redhat-config-date의 소스를 잘 살펴보면

timezoneBackend.py 파일의 내용에는 /etc/localtime의 파일을 어떻게 변경하는가에 대한 부분이 있는데요..

이 파일 말고 dateBackend.py파일에서 하는 일이 원하시는 정보인 것으로 보입니다.
이 파일은 /bin/date 명령을 이용하여 시스템의 시간을 설정하고 /bin/hwclock명령을 이용하여 시간을 하드웨어 시각과 동기화시켜줍니다.

이 부분을 참고해서 확인해 보는 것이 좋을 듯 합니다.

redhat-config-date는 두 부분으로 이루어져있는데요.
시간을 설정하는 부분과 시간대를 설정하는 부분으로 나누어져 있습니다.
시간을 설정하는 부분에는 시간을 직접입력하거나, ntp를 사용하는 설정할 수 있구요.
시간대를 설정하는 부분은 시간대를 설정하고 UTC로 설정할지를 결정합니다.

두가지 설정은 서로 독립적이기 때문에 시간대를 설정한다고 해서 dateBackend의 내용이 실행되지는 않습니다.

dude7853의 이미지

/etc/localtime은 아마도 localtime함수에 사용되는 것 일것입니다.
예를 들어 date명령을 실행하면 시스템 클락을 얻어와서 현재 설정한 시간대에 맞게 변화하게 되는데 그때 localtime함수를 이용합니다. 아마도 이때 /etc/localtime의 내용이 사용되는 것으로 알고 있습니다.

즉, 쉘이 이미 떠있건 나중에 떴건 간에 /etc/localtime의 변화가 바로 적용되어야 합니다. 제가 작업했던 시스템도 하드헷을 기반으로 이것저것을 추가한 시스템인데 크게 문제가 없었습니다.

그래서 드리는 말씀인데, 작업하시는 루트 파일 시스템을 통채로 보내주시면 좀더 자세한 답변을 드릴수있을듯합니다. 루트 파일 시스템이 너무 크다거나 하시면 /etc와 date바이너리를 보내주셔도 좋을듯하네요.

제 메일 주소는 제가 메일로 알려드리기로 하지요.

dreamer의 이미지

환경 변수 TZ값을

echo $TZ

로 한번 확인 해 보시고요..
strace로 내부 시스템 콜들의 사용을 확인해 보시고 한번 보여 주세요..
strace date
yhcheon의 이미지

date 명령을 시스템 콜 형태로 사용한 결과, timezone 변경한 것이 제대로 반영되는 것으로 보입니다.
지금까지는 date 명령을 시스템 콜로 사용하지 않고, localtime이나 ctime 같은 function을 사용해서 현재 date를 확인하려고 했고, 그래서 timezone이 반영되지 않은 것으로 보입니다.

그런데, 한 가지 새로운 의문은 localtime 이나 ctime 같은 function들은 timezone이 반영된 localtime을 보여 준다고 나와 있는데, 실제로 써 본 결과, TZ 환경변수가 설정되어 있지 않고, /etc/localtime 이 제대로 된 timezone file을 가리키도록 만든 상황에서는 timezone이 반영된 localtime을 보여 주지 못 한다는 사실입니다. 물론 새로운 쉘을 띄우게 되면 localtime 혹은 ctime을 부를 때 timezone이 반영된 값으로 보여 줍니다.

하지만, 제가 역시 궁금해 하는 건 기존에 이미 떠 있던 shell이나 현재 설정을 하고 있는 shell에서 localtime function이나 ctime function을 부를 때 왜 현재의 timezone 설정이 적용되지 않는가 하는 것입니다.(물론 TZ는 적용되어 있지 않은 상태입니다.)

* TZ 적용의 문제점은 바로 TZ라는 환경변수는 다른 프로세스 혹은 자신을 부른 parent process로는 TZ 값이 전달되지 않는다는 것으로 이것만 아니면 저는 TZ를 사용해서 timezone을 설정하는 방식을 쓸려고 했습니다.

Yoonho Cheon
ZPSYS Co., Ltd.
yhcheon@zpsys.com

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.