linuxecho命令源代码
-
以下是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年前 -
以下是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年前 -
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年前