>을 이용해 파일로 저장을 하려는데...

Surym의 이미지

안녕하세요.
/var/log/messages 의 내용을 > 을 이용해 파일로 저장을 하려하는데 잘
안되는 군요.. tail 의 -f옵션을 이용해 새로운 내용이 올라올 때 grep으
로 내가 원하는 내용인지 보고 원하는 내용이면 파일로 저장하려구
tail -f /va/log/messages | grep "surym" > thats_my_log.txt
이렇게 하면 thats_my_log.txt의 내용은 항상 비어있네요 -_-
grep "surym"까지하면 내가 원하는 메시지가 한줄씩 올라오거든요..
근데 왜 그것을 리다에렉 하여 파일로 쓰면 되지 않는 것일까요?
고수님들의 답변을 기다리겠습니다!

그럼,

------------------------------
Feel your heart, always.
Surym

vuccell의 이미지

파일을 쓸때... (프로그램 코딩상) fwrite시점에서 꼭 쓰여지는것이 아닙니다.
buffer가 차기를 기다렸다가 write를 하죠.. 그래서 바로바로 꼭 써야 하는상황이라면, fflush를 해줍니다.
tail -f ... > xxx 할 경우에도 log가 발생한 타이밍에 fwrite는 이루어지지만, 실제로 파일에 쓰여지진 않고, buffer에만 쌓입니다.
4k이상 쌓이면, file에 쓰여지겠죠...

futari의 이미지

Surym wrote:
안녕하세요.
/var/log/messages 의 내용을 > 을 이용해 파일로 저장을 하려하는데 잘
안되는 군요.. tail 의 -f옵션을 이용해 새로운 내용이 올라올 때 grep으
로 내가 원하는 내용인지 보고 원하는 내용이면 파일로 저장하려구
tail -f /va/log/messages | grep "surym" > thats_my_log.txt이렇게 하면 thats_my_log.txt의 내용은 항상 비어있네요 -_-
grep "surym"까지하면 내가 원하는 메시지가 한줄씩 올라오거든요..
근데 왜 그것을 리다에렉 하여 파일로 쓰면 되지 않는 것일까요?
고수님들의 답변을 기다리겠습니다!

그럼,

------------------------------
Feel your heart, always.
Surym

tail -F /va/log/messages | grep "surym" >> thats_my_log.txt

이걸로 해보세요.

file descriptor랑 관련된 몇가지 내부적 상황이 발생하는 듯 합니다.

-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5

futari의 이미지

vuccell wrote:
파일을 쓸때... (프로그램 코딩상) fwrite시점에서 꼭 쓰여지는것이 아닙니다.
buffer가 차기를 기다렸다가 write를 하죠.. 그래서 바로바로 꼭 써야 하는상황이라면, fflush를 해줍니다.
tail -f ... > xxx 할 경우에도 log가 발생한 타이밍에 fwrite는 이루어지지만, 실제로 파일에 쓰여지진 않고, buffer에만 쌓입니다.
4k이상 쌓이면, file에 쓰여지겠죠...

이게 맞는 듯 하네요.

테스트 해보니까 "꽤 많이" 써줬더니 처음 적어주신 방법으로도 저장이 됩니다.

* 근데 궁금한 점이 있는데,

버퍼에 저장했다 쓰는 처리방식이더라도

ctrl+c를 누르면 fwrite에서 받았던건 마무리 지어줘야 하는거 아닐까요?

파일이 비어있다는건.. 조금 이상...

-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5

vuccell의 이미지

버퍼가 다 안 차도 파일이 쓰여지는 건 fclose 가 정상적으로 이루어졌을때입니다.
Ctrl+c를 해서 프로그램을 강제종료시키면, fclose를 할수가 없겠죠 -,-;;;
이런 문제를 발생하지 않을려면 wfrite해주고 바로바로 flush를 해줘야 하는데, 그러면 file segmentation이 또 장난아니기 때문에... (상황에 따라 그렇게 해줄수도 있긴 합니다만... 아무리 file관리를 OS가 잘 알아서 해준다고 해주지만, 그렇게 개념없이 코딩하면.. 언젠간... 흐흐흐흐... 2G짜리 파일이 만개정도로 segmentation나서, file access에 상당히 문제가 발생했던게 떠오르네요..)

