이번엔 고급질문이다.

유닉스2007.09.11
조회473

Version: $Id: part4,v 2.9 1996/06/11 13:07:56 tmatimar Exp $

이 일곱개의 문서는 comp.unix.questions와 comp.unix.shell 에서 자주 대답되는
질문에 대한 답변을 포함하고 있다.
제발 이들 질문에 대해서는 다시 질문 하지 말아달라. 이미 이들은 충분히 대답된
것들이다. 그리고 제발 이 문서를 읽지 않았다는 이유로 다시 다른 사람들을
발끈하게 만들지 말라.

문서 부분 6번을 제외한 이 문서의 모음에 대한 저작권은 Ted Timar에게 있고
6번은 Pierre Lewis와 Ted Timar 에게 있다. 모든 권한이 보유되어 있다.
이 모음을 배포하는 권한은 통신상으로 배포되야 하며, 돈이 연루되면 안된다,
그 이외의 배포는 심사숙고 되어야 하며, 모든 합리적인 요청은 승락 될 것이다.

여기 있는 모든 정보는 좋은 목적으로 공헌 된 것들이다, 그러나 여기 있는 것의
모든 것에 대한 확실성에 대한 보증은 나와 공헌자들도 하지 않는다.
만약 이 문서로 인해 발생되는 모든 문제에 대해서는 독자가 책임져야 한다.

이것을 포함하여 많은 FAQ들은 rtfm.mit.edu의 /pub/usenet/news.answers에서
구할 수 있다. FAQ의 이름은 문서의 윗 부분에 "Archive-Name:"에 보여진다.
이 FAQ는 "unix-faq/faq/park[1-7]"로 저장되어 있다.

이 문서는 대체로 다음의 부분으로 나뉘어져 있다.

      1.*) 일반적인 질문들
      2.*) 초보자들에 의해 요청되는 상대적으로 기본적인 질문들
      3.*) 중급 질문들
      4.*) 이미 모든 대답을 알고 있는 것으로 생각되는 사람들에 의한 고급 질문들,      
      5.*) 다양한 쉘과 그 차이에 관계되는 질문들
      6.*) 상이한 유닉스들에 대한 개관
      7.*) 설정관리시스템(RCS, SCCS)의 비교

이 문서는 다음에 대한 대답을 포함하고 있다.:

      4.1)  사용자가 RETURN을 누르지 않아도 터미널로부터 문자를 입력 받을 수 없는가?
      4.2)  실제로 읽지 않고서도 읽을 데이터가 있는지 확인할 수 있는 방법인 있는가?
      4.3)  열려 있는 파일의 이름을 알 수 있는가?
      4.4)  실행되고 있는 프로그램이 자신의 Path를 확인하도록 하는 방법은?
      4.5)  프로세스를 만들어 popen()를 통하여 읽고 쓰기 하는 방법은?
      4.6)  C 프로그램에서 sleep()을 통해 1초 이하로 sleep하는 방법은?
      4.7)  setuid쉘 스크립트가 작동하도록 하려면 어떻게 하나?
      4.8)  한 파일을 어떠한 사용자나 프로세스가 열고 있는지 또는 특정 파일시스템을 사용하
고 있는 프로세스나 사용자가 누구인지를 아는 방법은(umount하려고하는데)?
      4.9)  How do I keep track of people who are fingering me?
      4.10) 프로세스를 프로세스가 터미널로부터 연결이 끊어진 후에 다시 연결할 수 있는 방법
이 있는가?(예를 들어, 프로그램을 백그라운드에서 실행하고나서 logout한 다음에)
      4.11) 다른 터미널에 출력되는 내용을 내 터미널에서 훔쳐 볼 수 있는 방법이 있는가?

만약 여러분이 4.5 질문과 대답에 관해 찾는다고 하고 나머지는 뛰어넘으려고
할 경우 다음 정규식을 사용할 수 있다. "^4.5)".
이것들은 모두 정당한 질문인 반면, 이들은 모두 comp.unix.shell과 comp.unix.questions로
부터 정규적으로 수확된 것이다. 보통 많은 답변들이 올라오고(몇몇은 수정되었다)
같은 질문들이 얼마나 자주 올라 오느냐에 따라 선택 된 것들이다.
여러분은 또한 뉴스그룹에 한달마다 정기적으로 올라오는
"Answers to Frequently Asked Questions" 와 "news.announce.newsusers"에서
유닉스가 무엇을 뜻하는지 알 수 있을 것이다.

