码迷,mamicode.com
首页 > 系统相关 > 详细

linux下自实现简易tail命令

时间:2015-07-04 14:12:08      阅读:204      评论:0      收藏:0      [点我收藏+]

标签:

/*
    浏览单个文件,按行或者按字节
    格式: tail filename c/n num,目前不支持其他格式
*/
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
/*
    错误处理
*/
void oops(char *s1, char* s2)
{
    fprintf(stderr, "Error:%s", s1);
    perror(s2);
    exit(1);
}

/*
    按字节输出,name打开文件名,命令行字节数
*/
void print_c(char* name, int num)
{
    char buf[200];
    int fd, n;
    long size;
    
    fd = open(name, O_RDONLY);
    if (fd == -1)
        oops("can‘t open", name);
    size = lseek(fd, 0, SEEK_END);
    if (num < 0) 
        if (-num >= size)
            lseek(fd, 0, SEEK_SET);
        else
            lseek(fd, num, SEEK_END);
    else if (num >= size)
        lseek(fd, 0, SEEK_END);
    else
        lseek(fd, num, SEEK_SET);
    while (( n = read(fd, buf, 200)) > 0)
        if (write(STDOUT_FILENO, buf, n) != n)
            oops("write failed", "stdout");
    if (n == -1)
        oops("read failed", "input");
    close(fd);
}
/*
    按行输出,name文件名,num命令行行数
    按行输出,方法效率较低,先遍历文件统计所以行数,再确定输出位置
*/
void print_n(char *name, int num)
{
    char buf[200]; 
    FILE *fp;
    int n = 0;
    fp = fopen(name, "r");
    while (fgets(buf, 200, fp) != NULL)
        n++;
    rewind(fp);
    if (num < 0)
        num = n + num;
    if (num < 0)
        num = 0;
    while(num--)
        fgets(buf, 200, fp);
    while (1) {
        if (fgets(buf, 200, fp) == NULL)
            break;
        if (fputs(buf, stdout) == EOF)
            oops("write failed", "stdout");
    }
    fclose(fp);
}


int main(int argc, char* argv[])
{
    int num;
    FILE *fp;
    char cmd;
    if (argc < 3) {
        fprintf(stderr, "tail01: missing operand");
        exit(1);
    }
    if (argv[2][0] == ‘c‘ || argv[2][0] == ‘n‘)
        cmd = argv[2][0];
    else {
        fprintf(stderr, "operand error");
        exit(1);
    }
    num = atoi(argv[3]);
    if (argv[3][0] != ‘+‘&&argv[3][0] != ‘-‘)
        num = -num;
    switch(cmd) {
        case ‘c‘:
            print_c(argv[1], num);
            break;
        case ‘n‘:
            print_n(argv[1], num);
            break;            
        default:
            fprintf(stderr, "switch eror");
            exit(1);
    }
}

总结:

目前未实现其他功能

linux下自实现简易tail命令

标签:

原文地址:http://my.oschina.net/u/2313065/blog/474539

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!