futari의 이미지

그러니까 OS에서 처리를 해줘야 할 것 같다는 이야기였죠 :)

사용자 입장에선 fwrite가 불러지면 벌써 썼다고 생각할텐데,

어쨌든 예상치 않은 상황이 되어버리니...

fclose 정도는 cleanup 하면서 OS가 자동으로 처리해줘도 될것 같은 생각이 드는데

혹시 안되는 이유라도 있나요?

-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5

Surym의 이미지

답변들 정말 감사합니다!!!꾸벅!!

역시 4K이상이니까 저장이 되는군요..
그런데 다른 의문 사항이 생겼습니다 -_-;;

다름아닌
tail -f 든 tail -F는 grep 까지는 line by line으로 내용이 간는데요. 즉
tail -F /var/log/messages | grep "surym"
이렇게만 실행시키고 메시지를 찍게하면 line by line (즉 디버그 메시지가 뜰때마다) 출력이되는데요..이것을 간단한 응용으로 보내는 것
예를 들어..

#include <stdio.h>

int main(int argc, char * argv[])
{
printf("just test : argc:%d, %\n", argc, argv[1]);
return 0;
}

이런식으로 test를 하나 만들었다면 line by line으로 받으면 출력을 하게 하면
역시 먹동이 되네요..(이것도 4k까지 기다려야 하는지 -_-;;)
만약 테스트 프로그램에서 debug용 file에 써주고 그때 그때 ffush 같은것을 해주면 될것같아서 시도해 봤는데 되질 않아서요 -_-;;

그럼 수고하세요..

--------------------------------
Feel your heart, always...
Surym

seoleda의 이미지

int main(int argc, char* argv[]){
    FILE * fp = fopen(stdin);
    while(!feof(fp)){
        printf("%s", fgets(fp));
    }
}

머 이런식으로 코딩한후

$ tail -F filename | grep "ff" > ./a.out

이런식의 명령을 내리면 원하시는 결과를 얻을것 같습니다. ^^

다시생각해보니 명령을 아래처럼 주어야 할것 같습니다.

$ tail -F filename | grep "ff" | ./a.out

vuccell의 이미지

위의 futari 님의 글에 대한 답변입니다.

아시다시피 무한루프문이든 그냥 긴 프로그램이든..
(멀티프로세스나 멀티스레드는 제외하고요.. 사실.. 이런것들도 마찬가지지만..)
프로그램은 linear하게 실행됩니다.
그러니까 각각의 분기별로 조건에 따라 분기하기는 하지만, 시작이 있고, 마지막이 있어서 시작부터 마지막까지 선형이죠.... 아무리 복잡한 프로그램이라도 이것은 마찬가지겠죠....

그런데 언급하신 Ctrl+C를 실행하는 것은 이러한 선형의 프로그램중간에 강제로 종료한 것입니다.
프로그램입장에서 보면 비정상적인 종료를 하는 것이죠..

write를 하고 flush를 해주는 식으로 프로그램을 짜는것은 단점이 있습니다. 그래서 write자체를 OS에게 맡기는 편이죠(매번마다 flush를 안해주는 이유)
그러나, 당연히 close가 되면 그동안 버퍼에 쌓여있는 데이터를 쓰게 됩니다.

write후 close전에 비정상적으로 프로그램을 종료시켜버리면, 프로그램은 아예 close할 권한을 잃어버리는것이죠.. 간단한 문제가 아니죠...

물론, Ctrl+c(강제종료) 가 정상적인 종료를 하게 프로그램을 짤수도 있습니다. 그럴경우는 프로그램안에 적절한 signal을 받을수있게 코딩을 해두고, 적절한 signal이 왔을경우 지금 대기상태를 해제하고, 그동안 프로그램에서 열어둔 객체를 모두 해제하고, 프로그램을 정상적으로 종료하는 프로그램은 가능합니다.