유닉스 시스템의 다양함으로 여기의 답변들이 모두 잘 동작할 것을 보증 할 수는 없다.
여기에 제안된 내용을 시도하기 전에 여러분의 local메뉴얼을 읽는게 좋다.
만약 여기에 있는 답변들에 대한 제안이나 수정사항이 있으면 다음으로 메일을
보내주기 바란다.
tmatimar@isgtec.com.

----------------------------------------------------------------------

Subject: 사용자가 RETURN을 누르지 않아도 터미널로부터 문자를 입력 받을 수 없는가?
Date: Thu Mar 18 17:16:55 EST 1993

4.1)  사용자가 RETURN을 누르지 않아도 터미널로부터 문자를 입력 받을 수 없는가?

      BSD에서는 cbreak, SysV에서는 ~ICANON 모드가 있는지 확인하라.

      만약 여러분이 ioctl(2)시스템 호출을 사용하여 터미널 파라미터를 바꾸려고 하지
      않는다면, 여러분은 stty프로그램 가지고 그러한 일을 할 수가 있다. 그러나 이것은
      느리고 비 효율적이다. 그리고 여러분은 실행후에 다시 원상 복귀시켜야 한다.

      #include
      main()
      {
            int c;

            printf("Hit any character to continue\n");
            /*
             * ioctl()을 쓰면 더 좋던데; 게으른 사람들은
             * 다름과 같이 한다.
             */
            system("/bin/stty cbreak");        /* 또는 "stty raw" */
            c = getchar();
            system("/bin/stty -cbreak");
            printf("Thank you for typing %c.\n", c);

            exit(0);
      }

      여러 사람들이 이 문제에 대한 보다 많은 솔루션을 내게 줬다.
      여기에 그것들을 포함시키지 못해서 죄송스럽게 생각한다. 왜냐하면
      그들도 정말 여기에 충분히 포함될 만한 것들이기 때문이다.

      여러분은 "curses"스크린 라이브러리 에 대한 문서를 확인해 보는것도 좋겠다.
      여러분이 이것과 같은 single-character I/O에 관심이 있으면, 또는 몇몇 스크린
      디스플레이 제어에 관심이 있으면, 그 curses라이브러리는 이 두가지 함수에 대한
      다양한 루틴들을 제공할 것이다.

------------------------------

Subject: 실제로 읽지 않고서도 읽을 데이터가 있는지 확인할 수 있는 방법인 있는가?
Date: Thu Mar 18 17:16:55 EST 1993

4.2)  실제로 읽지 않고서도 읽을 데이터가 있는지 확인할 수 있는 방법인 있는가?

      어떤 버전의 유닉스는 문자들이 현재 파일 디스크립터로부터 읽기 가능한지를
      확인하는 방법을 제공한다. BSD에서 여러분은 select()를 사용할 수 있다.
      또한 여러분은 FIONREAD ioctl을 사용하여 읽기를 기다리고 있는 문자들의
      개수를 세어오는 방법을 제공한다. 그러나 이것은 터미널과 파이프, 그리고
      소켓에만 해당한다. System V Release 3에서는 poll()을 사용할 수 있다. 그러나
      이것은 stream에서만 동작한다. Xenix에서 (그리고 Unix SysV r3.2와 그 후버전)
      에서는 rdchk()시스템 호출을 통하여 주어진 파일 디스크립터에서의 read()호출이
      블록될지를 알아낼 수 있다.

      그러나 파일 포인터로부터 문자들이 읽기 가능인지를 체크하는 방법은 없다.
      (여러분은 stdio의 입력버퍼가 비어있지 않은지를 엿볼 수 있다, 그러나
      여러분이 그 버퍼를 다음에 채우려고 할 때 무슨일이 일어날지 아는 방법이
      없다면 그것은 동작하지 않을 것이다.)

      때때로 사람들은 writing의 의도로 이러한 질문을 하기도 한다.
            if (characters available from fd)
                    read(fd, buf, sizeof buf);
      비블록킹 읽기의 효과를 얻기 위하여. 이것은 그것을 하기 위한 가장 좋은
      방법은 아니다. 왜냐하면 여러분이 가능성(availability)을 테스트할 때
      문자들이 이용가능할 것이라는 것이 가능성이 있는 것이기 때문이다. 그러나
      여러분이 read를 호출할 때 그것은 더 이상 이용가능하지 않다.
      대신, O_NDELAY flag를 fcntl(2)의 F_SETFL옵션을 사용하여 설정하라.
      오래된 시스템(Version 7, 4.1 BSD)는 O_NDELAY를 가지고 있지 않다.
      이들 시스템에서 여러분이 비블록킹 read를 수행할 수 있는 가장 근접한
      방법은 alarm(2)를 사용하여 read타임아웃을 설정하는 것이다.

