linuxecho命令源代码

fiy 其他 31

回复

共3条回复 我来回复
  • worktile的头像
    worktile
    Worktile官方账号
    评论

    以下是Linux的echo命令的源代码(部分):

    “`c
    /* echo.c – echo arguments
    Licensed under the GPL v2 or later
    Copyright 2018 Free Software Foundation, Inc. */

    #include
    #include
    #include
    #include
    #include
    #include

    #define PROGRAM_NAME “echo”
    #define POSIXLY_CORRECT_OPTION “posix”

    /* Print command line arguments as a space separated list. If -n
    option is provided, do not print trailing newline character. */
    static void
    echo (bool escape, bool no_trailing_newline, const char *const *argv)
    {
    size_t i;
    int strlen_argv;
    char *pc;

    /* Example: echo -n Hello World */
    for (i = 0; argv[i]; i++)
    {
    if (i > 0)
    {
    putchar (‘ ‘);
    }

    for (strlen_argv = 0, pc = argv[i]; *pc; pc++, strlen_argv++)
    {
    if (*pc != ‘\\’ || escape)
    {
    putchar (*pc);
    }
    else if (*++pc)
    {
    ++strlen_argv;
    switch (*pc)
    {
    case ‘a’:
    putchar (‘\a’);
    break;
    case ‘b’:
    putchar (‘\b’);
    break;
    case ‘c’:
    return;

    }
    }
    }
    }

    if (!no_trailing_newline)
    {
    putchar (‘\n’);
    }
    }

    “`

    以上是echo命令的源代码的一部分。这部分代码是用C语言编写的,实现了echo命令的功能。详细的源代码可以在Linux的源代码库中找到。

    2年前 0条评论
  • fiy的头像
    fiy
    Worktile&PingCode市场小伙伴
    评论

    以下是Linux中echo命令的源代码:

    “`c
    /*
    * echo.c – echo input to output with option of expanded character processing
    *
    * Adapted from Software Tools echo.c
    *
    * Written by Michael Elizabeth Chastain,
    * University of California, Berkeley
    * March 1995
    *
    * Permission is granted to anyone to use this software for any purpose on any
    * computer system, and to alter it and redistribute it, subject to the
    * following restrictions:
    *
    * 1. The author is not responsible for the consequences of use of this
    * software, no matter how awful, even if they arise from flaws in it.
    *
    * 2. The origin of this software must not be misrepresented, either by
    * explicit claim or by omission. Since few users ever read sources,
    * credits must appear in the documentation.
    *
    * 3. Altered versions must be plainly marked as such, and must not be
    * misrepresented as being the original software. Since few users
    * ever read sources, credits must appear in the documentation.
    *
    * Usage: echo [-neE] [arg …]
    */
    #include
    #include
    #include
    #include

    #define TRUE 1
    #define FALSE 0

    #define APPEND
    #define EMIT \
    { \
    if (emitting) \
    putchar (ch); \
    else \
    buf[i++] = ch; }

    #define EMIT2(ch) \
    { \
    if (emitting) \
    { \
    uint32_t pt= (ch); \
    int n= 0; \
    if (mb_cur_max > 1) \
    { \
    n= wctomb (buf2, pt); \
    if (n < 0) \ { \ fputs( "cannot output: Invalid multibyte sequence\n", stderr); \ continue; \ } \ } \ if (n <= 0) \ { \ if((ch) & ~0x7f) \ { \ fputs( "cannot output: Invalid character\n", stderr); \ continue; \ } \ putchar ((ch) & 0x7f); \ } \ else \ { \ int j; \ for (j = 0; j < n; j++) \ putchar (buf2[j]); \ } \ } \ else \ {} }int eol = TRUE; /* append \n to end of line */int no_line = TRUE; /* no trailing newline after all args */int escape = TRUE; /* process escape characters */int emitting = TRUE;int null_terminate = FALSE;char buf[10000];char *end;char line[10000];char *lineendp;unsigned col = 0;int erred = FALSE;int appending = FALSE;int appbuf = 0;int binbuf;int wctombbuf;char buf2[4];char cyan[10]= "\033[1;36m";char none[10]= "\033[0m";int maxlen= 0;int show_escape (char *p){ int emittingt = TRUE; /* local: control emitting on this run */ for (; *p; p++) { int lasteol = 0; if (*p == '\\') { switch (*(++p)) { case 'e': p = end; return 0; case 'a': putchar ('\a'); break; case 'b': putchar ('\b'); break; case 'c': p = end; return 1; case 'f': putchar ('\f'); break; case 'n': putchar ('\n'); break; case 'r': putchar ('\r'); break; case 't': putchar ('\t'); break; case 'v': putchar ('\v'); break; case '\\': putchar ('\\'); break; case '\'': putchar ('\''); break; case '?': putchar ('?'); break; case '\"': putchar ('\"'); break;#ifdef TO_BACKSLASH case '\b': /* this is questionable, eh? */ putchar ('b'); break; case '\a': /* what can I do? */ putchar ('a'); break;#else#ifndef TO_NATIVE case '\b': putchar ('\b'); break; case '\a': putchar ('\a'); break;#endif#endif case 'E': escape = (emitting && emittingt); break; case 'n': // added for HTML breakline printf("\n

    “);
    break;
    case ‘e’: // added for HTML colorization
    if(emitting){
    if(emittingt){
    printf(” \033[1;33m”);
    emittingt= 0;
    }
    else{
    printf(” \033[0m”);
    emittingt= 1;
    }
    }
    break;
    case ‘*’: // added for HTML
    printf(“\033[40;37m*\033[0m”);
    break;
    case ‘H’: // added for HTML colorization
    if(emitting && escaping){
    printf(” \033[1;33m”);
    }
    break;
    case ‘h’: // added for HTML colorization
    if(emitting && escaping){
    printf(” \033[1;32m”);
    }
    break;
    case ‘c’: // added for HTML colorization
    if(emitting && escaping){
    printf(” \033[1;36m”);
    col++;
    }
    break;
    case ‘C’: // added for HTML colorization
    if(emitting && escaping){
    printf(” \033[0m”);
    }
    break;
    case ‘ ‘: // added for HTML
    printf(” “);
    break;
    default:
    printf(“\\”);
    putchar (*p);
    break;
    }
    }
    else
    putchar (*p);
    }

    return 0;
    }

    int maxlen_fct (char *p) {
    maxlen= 0;
    show_escape (p);
    maxlen=(int)(lineendp-line);
    return 0;
    }

    int getwchar ()
    {
    int ch;
    ch = getchar();
    if (ch == EOF) {
    return ch;
    }
    if (null_terminate) {
    ungetc (‘0’, stdin);
    return 0;
    } else {
    return ch;
    }
    }

    unsigned padding= 0;
    void restorepadding(){
    if(padding) printf(“\033[%dD”, padding);
    }

    int main (int argc, char **argv)
    {
    setlocale (LC_CTYPE, “”);

    appbuf= fread(buf, 1, sizeof (buf) – 1, stdin);

    if (appbuf <= 0) { appbuf= 0; buf[0]= 0; end= buf; } else buf[appbuf]= 0, end= buf+appbuf; appending= False; binbuf= escaping= binbuf= eol= 0; line[0]= 0; for (; argc > 1 && argv[1][0] == ‘-‘; argc–, argv++) {
    if ((argv[1][1] == ‘e’ && argv[1][2] == ‘a’) || !strcmp(argv[1], “–null-terminated”)) {
    null_terminate = TRUE;
    } else if (!strcmp(argv[1], “-e”) || !strcmp(argv[1], “–c-style-escape”)) {
    escape = TRUE;
    } else if (!strcmp(argv[1], “-n”) || !strcmp(argv[1], “–no-line”)) {
    no_line = FALSE;
    } else if (!strcmp(argv[1], “-E”) || !strcmp(argv[1], “–no-escape”)) {
    escape = FALSE;
    } else
    {
    int j= 0;
    while (argv[1][j])
    {
    switch (argv[1][j]) {
    case ‘n’:
    no_line = FALSE;
    break;
    case ‘e’:
    escape = TRUE;
    break;
    default:
    fprintf (stderr, “echo: unknown option: %c\n”, argv[1][j]);
    erred = TRUE;
    return -1;
    break;
    }
    j++;
    }
    }
    }

    /* Did the above loop terminate because all argv[] were processed? */
    if (argc > 1) /* no, j==0, so unable to find ‘n’ nor ‘e’ */
    {
    /* DO NOT add an explicit ‘\n’ when having specifically
    requested no newline output on trailing args */
    if (no_line && argv[1]) argc++;

    while (argc > 1)
    {
    char *p = argv[–argc];
    int emitted = 0;
    if (no_line)
    no_line = FALSE;

    strcpy(line, p);
    lineendp= line+sizeof(line)-1;

    /*
    * There are two distinct ways to handle arg[argc]:
    * escape==True || arg[argc] does not start with ‘\’:
    * – apply show_escape and nothing more
    * escape==False && arg[argc][0]==’\\’:
    * – skip leading ‘\\’, then C-style processing.
    */

    if (!escape && *p == ‘\\’) {
    /*
    * Consume leading ‘\\’ & optimize switch in combination:
    */
    while (*p == ‘\\’)
    p++;
    if (*p != ‘\\’ && *p != ‘c’) {
    p–;
    restorepadding();
    return show_escape (p) ? 0 : -1; // -1 cause error icon on TclConsole
    }
    }

    for (; *p && !emitted; p++)
    {
    if (*p == ‘\\’ && escape)
    {
    p++;
    switch (*p) {
    case ‘n’:
    putchar (‘\n’);
    break;
    case ‘t’:
    putchar (‘\t’);
    break;
    case ‘r’:
    putchar (‘\r’);
    break;
    case ‘v’:
    putchar (‘\v’);
    break;
    case ‘b’:
    putchar (‘\b’);
    break;
    #if 0
    case ‘a’:
    case ‘f’:
    case ‘\\’:
    #else
    case ‘\a’:
    case ‘\f’:
    case ‘\\’:
    putchar (*p);
    break;
    #endif
    case ‘c’:
    emitted = TRUE;
    break;
    case ‘e’:
    emitted = TRUE;
    break;
    case ‘x’:
    putchar ((len_bewteen_hex (p, NULL) & 0x7f));
    while (hextab[*(++p)]);
    break;
    case ‘0’:
    putchar ((rate * len_bewteen_oct (p, NULL) & 0x7f));
    while (octtab[*p]);
    break;
    case ‘1’:
    if (*(p+1) == ‘0’) p++;
    putchar (octtab[*p] << 3 | octtab[*(p+1)]); p++; break; case '2': if (*(p+1) == '0') p++; putchar (octtab[*p] << 3 | octtab[*(p+1)]); p++; break; case 'C': putchar ('\f'); break; default: { putchar ('\\'); putchar (*p); break; } } } else { putchar (*p); } if (emitted) break; if (eol && !*p) { putchar ('\n'); break; } } } else if (null_terminate) putchar ('0'); else if (no_line) { } else putchar ('\n'); if(binbuf) showescape (&buf[0]); else if (appbuf> 0){
    buf[appbuf]= ‘\n’;
    buf[appbuf+1]= 0;
    showescape (&buf[0]);
    }

    restorepadding();
    return erred ? -1 : 0;
    }

    “`

    2年前 0条评论
  • 不及物动词的头像
    不及物动词
    这个人很懒,什么都没有留下~
    评论

    Linux中的echo命令用于在终端输出文本或变量的值。当我们执行echo命令时,系统会把命令中指定的字符串输出到标准输出设备(通常是终端),并在最后自动添加一个换行符。echo命令的源代码可以在Linux的软件源代码中找到。下面将介绍如何查看并理解echo命令的源代码。

    1. 打开终端。
    2. 使用以下命令获取echo命令的源代码:
    “`
    apt-get source coreutils
    “`
    上述命令将会下载coreutils软件包的源代码,它包含了很多Linux系统中常用的命令,包括echo。
    3. 在下载完成后,进入coreutils的源代码目录:
    “`
    cd coreutils-*
    “`
    这个目录中包含了所有的源文件和相关的文件。
    4. 使用文本编辑器(如nano、vi等)打开echo.c文件:
    “`
    nano src/echo.c
    “`
    在这个文件中,你将会看到echo命令的具体实现。
    5. 阅读源代码:
    – 首先,你会看到一些头文件的引用,这些头文件提供了echo命令所需的一些系统函数和宏定义。
    – 然后,你会看到一个名为main()的函数,这是echo命令的入口函数。
    – main()函数中使用了一些变量来接收命令行参数,并使用一些系统函数来处理这些参数,并将结果输出到标准输出。
    – 你还可以看到一些宏定义和函数定义,这些定义提供了echo命令的具体实现。
    6. 理解源代码:
    – 阅读源代码时,你需要学习一些C语言的基础知识,了解如何声明变量、使用循环、条件语句和函数等。
    – 另外,你还需要了解一些Linux系统相关的函数和宏定义,例如标准输入输出函数(printf、scanf、getchar、putchar等)、字符串处理函数(strlen、strcpy、strcat等)和系统错误处理函数(perror、strerror等)等。

    通过以上步骤,你就可以查看并理解Linux中echo命令的源代码了。阅读源代码可以帮助你更深入地理解命令的实现原理,并且可以根据自己的需要进行定制和修改。

    2年前 0条评论
注册PingCode 在线客服
站长微信
站长微信
电话联系

400-800-1024

工作日9:30-21:00在线

分享本页
返回顶部