그런데 그렇게 짤려면 당연히 사용자가 Ctrl+C라는 시그널을 보내면 안되죠.. 정상적인 종료를 할수 있는 시그널을 날려야 되고, 해당프로그램에서도 그에 대한 처리를 할 수 있게해야 되는데... linux에서 killall -USR1 httpd 같은 명령을 써야 될텐데 그저 간단히 쓰는 ">" 에 그런 기능이 추가될 날은..... -,-;;; 모르겠네요...

그런수준이라면 직접 짜셔야 되지 않을까요? -,-;;;

newprogram -f filename --grep "ff" --outfile a.out
이렇게 작동하도록 -,-;;;;
tail -f 류의 프로그램에 ">"나 ">>"를 쓰는건 적절하지 않은 것 같습니다.
tail -f 는 순간순간의 로그를 실시간으로 확인할때 주로 쓰는것이니... 해당파일은 여전히 존재하고 있고요...

angpoo의 이미지

tail -F /va/log/messages | grep "surym" >> thats_my_log.txt &
그리고 필요할때 tail을 죽여버리심이...

futari의 이미지

우선 답변 감사합니다 :D

약간 뭔가 핀트가 엇나간 부분이 있나보네요. (제 쪽에서..)

제가 생각한 것은

프로그램의 내부 버퍼에 저장했다가 블럭 단위로 쓸 때가 아니라

File Descriptor 처리에서 fwrite 했을때, file에 쓰지 않고 버퍼링을 수행 하였을 경우에 (이 경우엔 아마 OS차원에서 버퍼처리하고 있겠지요? 혹시 compiler 단에서 처리해서, 프로그램 내부 버퍼가 사용되는 것이라면 결론은 난거구요... 그러나... 쓰레드 써야 가능할 것 같으므로.. 아마도 이것은 아닌 듯...)

File Descriptor가 lost 되면 fwrite 요청 되었던 부분 까지는 file 저장을 보장해줘야 하지 않을까 하는 것입니다. (다시 말해 lost된 File Descriptor의 버퍼를 file에 적어줘야 하지 않느냐는거죠.)

이건 프로그램이 종료되었다고 바로 사라지는 정보여야 할 필요도 없고,

단지 '그럴 필요가 없거나 그렇게 할 경우에 공평하지 못하거나, 효율적이지 않아서' 처리 하지 않는 것 같은데요...

사실 fwrite를 수행하였을 경우에 return 값으로 쓴 크기를 다시 돌려주지요.

사용자 입장에서는 그 리턴값을 확인하는 순간 '파일에 써 졌다' 라고 생각 할 수 있는데,

실질적으로 그렇지 못하기 때문에 인식상의 오류가 나타날 수 있다고 보이거든요,

다시 줄여 말하자면,

제 생각은 ,

fwrite가 끝난 (사용자에게 성공적으로 썼다는 return이 돌아온) 정보에 대해서는

file에 써질 것을 OS가 보장해 주는것이 옳지 않은가... 하는 것이었습니다.

약간은 상식적이지 못한 것 같아서...

누가 명쾌한 답변을 좀 :P

-------------------------
The universe is run by the complex interweaving of three elements: matter, energy, and enlightened self-interest.
- G'kar, Babylon 5

hwang의 이미지

fwrite와같은 stdio 함수의 경우 버퍼링은 userspace인 libc에서 해줍니다.
따라서 kernel 차원에서는 갑자기 process가 죽었을때
어떻게 해줄 아무것도 없습니다.
write와같은 raw io함수를 사용하는 경우라면 process가
갑자기 죽더라도 이미 이 요청이 kernel로 전달된 뒤이기
때문에 상관이 없이 저장됩니다.
하지만 이 경우라도 hardware trouble이나 아님 다른 이유도 system이 통째로
비정상 종료가 일어나는 경우에는 write했던 내용이 실제로
harddisk에 저장된다는 것을 보장하진않습니다. 이걸 보장
받을 려면 write후에 fsync/fdatasync와같은 함수를 사용해야만
합니다.

alwaysN00b의 이미지

angpoo wrote:
tail -F /va/log/messages | grep "surym" >> thats_my_log.txt &
그리고 필요할때 tail을 죽여버리심이...

ㅋㅋ~

언제나 시작

댓글 달기

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
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.