------------------------------

Subject: 열려 있는 파일의 이름을 알 수 있는가?
Date: Thu Mar 18 17:16:55 EST 1993

4.3)  열려 있는 파일의 이름을 알 수 있는가?

      일반적으로, 이것은 매우 어렵다. 파일 디스크립터는 아마도 파일이나
      pty에 부착되어 있을 것이다. 그런 경우에 그것은 이름을 가지고 있지 않다.
      그것은 삭제된 파일에 부착되어 있을 수도 있고, 다중의 이름(hard또는
      심볼릭 링크 때문에)을 가지고 있을 수도 있다.

      만약 여러분이 정말로 이것을 하는게 필요하면, 여러분은 -xdev와
      -inum을 이용하여 find명령을 사용할 수 있을 것이다. 또는 ncheck
      또는 이러한 일을 하는 프로그램을 여러분의 프로그램에 추가시킬
      수도 있을 것이다. 하지만 알아둘 것은 하나의 파일을 600메가바이트의
      파일 시스템에서 찾는건 시간이 좀 걸릴 것이란 것이다.

------------------------------

Subject: 실행되고 있는 프로그램이 자신의 Path를 확인하도록 하는 방법은?
Date: Thu Mar 18 17:16:55 EST 1993

4.4)  실행되고 있는 프로그램이 자신의 Path를 확인하도록 하는 방법은?

      여러분의 프로그램은 argv[0]을 찾을 수있을 것이다. 만약 그것이 "/"로
      시작한다면, 그것은 아마도 그 프로그램이 절대패스로 지정되었음을 뜻하는
      것이고, 그렇지 않다면, 여러분의 프로그램은 여러분의 PATH환경변수에서
      argv[0]에 있는 파일을 찾아야 한다. 그 디렉토리와 실행되고 있는 파일의
      이름을 연결하여 원하는 이름을 얻을 수 있을 것이다.

      그럼에도 확신할 수는 없을 것이다. 왜냐하면 argv[0]을 다른이름으로 지정하여
      프로그램을 실행할 수 있기 때문이다. 이것은 단순히 새로운 프로그램이
      argv[0]에 있는 실행파일 이름으로 실행될때에 한정된다.

      예를 들어, 단순히 이러한 예제가 있다고 보자.
       
        #include
        main()
        {
            execl("/usr/games/rogue", "vi Thesis", (char *)NULL);
        }

      실행되는 프로그램은 그것의 이름이 "vi Thesis"라고 생각할 것이다.
      (어떤 다른 프로그램은 여러분이 실행하고 있는 프로그램이
      또한 그 프로그램의 이름이 "vi Thesis"라고 생각할 것이고, 그러나
      물론 이것은 단지 가설이고, 그렇게 하지는 마라)

------------------------------

Subject: 프로세스를 만들어 popen()를 통하여 읽고 쓰기 하는 방법은?
Date: Thu Mar 18 17:16:55 EST 1993

4.5)  프로세스를 만들어 popen()를 통하여 읽고 쓰기 하는 방법은?

      임의 종속 프로세스에 데이터를 보내고 받기 위한 pipe를 만들면 deadlock이
      생길 수 있다.(만약 동시에 두 프로세스가 아직 생성되지 않은 입력을 기다릴 때)
      Deadlock은 양쪽에서 엄격한 deadlock-free 프로토콜을 사용해서만 이것을 피할
      수 있다. 그러나 그것은 그 프로세스 사이의 협동이 필요하기 때문에 그것은
      popen()과 같은 라이브러리 함수에서는 적당하지가 않다.

      'expect'의 라이브러리 배포판에는 C프로그래머가 직접 호출할 수 있는
      함수들이 들어있따. 이 함수들 중에 하나는 양쪽에서 읽고 쓸 수 있는
      popen()과 같은 일을 하는 것이 있다. 그리고 이것은 deadlock문제도 없다.
      이것은 BSD나 SV둘다 에서 사용가능하다. 3.9 질문을 보면 'expect'에 관한
      더 자세한 내용을 볼 수 있을 것이다.

