2009-09-17 54 views

回答

37

tail实用程序是linux上的coreutils的一部分。

我总是发现FreeBSD系统具有比GNU工具更加清晰的源代码。因此,这里的在FreeBSD项目tail.c:

+0

+1的多样性,即使原来的问题是关于Linux实用程序。 – 2009-09-17 16:19:04

+1

我喜欢linux版本比BSD版本多几倍。 – 2012-09-04 14:30:52

+5

由于执行所有工作的函数不在该文件中,因此BSD版本较短。即:follow()。 – 2013-04-27 14:06:32

1

打开uclinux网站。由于他们分发软件,他们被要求以这种或那种方式提供源代码。

或者,您可以阅读man fseek并猜测如何完成。

注意 - 请参阅William的注释,有些情况下您无法使用seek。

+0

尾巴不使用fseek。如果是这样,它不会在流中工作(例如'grep pat file | tail') – 2009-09-17 16:13:40

+0

嗯,从来没有想到这一点。谢谢。我必须认为,使用可搜索的输入时它仍然会更快。 – dmckee 2009-09-17 16:18:33

+1

这不完全正确。 '尾巴'不总是*使用寻求;-) – 2009-09-17 16:20:21

0

您可能会发现一个有趣的练习写自己的。绝大多数的Unix命令行工具都是一个非常简单的C代码页面。

为了看看代码,可以在gnu.org或您最喜欢的Linux镜像站点上轻松找到GNU CoreUtils源代码。

+1

当Linux处于初级阶段时,我为MS-DOS编写了一套相当完整的工具。虽然很多都是直截了当的,但我会毫不犹豫地说出“一个页面”,而不会说“绝大多数”。**例如,找到**和** ls **要复杂得多 – NVRAM 2009-09-17 16:26:32

+0

核心大多数工具通常*是* short。但是参数处理和角落案例处理可能会很痛苦 – dmckee 2009-09-17 16:26:53

+0

是的,我可能应该说“许多”工具简单而简单,GNU tail有很多选项,所以它可能不适合“简单”的类别,大多数人会使用的尾部版本(即尾部-xxx文件或尾部-f文件)将非常简单。 – 2009-09-17 19:04:52

-2
/`*This example implements the option n of tail command.*/` 

    #define _FILE_OFFSET_BITS 64 
    #include <stdio.h> 
    #include <stdlib.h> 
    #include <fcntl.h> 
    #include <errno.h> 
    #include <unistd.h> 
    #include <getopt.h> 

    #define BUFF_SIZE 4096 

    FILE *openFile(const char *filePath) 
    { 
     FILE *file; 
     file= fopen(filePath, "r"); 
     if(file == NULL) 
     { 
     fprintf(stderr,"Error opening file: %s\n",filePath); 
     exit(errno); 
     } 
     return(file); 
    } 

    void printLine(FILE *file, off_t startline) 
    { 
     int fd; 
     fd= fileno(file); 
     int nread; 
     char buffer[BUFF_SIZE]; 
     lseek(fd,(startline + 1),SEEK_SET); 
     while((nread= read(fd,buffer,BUFF_SIZE)) > 0) 
     { 
     write(STDOUT_FILENO, buffer, nread); 
     } 
    } 

    void walkFile(FILE *file, long nlines) 
    { 
     off_t fposition; 
     fseek(file,0,SEEK_END); 
     fposition= ftell(file); 
     off_t index= fposition; 
     off_t end= fposition; 
     long countlines= 0; 
     char cbyte; 

     for(index; index >= 0; index --) 
     { 
     cbyte= fgetc(file); 
     if (cbyte == '\n' && (end - index) > 1) 
     { 
      countlines ++; 
      if(countlines == nlines) 
      { 
     break; 
      } 
     } 
     fposition--; 
     fseek(file,fposition,SEEK_SET); 
     } 
     printLine(file, fposition); 
     fclose(file); 
    } 

    int main(int argc, char *argv[]) 
    { 
     FILE *file; 
     file= openFile(argv[2]); 
     walkFile(file, atol(argv[1])); 
     return 0; 
    } 

    /*Note: take in mind that i not wrote code to parse input options and arguments, neither code to check if the lines number argument is really a number.*/