답변
꼬리 유틸리티는 리눅스에로 coreutils의 일부입니다.
- 소스 타르볼 : ftp://ftp.gnu.org/gnu/coreutils/coreutils-7.4.tar.gz
- 소스 파일 : 나는 항상 FreeBSD의는 GNU 유틸리티보다 훨씬 명확하게 소스 코드를 발견했습니다 http://git.savannah.gnu.org/cgit/coreutils.git/tree/src/tail.c
. 그래서 여기에 FreeBSD 프로젝트에 tail.c의 :
uClinux는 사이트 찌를. 그들은 소프트웨어를 배포했기 때문에 소스를 다른 방법으로 사용할 수 있도록해야합니다.
또는, man fseek
을 읽고 그것을 할 수있는 방법을 추측 할 수있다. 당신이 찾는 사용할 수없는 경우
아래 NB-- 참조 윌리엄의 코멘트 경우가 있습니다.
꼬리는 fseek는 사용하지 않습니다. 그럴 경우 스트림에서 작동하지 않습니다 (예 : 'grep pat file | tail') –
흠, 결코 그런 생각을하지 않았습니다. 감사. 나는 seekable 입력으로 작업 할 때 여전히 더 빠를 것이라고 생각해야한다. – dmckee
이것은 사실이 아닙니다. '꼬리'는 * 항상 * 검색을 사용하지 않습니다 .- 원래의 질문은 리눅스 유틸리티에 관한 것이지만 –
당신은 그것을 직접 작성 흥미로운 운동을 찾을 수 있습니다. Unix 명령 행 도구의 대다수는 상당히 단순한 C 코드의 한 페이지 정도입니다.
그냥 코드를 보면하려면 GNU로 coreutils 소스는 쉽게 gnu.org 또는 좋아하는 리눅스 미러 사이트에서 찾을 수 있습니다.
Linux가 초기 단계에있을 때 MS-DOS 용 도구를 상당히 완벽하게 작성했습니다. 많은 사람들이 분명히 똑바로 서 있지만 "페이지"라고 말하기를 망설이고 "대다수"라고 말하지 않을 것입니다. ** find ** 및 ** ls ** 예를 들어, 상당히 복잡했습니다. – NVRAM
코어 대부분의 도구는 일반적으로 * 짧습니다. 그러나 인수 처리 및 구석 처리는 고통 스러울 수 있습니다. – dmckee
네, 아마도 "많은"도구가 짧고 단순하다고 말했을 것입니다 .GNU 꼬리에는 많은 옵션이 있습니다. 아마도 "단순한"범주에 맞지 않을 것입니다. 대부분의 사람들이 사용할 꼬리의 버전 (tail-xxx 파일 또는 tail -f 파일)은 꽤 간단합니다. –
/`*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.*/
+1은 다양성을 나타냅니다. –
나는 리눅스 버전이 BSD 버전보다 몇 배 더 긴 것을 좋아한다. –
모든 작업을 수행하는 함수가 해당 파일에 없기 때문에 BSD 버전이 더 짧습니다. 즉 : follow(). –