------------------------------

Subject: C 프로그램에서 sleep()을 통해 1초 이하로 sleep하는 방법은?
Date: Thu Mar 18 17:16:55 EST 1993

4.6)  C 프로그램에서 sleep()을 통해 1초 이하로 sleep하는 방법은?

      여러분이 알고 있어야할 첫 번째 것은 여러분이 지정할 수 있는 것은 오직
      지연시간의 MINIMUN의 양이다. 실제 delay는 시스템 load와 같은 스케줄링
      이슈에 의해 좌우된다. 그리고 그것은 여러분에는 불행이지만 임의적으로
      커질수도 있다.

      여러분이 sleep보다 더 작은 시간을 sleep하기 위한 표준 라이브러리는 없다.
      몇몇 n 마이크로 초를 통한 "usleep(n)"와 같은 함수를 지원하는 환경도 있다.
      만약 여러분의 환경이 usleep()을 지원하지 않는다면, 여기 몇 개의 BSD와
      System V환경에서 돌아가는 구현이 있따.

      아래의 코드는 Doug Gwyn의 4BSD를 위한 System V에뮬레이션으로부터
      수정된 프로그램이며 4BSD의 select()시스템 호출을 이용했다.
      Doug는 원래 이것을 'nap()'이라고 불렀다. 여러분은 아마 이것을 "usleep()"
      이라고 부르길 원할 것이다.

      /*
            usleep -- 4.2BSD시스템 호출을 지원하는 에뮬레이션
            최종수정일:  29-Oct-1984     D A Gwyn
      */

      extern int        select();

      int
      usleep( usec )                            /* returns 0 if ok, else -1 */
            long                usec;           /* delay in microseconds */
            {
            static struct                       /* `timeval' */
                    {
                    long        tv_sec;         /* seconds */
                    long        tv_usec;        /* microsecs */
                    }   delay;          /* _select() timeout */

            delay.tv_sec = usec / 1000000L;
            delay.tv_usec = usec % 1000000L;

            return select( 0, (long *)0, (long *)0, (long *)0, &delay );
            }

      System V에서 여러분은 다음과 같은 방법으로 할 것이다.

      /*
      subseconds sleeps for System V - or anything that has poll()
      Don Libes, 4/1/1991

      Poll()이 밀리초로 정의되는 반면에, BSD에서 이 함수와 비슷하게 구현된건
      마이크로초로 정의된다. 호환성을 위해 이 함수는 밀리초에 대한 실제 요청을
      잘라 버리고 여러분이 아마도 이것을 팽팽한(tight) loop에서 호출된다고 가정하여
      마이크로초를 누적하여 오랜동안 정확성을 유지한다. 그러나 오랜 시간이 지나면
      역시 에러가 발생한다.
    
      만약 여러분이 이것을 팽팽한 loop에서 호출하지 않으면, 여러분은 거의 확실하게
      마이크로초-해상도(?)(microsecond-resolution) 요청만들기를 하지 않을 것이다.
      이러한 경우에는 여러분은 마이크로초를 걱정하지 않아도 된다. 그리고 만약 여러분이
      했다면, 어떤 유닉스도 여러분은 사용하지 않을 것이다. 왜냐하면 랜덤 시스템이
      미숙하면 어떤 타이밍 코드로 부터도 실패될 수 있기 때문이다.

      성공이면 0을 리턴하고 실패이면 -1
      */

      #include

      int
      usleep(usec)
      unsigned int usec;                /* 마이크로초 */
      {
            static subtotal = 0;        /* 마이크로초 */
            int msec;                   /* 밀리초 */

            /* 'foo'는 오직 여기에 있다. 왜냐하면 비록 두 번째 argument가 0일지라도
             * 몇몇 5.3 버전은 poll()을 위한 첫 번째 argument가 합당한 메모리 주소에
             * 대하여 체크되는 버그를 가지고 있다.
             */
            struct pollfd foo;

            subtotal += usec;
            /* 1초 요청보다 작으면, 그것을 기억만 한다.
            */
            if (subtotal < 1000) return(0);
            msec = subtotal/1000;
            subtotal = subtotal%1000;
            return poll(&foo,(unsigned long)0,msec);
      }

      System V과 다른 non-BSD에서 nap()을 하기위한 다른 가능성은
      Jon Zeff의 s5nap패키기가 있는데 이것은 comp.sources.misc, volume 4에
      포스팅 되었다. 그것은 디바이스 드라이버를 인스톨 할 것을 요구한다. 그러나
      한 번 인스톨 되면 결점없이 잘 동작한다.(그것의 resolution은 커널 HZ값에
      의해 제한된다. 왜냐하면 그것은 커널의 delay()루틴을 사용하기 때문이다.)

      많은 새로운 버전의 Unix는 nanosleep 함수를 가지고 있다.

------------------------------

Subject: setuid쉘 스크립트가 작동하도록 하려면 어떻게 하나?
Date: Thu Mar 18 17:16:55 EST 1993

4.7)  setuid쉘 스크립트가 작동하도록 하려면 어떻게 하나?

      [ 이것은 긴 답변이다. 그러나 이것은 복잡하고 자주 답변되는 질문이다.
       이것에 대한 대답과 아래의 "indir"프로그램을 제공해준 Maarten Litmaath에
       대해 감사 한다.]

      일단 여러분이 소위 '실행가능한 쉘 스크립트'를 인식하는 UNIX 시스템
      (예를 들어 4.3BSD나 SunOS)을 쓴다고 가정하자.
      그러한 스크립트는 다음과 같은 라인으로 시작한다.

        #!/bin/sh

      이 스크립트는 '실행가능'하다고 불리는데 왜냐하면 단지 실제 바이너리 실행파일은
      매직넘버라고 불리는 실행가능을 지시하는 것으로 시작한다.
      우리의 경우 그 번호는 '#!'이고 OS는 그 첫 번 라인의 나머지 부분을 그 스크립트에
      대한 해석기로 간주한다. 다음을 내용으로 가진 스크립트가 있다고 가정하자.

        #!/bin/sed -f

      이 스크립트는 'foo'라고 부르고 /bin에 있다고 하자 만약 우리가 다음과 같이 타이프
      하면

        foo arg1 arg2 arg3

      OS는 다음과 같이 재 설정할 것이다.

        /bin/sed -f /bin/foo arg1 arg2 arg3

      여기 하나의 다른 것이 있는데: 만약 setuid 퍼미션 비트가 'foo'에 대해
      설정되어 있으면, 그 권한을 첫 번째 폼에서 부여받게 될 것이다.
      만약 여러분이 실제로 두 번째 처럼 타이핑한다면, OS는 setuid가 붙어 있지 않은
      /bin/sed에게 그 권한을 부여할 것이다.

      ----------

      좋다. 그러나 나의 스크립트가 '#!'로 시작하지 않거나 OS가 그것을 인식하지 못하면
      어떻게 되는가?

      음, 만약 쉘이 그것을 실행하려 한다면,  OS는 파일이 적정한 매직넘버로 시작하지
      않는다고 에러를 발생시킬 것이다. 이 에러를 받고 나면 쉘은 그 파일을 쉘 스크립트라고
      다시 가정하게 될 것이다. 그리고 다른 방법으로 시도할 것이다. 다음과 같이:

        /bin/sh shell_script-x arguments

      그러나 이 경우에는 setuid 권한은 받지 못한다.

      ----------

      그렇다면 보안의 위험성은 어떤가?

      음, 쉘 스크립트가 '/etc/setuid_script-x'라고 가정하고, 그것이 다음으로 시작한다고
      해보자.

        #!/bin/sh
       
      이제 다음의 명령을 쳐보자. 어떻게 되나..

        $ cd /tmp
        $ ln /etc/setuid_script-x -i
        $ PATH=.
        $ -i

      우리는 마지막 명령이 다음으로 재설정 된다는 것을 안다:

        /bin/sh -i

      그러나 이 명령은 우리에게 그 스크립트의 쉘 소유자로 setuid가 된
      인터랙티브 쉘을 줄 것이다.
      운좋겠도 이 보안 구멍은 첫 번째 라인을 다음과 같이 하여 쉽게 닫을 수 있다.

        #!/bin/sh -

      옵션 리스트의 마지막에 있는 '-' 시그널은 다음 argument인 '-i'를
      명령이 읽어 들어야 할 파일의 이름으로 간주하게 된다.

      ---------

      하지만 더 심각한 문제가 있다.

        $ cd /tmp
        $ ln /etc/setuid_script-x temp
        $ nice -20 temp &
        $ mv my_script-x temp

      세 번째 명령은 다음과 같이 재설정된다.

        nice -20 /bin/sh - temp

      이 명령이 아주 천천히 실행되는 동안, 'temp'가 쉘에 의해 open되기 전에
      네 번째 명령은 원래의 'temp'를 'my_script-x'로 대치 할 것이다. 이 보안구멍을
      막는 네가지 방법이 있다.

        1) OS가 setuid가 붙은 쉘 스크립트를 다른 안전한 방법으로 수행하도록 하는
           것이다.
           - System V R4와 4.4BSD는 /dev/fd드라이버를 사용하여 그 스크립트에 대한
            파일 디스크립터를 해석기가 통과하도록 한다.

        2) 그 스크립트가 간접적으로 해석되도록 한다. 그 실제 해석기를 실행하기 전에
           모든 것이 좋다라는 확신을 받도록. 만약 여러분이 comp.sources.unix에 있는
           'indir'프로그램을 사용한다면, setuid스크립트는 다음과 같이 보여질 것이다.

                #!/bin/indir -u
                #?/bin/sh /etc/setuid_script-x

            'binary wrapper'를 만들어라: setuid이고 그것이 하는일은 오직 argument로
             그 스크립트의 이름을 가지고 해석기를 실행하는일만 하는
             실제 실행파일 (real excutable) 프로그램을 만들어라.

        4)  합당한 스크립트의 데이터 베이스 안에서 요청된 '서비스'를 위치시키는
           보편적인 'setuid script-x server'를 만들어라. 그리고 그것이 성공하면
           옳은 argument를 가지고 해석기를 실행할 것이다.

      ---------

      이제 우리는 그 올바른 파일이 해석되었다는 것을 확신하게 되었다.
      아직도 위험은 남아 있는가?

      물론 그렇다. 쉘 스크립트에 대해서 우리는 PATH를 안전한 path로 지정하는 것을
      잊어서는 안된다. 왜 그런지 아는가? 또한 IFS 변수가 있는데 이것은 만약 제대로
      설정되지 않으면 문제를 일으키게 된다. 다른 환경변수가 보안에 문제를 줄수 있다고
      밝혀졌다...예를 들어.. SHELL 등등. 게다가 여러분은 스크립트안에 있는 명령이
      인터랙티브 쉘 탈출(escape)를 허용하지 않도록 해야 한다. 그리고 umask를
      잘못쓰면 뭔가 이상하게 될 수 있으므로 주의해야 한다.

      기타로, 여러분은 setuid스크립트는 그 스크립트에서 부르는 모든 명령에 대한
      보안 위험과 모든 버그도 상속받게 된다는 것을 알아둬야 한다.

      setuid 쉘 스크립트를 쓰는건 위험성이 크다..될수 있으면 C 프로그램을 작성하는게
      낫다.

------------------------------

Subject: 한 파일을 어떠한 사용자나 프로세스가  열고 있는지 또는 특정 파일시스템을 사용하고
있는 프로세스나 사용자가 누구인지를 아는 방법은(umount하려고하는데)?
Date: Thu Mar 18 17:16:55 EST 1993

4.8)  한 파일을 어떠한 사용자나 프로세스가 열고 있는지 또는 특정 파일시스템을 사용하고 있는
프로세스나 사용자가 누구인지를 아는 방법은(umount하려고하는데)?

      fuser(System V), fstat(BSD), ofiles(공개프로그램) 또는 pff(공개프로그램)등이
      이 일을 해준다.
      이들 프로그램은 여러분에게 특정 파일을 사용하는 프로세스에 대한
      다양한 정보를 제공해 준다.

      4.3 BSD fstat을 Dynix, SunOS, Ultrix로 포팅한 것은 comp.sources.unix, volume 18
      에 있다.

      pff는 kstuff패키지의 일부분이고 이것이 동작하는 시스템은 매우제한되어 있다.
      kstuff을 얻는 명령은 3.10에 있다.
     
      나는 또한 lsof라는 프로그램이 있다는 것을 알려줬었다. 나는 그것을 어디에서
      얻는지는 모른다.

      Michael Fink 가 추가함:

        만약 여러분이 위의 툴들이 어떤 열려 있는 파일에 대해서도 레포트를 주지
        못하는 파일시스템을 unmount하지 못한다면 여러분이 unmount하려고 하는
        그 파일 시스템이 어떠한 active마운트 포인트도 포함하고 있지
        않은지를 확인하라.(df(1)).

------------------------------

Subject: How do I keep track of people who are fingering me?
>From: Jonathan I. Kamens
>From: malenovi@plains.NoDak.edu (Nikola Malenovic)
Date: Thu, 29 Sep 1994 07:28:37 -0400

4.9)  How do I keep track of people who are fingering me?

      일반적으로 여러분은 리모트 기계의 다른사람이 여러분을 finger하는지를 알 수가 없다.
      여러분은 단지 finger요청이 어느기계에서 들어왔는지는 확인 할 수 있다. 하나의
      만약 여러분의 시스템이 그것을 지원하고 finger daemon 거부하지 않을 경우에
      가능한 하나의 방법은 여러분의 .plan 파일을 일반 파일이 아니라 "named pipe"로
      만드는 것이다.(이것을 만들기 위해 'mknod'를 사용하라)

      여러분은 그런다음 여러분의 .plan파일을 open하는 프로그램을 실행 시킬 수 있다.
      그 open은 다른 프로세스(말하자면 fingerd)가 .plan을 reading을 위해 open할 때까지
      블록된다. 이제 여러분은 이 파이프를 통해 여러분이 원하는 것을 날릴수 있다.
      이렇게 되면 여려분은 사람들이 finger할 때마다 원하는 어떤 정보를 계속
      바꿔가면 넣을 수도 있다. 이러한 프로그램이 comp.sources.misc의 Volume 41에
      "planner"라는 패키지로 있다.

      물론, 이것은 여러분이 named pipe를 지원하지 않거나 만약 여러분의 local fingerd가
      .plan파일이 일반 파일이기를 고집한다면 작동하지 않을 수도 있다.

      여러분의 프로그램은 또한 "netstat"의 출력을 볼 수 있는 기회가 있다. 그리고
      들어오는 finger연결이 어디에서 왔는지도 알 수 있다. 그러나 이것은 리모트의
      유저를 알 수는 없다.

      리모트 유저의 userid를 얻는 것은 리모트 site가 RFC 931에서 정의하는 identity서비스를
      지원해야 한다. BSD시스템에 대해서 3개의 RFC 931지원 프로그램이 현재 있따. 그리고
      몇몇 어플리케이션들(wuarchive ftpd)는 그러한 서비스를 지원한다.
      더 자세한 정보는 rfc931-users mailing list와 rc931-users-request@kramden.acf.nyu.edu를
      참조하라

      이 답변에 관련된 세가지 경고가 있다. 첫 번째는 많은 NFS시스템이
      named pipe를 정확히 인식하지 못한다는 것이다. 이것은 다른 기계의
      named pipe를 읽으려고 하면 타임아웃이 끝날때까지 블록되거나
      크기가 0인 파일로 간주 되게 되거 아무것도 출력되지 않을 수 있다.

      두 번째 문제는 많은 시스템에서 fingerd는 .plan파일이 그 파일을 읽기전에
      파일이 데이터를 가지고 있는지를 확인한다 이것은 리모트 finger가 여러분의
      .plan파일을 완전히 읽지 않게된다라는 것을 의미한다.

      세 번째 문제는 named pipe를 지원하는 시스템은 일반적으로 고정된 크기의
      커널이 사용할 수 있는 named pipe를 가지고 있다라는 것이다. - 커널의 config파일을
      체크하고 FIFOCNT 옵션을 확인하라. 만약 시스템에서의 FIFOCNT 수를 pipe갯수가
      초과하면 시스템은 새로운 pipe는 어떤 자원이 free될때까지 블록된다.
      이것에 대한 이유는 버퍼는 non-paged 메모리에 할당되기 때문이다.

------------------------------

Subject: 프로세스를 프로세스가 터미널로부터 연결이 끊어진  후에 다시 연결할 수 있는 방법이
있는가?(예를 들어, 프로그램을 백그라운드에서 실행하고나서 logout한 다음에)
Date: Thu Mar 18 17:16:55 EST 1993

4.10) 프로세스를 프로세스가 터미널로부터 연결이 끊어진 후에 다시 연결할 수 있는 방법이 있는
가?(예를 들어, 프로그램을 백그라운드에서 실행하고나서 logout한 다음에)

      대부분의 UNIX는 VMS와 Multics가 지원하는 것처럼 프로세스의  "detaching"와
      "attaching"을 지원하지 않는다. 그러나 세 개의 자유 배포 패키지는 프로세스를
      나중에 어떤 터미널에 다시 attach될수 있도록 해주는 그러한 방법으로 구동
      시킬수 있게 해주고 있다.

      첫 번째 것이 "screen"인데 이것은 comps.sources.unix에 "screen, multiple windows on
      a CRT"라는 이름으로 등록되어 있다.(comp.sources.misc의 Volume 28에 있는
      "screen-32"패키기를 보라) 이 패키지는 적어도 BSD와 System V r3.2와
      SCO UNIX에서는 돌아간다.

      두 번째는 "pty"인데 이것은 comp.sources.unix에 "Run a program under a pty session"
      이라는 것으로 등록되어 있다.(Volume 23의 "pty"를 보라). pty는 BSD계열 시스템에서
      동작하도록 디자인 되었다.

          세 번째는 "dislocate"이다. 이것은 expect프로그램과 함께 오는 스크립트이다.
          앞의 프로그램들과 달리 이것은 모든 유닉스에서 실행가능하다.  자세한건
          3.9에 있다.

      이들 어느 프로그램도 소급(retroactive)되지 않는다. 여러분은 screen 또는 pty하에서
      실행된 프로세스만을 detach하거나 reattach할 수 있다.

------------------------------

Subject: 다른 터미널에 출력되는 내용을 내 터미널에서 훔쳐 볼 수 있는 방법이 있는가?
Date: Wed, 28 Dec 1994 18:35:00 -0500

4.11)다른 터미널에 출력되는 내용을 내 터미널에서 훔쳐 볼 수 있는 방법이 있는가?
      모두 완벽한건 아니지만 몇가지 방법이 있다.

      * kibitz는 두 사람이 하나의 쉘(또는 어떤 임의의 프로그램)을 가지고 인터랙트
        할 수 있게 해준다.

        - 다른 사람의 터미널 세션을 보거나 도와줄 수 있다.
        - 뒤로 스크롤 할 능력만 계속 유지되면 대화를 기록하고 저장하고 또는 심지어
          그것을 편집할 수도 있다.
        - 여러사람이 함께 게임을 하거나, 문서를 편집하거나 다른 협동 작업을 할 수 있다

        kibitz는 expect프로그램의 한 부분으로 배포된다. 3.9 질문을 보라.

        kibitz는 훔쳐올 대상의 권한을 받아야 한다. 권한 없이 훔치기 위해선 좀
        유쾌하지 않은 방법이 필요하다.

      * 여러분은 커널 구조를 뒤지고 궁금한 터미널에 대한 버퍼 출력을 쳐다
        볼 프로그램을 만들 수 있다. 이것은 확실히 Unix커널에 상당한 지식이
        없는 사람이 할만한 일은 아니다. 게다가 여러분이 사용하려는 툴들은
        대부분은 호환성이 떨어지는 것들이 대부분이다.

      * 만약 여러분이 특정 hard-wired터미널을 계속해서 감시하고 싶다면(예를 들어
        만약 콘솔 터미널을 다른 곳에서 계속 체크하기위해) 여러분은 그 터미널
        케이블을 꼬아서 다른 터미널에 연결할 수 있다. 예를 들어 모니터 출력을
        다른 기계의 시리얼 포트로 연결하는 것이다. 그리고 프로그램을 그 포트에서
        실행하면 그 내용은 다른곳으로 전송될 것이다. 만약 이렇게 한다면
        그 터미널로부터의 어떤 출력이 wire뒤로 가는지를 확인해야 한다.
        비록 꼼(splice)가 오직 computer->터미널 wire일 지라도 이것은
        많은 문제가 되지는 않는다. 이것은 터머널 와이어링에 잘 아는 사람이
        아니면 잘 시도 될 수 없는 것이다.

      * 스크린의 마지막 버전은 다중사용자 버전을 포함하고 있다.
        몇몇 자세한 정보는 4.10에 있다.

      * 만약 시스템이 (SunOS, SVR4)처럼 stream을 가지도록 되어 있다면,
        comp.sources.misc의 volume 28에 포스팅된 프로그램이 사용될 수 있을 것이다.
        그리고 그것은 처음에 실행될 필요는 없다.

유닉스 쩜 씨오 쩜 케알  펌//