linux下的wc命令的源代码
- 格式:docx
- 大小:26.20 KB
- 文档页数:19
实验一Linux常用命令(一)1、Shell环境和Shell命令格式如果实验用计算机上Linux以图形方式启动,登录系统后打开终端窗口。
方法:桌面:右键菜单-Terminal(终端);或:主菜单-系统工具-Terminal(终端)。
命令格式:command [-option(s)] [option argument(s)] [command argument(s)]步骤1:使用who命令步骤2:使用date命令步骤3:使用上下健提取历史命令who,执行。
2、文件系统操作命令(1)改变目录命令:cd 目标目录路径步骤1:使用绝对路径依次进入Linux根目录下的所有子目录。
例如:cd /usr/bin步骤2:使用绝对路径依次进入用户目录。
步骤3:使用相对路径进入子目录1)使用绝对路径进入/lib目录2)使用相对路径进入/lib/i868目录3)使用相对路径退回到/lib目录(2)列出并观察目录中的文件步骤1:进入任意目录,使用无参数ls命令列出并观察其中所有文件;步骤2:进入任意目录,使用通配符列出其中部分文件;例如:cd /binls c*步骤3:使用-l选项,列出目录中文件的各种属性,并观察识别这些属性。
步骤4:直接列出子目录中的文件。
例如:ls i868步骤5:仅列出子目录本身(-d)步骤6:使用-F选项,显示文件类型标志。
步骤7:使用-a或-A选项,观察结果有什么变化。
步骤8:综合使用以上选项。
(3)目录的创建与删除步骤1:在用户目录中,使用相对路径创建一个任意名称的目录,如“tmp”。
mkdir tmp步骤2:删除该目录rmdir tmp步骤3:在根目录中,使用绝对路径在用户命令中创建一个子目录。
mkdir ~/tmp步骤4:删除该目录rmdir ~/tmp步骤5:使用-p参数一次创建多级目录。
如:mkdir ~/tmp/dir1步骤6:使用-p参数删除多级目录。
如:cd ~rmdir tmp/dir1(4)文件和目录拷贝命令:cp步骤1:从/usr/include目录中,任选一个文件拷贝到用户目录的tmp子目录中mkdir ~/tmpcp /usr/include/signal.h ~/tmp步骤2:从/usr/include目录中,任选一个文件拷贝到用户目录的tmp子目录中,并改变其文件名。
linux gcc编译win32程序如何通过Linux GCC编译Win32程序在跨平台开发中,有时候我们可能需要在Linux操作系统上编译Windows 平台的程序。
虽然Windows和Linux是两种截然不同的操作系统,但是通过使用GCC编译器和一些工具,我们仍然可以完成这个任务。
在本文中,我将向您展示一步一步使用Linux GCC编译Win32程序的过程。
请按照以下步骤进行操作。
步骤1:安装GCC编译器首先,确保您的Linux系统中已经安装了GCC编译器。
如果没有安装,可以通过以下命令在终端中进行安装:shellsudo apt-get install build-essential这条命令将会安装GCC编译器以及相关的开发工具。
步骤2:安装MinGW工具链MinGW是一个在Windows上运行的开发工具链集合,可以用来编译Windows平台的可执行文件。
我们将在Linux上使用MinGW工具链来编译Windows程序。
您可以通过以下命令在终端中进行安装:shellsudo apt-get install mingw-w64这条命令将会安装MinGW工具链。
步骤3:创建Win32交叉编译环境现在,我们需要为GCC编译器创建一个Win32交叉编译环境。
在终端中运行以下命令:shellsudo update-alternatives config x86_64-w64-mingw32-gcc该命令将显示一个列表,列出了可用的编译器版本。
选择与您的系统架构相对应的gcc版本。
按照提示进行选择。
步骤4:编写Win32程序在准备好编译环境后,我们可以开始编写Win32程序。
创建一个C语言源文件,比如"hello.c",并输入以下代码:c#include <windows.h>#include <stdio.h>int WINAPI WinMain(HINSTANCE hInstance, HINSTANCEhPrevInstance, LPSTR lpCmdLine, int nCmdShow) {MessageBoxA(NULL, "Hello World!", "Hello", MB_OK);return 0;}这是一个简单的Win32程序,用于显示一个消息框。
⼀天⼀个shell命令linux⽂本操作系列-wc命令详解
全称
wc是⼀个⽤于统计的⼯具,全拼为:Word Count(单词统计)
实例:
1. 统计⾏数
$wc –l file
2. 统计单词数
$wc –w file
3. 统计字符数
$wc –c file
4. 统计流中的字符数
$echo –n 1234 | wc –c
输出:4
解读--help
⽤法:wc [选项]... [⽂件]...
或:wc [选项]... --files0-from=F
打印每⾏的换⾏符,单词,字节的数量,如果多于⼀个⽂件,则打印每个总⾏数。
如果没有⽂件,或者⽂件位置⽤“-”表⽰,则读取标准流。
⼀个单词是由空⽩符分隔的⾮零长的字符序列下⾯的操作可能⽤于选择某种类型数量的打印,通常顺序是换⾏符,单词,字符,字节,最⼤⾏的长度
-c, --bytes 打印字节数
-m, --chars 打印字符数
-l, --lines 打印换⾏符,即总⾏数
--files0-from=⽂件从指定⽂件读取以NUL 终⽌的名称,如果该⽂件被
指定为"-"则从标准输⼊读⽂件名
-L, --max-line-length 显⽰最长⾏的长度
-w, --words 显⽰单词计数
--help 显⽰此帮助信息并退出
--version 显⽰版本信息并退出
解读:
1. 多于⼀个⽂件
$wc file1 file2
打印两个⽂件的分别的统计⾏数
2. –L
打印最长的⾏数的字符数,即长度
3. 直接wc ⽂件,⽆任何参数
顺序是⾏数,单词,字符,字节,最⼤⾏长度。
Linux命令高级技巧使用xargs命令进行命令参数的灵活处理和传递Linux命令高级技巧:使用xargs命令进行命令参数的灵活处理和传递Linux是一种自由和开放源代码的类Unix操作系统,广泛应用于服务器领域。
在Linux中,命令行是基本操作方式之一,灵活运用各种命令可以提高工作效率。
本文将介绍Linux命令高级技巧之一:使用xargs命令进行命令参数的灵活处理和传递。
一、xargs命令简介xargs命令是一个强大的命令,可以将标准输入的数据转换为命令行参数,实现对命令参数的灵活处理和传递。
它通常与其他命令(如grep、find等)配合使用,能够处理大量的参数,提高命令的执行效率。
二、基本使用方法xargs命令的基本使用方法如下:```command | xargs [options] [command]```其中,command代表要执行的命令,可以是任意的Linux命令。
options是一些可选参数,可以用于调整xargs命令的行为。
[command]是可选的,如果不指定,则默认为echo命令。
三、参数处理示例以下是一些使用xargs命令进行参数处理的示例:1. 使用xargs命令传递参数假设我们有一个文件列表filelist.txt,里面包含了一些文件名,每行一个文件。
我们可以使用xargs命令将这些文件名作为参数传递给另一个命令进行处理。
例如,我们可以使用xargs命令将这些文件复制到指定目录:```cat filelist.txt | xargs -I {} cp {} /path/to/destination/```其中,-I {}表示将每行的文件名替换成{},然后将替换后的参数传递给cp命令进行处理。
2. 使用xargs命令处理find命令的输出find命令用于在文件系统中搜索文件和目录。
假设我们希望在当前目录及其子目录中找到所有后缀名为.txt的文件,并统计它们的行数。
我们可以将find命令的输出通过管道传递给xargs命令,并使用wc命令统计行数:```find ./ -type f -name "*.txt" | xargs wc -l```以上命令将在当前目录及其子目录中搜索后缀名为.txt的文件,并统计它们的行数。
渗透利器(第⼀章-2)kalilinux基础命令讲解介绍认识Linux什么是shellshell与终端的区别Linux常⽤命令Linux中⽂件与⽬录的权限什么是shell在计算机科学中,shell俗称外壳(⽤来区别于内核),它类似于windows的dos,能够接收⽤户的命令并翻译给操作系统执⾏,是⽤户与操作系统(内核)之间的桥梁查看shell查看系统⽀持那些shellcat/etc/shells查看正在使⽤的shellecho $SHELLshell与终端的区别终端:接受⽤户的输⼊,并传递给shell程序,接受程序输出并展⽰到屏幕shell:接受并解析⽤户的命令给操作系统执⾏,将结果输出到终端使⽤vim编辑器VM编辑器是所有Unix及Linux系统下标准的编辑器,他就相当于windows系统中的记事本⼀样,它的强⼤不逊⾊于任何最新的⽂本编辑器。
他是我们使⽤Linux系统不能缺少的⼯具。
vim具有程序编辑的能⼒,可以以字体颜⾊辨别语法的正确性,⽅便程序设计;vim可以当作vi的升级版本,他可以⽤多种颜⾊的⽅式来显⽰⼀些特殊的信息。
vim会依据⽂件扩展名或者是⽂件内的开头信息,判断该⽂件的内容⽽⾃动的执⾏该程序的语法判断式,再以颜⾊来显⽰程序代码与⼀般信息。
vim⾥⾯加⼊了很多额外的功能,例如⽀持正则表达式的搜索、多⽂件编辑、块复制等等。
这对于我们在Linux上进⾏⼀些配置⽂件的修改⼯作时是很棒的功能。
vi/vim编辑器模式命令模式(默认):刚进⼊vim的时候,默认就是命令模式,可以复制⾏,删除⾏等。
输⼊模式- +命令模式 ESC键输⼊模式:可以输⼊内容。
关闭、保存⽂件模式转换 shift键+:号使⽤insert键切换进⼊输⼊模式命令模式下:命令模式-→输⼊模式:W:保存.i:在当前光标所在字符的前⾯,转为输⼊模式 q:退出I:在当前光标所在⾏的⾏⾸转换为输⼊模式 wq和x都是保存退出a:在当前光标所在字符的后⾯,转为输⼊模式 q! :强制退出A:在光标所在⾏的⾏尾,转换为输⼊模式 w! :强制保存,管理员才有权限o:在当前光标所在⾏的下⽅,新建⼀⾏,并转为输⼊模式0:在当前光标所在⾏的上⽅,新建-⾏,并转为输⼊模式查找s:删除光标所在字符普通模式:r:替换光标处字符 /PATTERN:从当前位置向后查找PATTERN: 从当前位置向前查找date命令date命令⽤于显⽰及设置系统的时间或⽇期,格式为“date [选项] [+指定的格式]”。
curl linux编译curl是一个非常流行的开源网络库,它支持多种协议(如HTTP、FTP、SMTP等)和常见的加密方式(如SSL、TLS等),并提供易于使用的命令行工具,用于在Linux系统上进行网络通信。
下面是关于在Linux上编译curl的指南。
1. 下载curl源代码首先,你需要从curl官方网站下载源代码。
你可以使用以下命令:$ wget https://curl.se/download/curl-7.79.1.tar.gz 这个命令将从curl官方网站下载curl-7.79.1版本的源代码,并将其保存为curl-7.79.1.tar.gz文件。
2. 解压缩源代码下载完成后,你需要解压缩源代码。
你可以使用以下命令:$ tar -xzvf curl-7.79.1.tar.gz这个命令将解压缩curl-7.79.1.tar.gz文件,并将源代码保存在一个名为curl-7.79.1的目录中。
3. 配置编译选项接下来,你需要配置curl的编译选项。
你可以使用以下命令: $ cd curl-7.79.1$ ./configure这个命令将执行一个脚本,用于检查你的系统并确定最佳的编译选项。
如果一切正常,你将看到一个类似下面的输出:......configure: Configured to build curl/libcurl:configure: CC: gccconfigure: CFLAGS: -g -O2 -Wdeclaration-after-statement configure: CPPFLAGS:configure: LD: gccconfigure: LDFLAGS:注意,你可能需要在configure命令中添加一些选项,以适应你的特定需求。
你可以查看configure的帮助文档,以获取更多信息:$ ./configure --help4. 编译和安装完成配置后,你可以开始编译curl。
linuxgcc命令及用法Linux的gcc命令是一款非常强大的编译器,用于将源代码转换为可执行文件。
本文将详细介绍gcc命令及其常用的用法,帮助读者更好地理解和使用这款工具。
一、gcc命令的基本语法结构gcc是GNU Compiler Collection(GNU编译器集合)的简称,因此其命令基本语法结构一般为:shellgcc [选项] [输入文件]其中,选项用于指定编译时的相关参数,输入文件则是需要编译的源文件。
二、gcc命令的常用选项gcc命令提供了许多选项,用于控制编译过程及生成的可执行文件的属性。
下面是一些常用的gcc选项及其作用:1. -o:用于指定输出文件的名称。
例如,使用`-o myprogram`选项将输出文件命名为myprogram。
2. -c:仅进行编译,不进行链接操作。
这个选项常用于编译多个源文件时,先将每个源文件编译为目标文件,再进行链接操作。
3. -g:生成调试信息。
这个选项会在编译时生成与调试器兼容的调试信息,方便开发人员进行程序调试。
4. -Wall:显示所有警告信息。
使用这个选项可以使编译器在编译时输出更多的警告信息,帮助开发人员提前发现潜在的问题。
5. -I:指定头文件的搜索路径。
使用这个选项可以告诉编译器在指定的路径中查找头文件,方便引用外部库、模块等。
6. -L:指定库文件的搜索路径。
与-I选项类似,这个选项用于告诉编译器在指定的路径中查找库文件,用于链接时的库文件搜索。
7. -l:指定要链接的库文件。
使用这个选项可以显式地告诉编译器要链接的库文件,如:-lmath将链接math库文件。
三、gcc命令的应用实例下面通过几个实例来演示gcc命令的具体用法,以帮助读者更好地理解和掌握这款工具。
1. 编译单个源文件并生成可执行文件假设我们有一个名为`hello.c`的源文件,内容如下:c#include <stdio.h>int main() {printf("Hello, World!\n");return 0;}我们可以使用以下命令将其编译为可执行文件`hello`:shellgcc -o hello hello.c编译成功后,即可在当前目录下生成名为`hello`的可执行文件。
linux中⽇志⽂件查找,根据关键字,vi命令,awk和wc当时需求:查看系统⽇志,统计系统的处理时间(从请求进去系统到系统返回)⽇志⽂件: 1.log开始处理:1. 将⽇志中的关键⾏(初始、结束、关键节点)打印出来/输出到⽂件(后添加:>2.log): cat 1.log | grep key //根据关键字输出 cat 1.log | egrep '(start handle)+|(end handle)+' //根据两个关键字如果不能⼀次查找出来(线程数较多),可以先输出到⽂件,再重复根据线程名查找⼀次。
grep最常⽤的分组,egrep可以使⽤更多的正则符号,fgrep可以认为就是不使⽤正则字符(应该可以这么理解,原⽂:正则表达式中的元字符表⽰回其⾃⾝的字⾯意义,不再特殊)。
cat 1.log | grep key 可以写为: grep key 1.log ,同理。
awk和wc命令ps -ef | grep java | awk '{print $2}' : 可以显⽰出所有Java进程的pid,awk中可以默认使⽤空⽩分隔符,可以使⽤awk -F,指定分隔符,其中$2就是分割后输出第⼆个字符串,ps -ef | grep java | awk '{print $2}' | wc -l : 可以统计当前⼀共有多少Java进程wc中-c 统计字节数,-l 统计⾏数,-m 统计字符数,这个标志不能与 -c 标志⼀起使⽤,-w 统计字数。
⼀个字被定义为由空⽩、跳格或换⾏字符分隔的字符串。
-L 打印最长⾏的长度。
VI中//以下删除命令好多都是剪贴,删除应该就是剪贴吧。
Ctrl+u:向⽂件⾸翻半屏;Ctrl+d:向⽂件尾翻半屏;Ctrl+f:向⽂件尾翻⼀屏;Ctrl+b:向⽂件⾸翻⼀屏;Esc:从编辑模式切换到命令模式;ZZ:命令模式下保存当前⽂件所做的修改后退出vi;:⾏号:光标跳转到指定⾏的⾏⾸;:$:光标跳转到最后⼀⾏的⾏⾸;x或X:删除⼀个字符,x删除光标后的,⽽X删除光标前的;D:删除从当前光标到光标所在⾏尾的全部字符;dd:删除光标⾏正⾏内容;ndd:删除当前⾏及其后n-1⾏;nyy:将当前⾏及其下n⾏的内容保存到寄存器?中,其中?为⼀个字母,n为⼀个数字;p:粘贴⽂本操作,⽤于将缓存区的内容粘贴到当前光标所在位置的下⽅;P:粘贴⽂本操作,⽤于将缓存区的内容粘贴到当前光标所在位置的上⽅;/字符串:⽂本查找操作,⽤于从当前光标所在位置开始向⽂件尾部查找指定字符串的内容,查找的字符串会被加亮显⽰;name:⽂本查找操作,⽤于从当前光标所在位置开始向⽂件头部查找指定字符串的内容,查找的字符串会被加亮显⽰;a,bs/F/T:替换⽂本操作,⽤于在第a⾏到第b⾏之间,将F字符串换成T字符串。
linux c语言好玩的代码Linux操作系统下的C语言编程提供了许多有趣的代码实现,让程序员们可以在编写代码的过程中获得乐趣与挑战。
本文将介绍一些有趣的Linux C语言代码示例,帮助读者更好地理解和掌握这些代码的实现原理。
一、彩色输出文本在Linux终端中,我们可以使用ANSI转义序列来实现彩色输出文本。
通过在输出文本前插入相应的转义序列,可以改变文本的颜色、背景色和样式。
下面是一个简单的示例代码,实现了在终端中输出彩色的 "Hello World!" 文本。
```c#include <stdio.h>#define COLOR_RED "\x1b[31m"#define COLOR_GREEN "\x1b[32m"#define COLOR_YELLOW "\x1b[33m"#define COLOR_BLUE "\x1b[34m"#define COLOR_MAGENTA "\x1b[35m"#define COLOR_CYAN "\x1b[36m"#define COLOR_RESET "\x1b[0m"int main() {printf(COLOR_RED "Hello " COLOR_GREEN "World!" COLOR_RESET "\n");return 0;}```在这段代码中,我们使用了一些预定义的ANSI转义序列来定义不同的颜色。
通过在输出文本前插入相应的转义序列,可以改变输出文本的颜色。
通过这种方式,我们可以在终端中实现彩色的输出效果。
二、生成随机数在C语言中,我们可以使用rand()函数生成一个伪随机数序列。
下面是一个简单的示例代码,实现了生成一个1到100之间的随机数。
Bootsect.s(1-9)!! SYS_SIZE is the number of clicks (16 bytes) to be loaded.! 0x3000 is 0x30000 bytes = 196kB, more than enough for current! versions of linux ! SYS_SIZE 是要加载的节数(16 字节为1 节)。
0x3000 共为1 2 3 4 5 60x7c000x00000x900000x100000xA0000system 模块代码执行位置线路0x90200! 0x30000 字节=192 kB(上面Linus 估算错了),对于当前的版本空间已足够了。
!SYSSIZE = 0x3000 ! 指编译连接后system 模块的大小。
参见列表1.2 中第92 的说明。
! 这里给出了一个最大默认值。
!! bootsect.s (C) 1991 Linus Torvalds!! bootsect.s is loaded at 0x7c00 by the bios-startup routines, and moves! iself out of the way to address 0x90000, and jumps there.!! It then loads 'setup' directly after itself (0x90200), and the system! at 0x10000, using BIOS interrupts.!! NOTE! currently system is at most 8*65536 bytes long. This should be no! problem, even in the future. I want to keep it simple. This 512 kB! kernel size should be enough, especially as this doesn't contain the! buffer cache as in minix!! The loader has been made as simple as possible, and continuos! read errors will result in a unbreakable loop. Reboot by hand. It! loads pretty fast by getting whole sectors at a time whenever possible.!! 以下是前面这些文字的翻译:! bootsect.s (C) 1991 Linus Torvalds 版权所有!! bootsect.s 被bios-启动子程序加载至0x7c00 (31k)处,并将自己! 移到了地址0x90000 (576k)处,并跳转至那里。
/* wc - print the number of lines, words, and bytes in filesCopyright (C) 1985, 1991, 1995-2010 Free Software Foundation, Inc.This program is free software: you can redistribute it and/or modifyit under the terms of the GNU General Public License as published bythe Free Software Foundation, either version 3 of the License, or(at your option) any later version.This program is distributed in the hope that it will be useful,but WITHOUT ANY WARRANTY; without even the implied warranty ofMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See theGNU General Public License for more details.You should have received a copy of the GNU General Public Licensealong with this program. If not, see </licenses/>. */ /* Written by Paul Rubin, phr@and David MacKenzie, djm@. */#include <config.h>#include <stdio.h>#include <assert.h>#include <getopt.h>#include <sys/types.h>#include <wchar.h>#include <wctype.h>#include "system.h"#include "argv-iter.h"#include "error.h"#include "mbchar.h"#include "physmem.h"#include "quote.h"#include "quotearg.h"#include "readtokens0.h"#include "safe-read.h"#include "xfreopen.h"#if !defined iswspace && !HAVE_ISWSPACE# define iswspace(wc) \((wc) == to_uchar (wc) && isspace (to_uchar (wc)))#endif/* The official name of this program (e.g., no `g' prefix). */#define PROGRAM_NAME "wc"#define AUTHORS \proper_name ("Paul Rubin"), \proper_name ("David MacKenzie")/* Size of atomic reads. */#define BUFFER_SIZE (16 * 1024)/* Cumulative number of lines, words, chars and bytes in all files so far.max_line_length is the maximum over all files processed so far. */ static uintmax_t total_lines;static uintmax_t total_words;static uintmax_t total_chars;static uintmax_t total_bytes;static uintmax_t max_line_length;/* Which counts to print. */static bool print_lines, print_words, print_chars, print_bytes;static bool print_linelength;/* The print width of each count. */static int number_width;/* True if we have ever read the standard input. */static bool have_read_stdin;/* The result of calling fstat or stat on a file descriptor or file. */struct fstatus{/* If positive, fstat or stat has not been called yet. Otherwise, this is the value returned from fstat or stat. */int failed;/* If FAILED is zero, this is the file's status. */struct stat st;};/* For long options that have no equivalent short option, use a non-character as a pseudo short option, starting with CHAR_MAX + 1. */ enum{FILES0_FROM_OPTION = CHAR_MAX + 1};static struct option const longopts[] ={{"bytes", no_argument, NULL, 'c'},{"chars", no_argument, NULL, 'm'},{"lines", no_argument, NULL, 'l'},{"words", no_argument, NULL, 'w'},{"files0-from", required_argument, NULL, FILES0_FROM_OPTION}, {"max-line-length", no_argument, NULL, 'L'},{GETOPT_HELP_OPTION_DECL},{GETOPT_VERSION_OPTION_DECL},{NULL, 0, NULL, 0}};voidusage (int status){if (status != EXIT_SUCCESS)fprintf (stderr, _("Try `%s --help' for more information.\n"),program_name);else{printf (_("\Usage: %s [OPTION]... [FILE]...\n\or: %s [OPTION]... --files0-from=F\n\"),program_name, program_name);fputs (_("\Print newline, word, and byte counts for each FILE, and a total line if\n\more than one FILE is specified. With no FILE, or when FILE is -,\n\read standard input.\n\-c, --bytes print the byte counts\n\-m, --chars print the character counts\n\-l, --lines print the newline counts\n\"), stdout);fputs (_("\--files0-from=F read input from the files specified by\n\NUL-terminated names in file F;\n\If F is - then read names from standard input\n\ -L, --max-line-length print the length of the longest line\n\-w, --words print the word counts\n\"), stdout);fputs (HELP_OPTION_DESCRIPTION, stdout);fputs (VERSION_OPTION_DESCRIPTION, stdout);emit_ancillary_info ();}exit (status);}/* FILE is the name of the file (or NULL for standard input)associated with the specified counters. */static voidwrite_counts (uintmax_t lines,uintmax_t words,uintmax_t chars,uintmax_t bytes,uintmax_t linelength,const char *file){static char const format_sp_int[] = " %*s";char const *format_int = format_sp_int + 1;char buf[INT_BUFSIZE_BOUND (uintmax_t)];if (print_lines){printf (format_int, number_width, umaxtostr (lines, buf));format_int = format_sp_int;}if (print_words){printf (format_int, number_width, umaxtostr (words, buf));format_int = format_sp_int;}if (print_chars){printf (format_int, number_width, umaxtostr (chars, buf));format_int = format_sp_int;}if (print_bytes){printf (format_int, number_width, umaxtostr (bytes, buf));format_int = format_sp_int;}if (print_linelength){printf (format_int, number_width, umaxtostr (linelength, buf));}if (file)printf (" %s", file);putchar ('\n');}/* Count words. FILE_X is the name of the file (or NULL for standard input) that is open on descriptor FD. *FSTATUS is its status.Return true if successful. */static boolwc (int fd, char const *file_x, struct fstatus *fstatus){bool ok = true;char buf[BUFFER_SIZE + 1];size_t bytes_read;uintmax_t lines, words, chars, bytes, linelength;bool count_bytes, count_chars, count_complicated;char const *file = file_x ? file_x : _("standard input");lines = words = chars = bytes = linelength = 0;/* If in the current locale, chars are equivalent to bytes, we prefer counting bytes, because that's easier. */#if MB_LEN_MAX > 1if (MB_CUR_MAX > 1){count_bytes = print_bytes;count_chars = print_chars;}else#endif{count_bytes = print_bytes || print_chars;count_chars = false;}count_complicated = print_words || print_linelength;/* When counting only bytes, save some line- and word-counting overhead. If FD is a `regular' Unix file, using lseek is enoughto get its `size' in bytes. Otherwise, read blocks of BUFFER_SIZEbytes at a time until EOF. Note that the `size' (number of bytes)that wc reports is smaller than stats.st_size when the file is notpositioned at its beginning. That's why the lseek calls below arenecessary. For example the command`(dd ibs=99k skip=1 count=0; ./wc -c) < /etc/group'should make wc report `0' bytes. */if (count_bytes && !count_chars && !print_lines && !count_complicated) {off_t current_pos, end_pos;if (0 < fstatus->failed)fstatus->failed = fstat (fd, &fstatus->st);if (! fstatus->failed && S_ISREG (fstatus->st.st_mode)&& (current_pos = lseek (fd, (off_t) 0, SEEK_CUR)) != -1&& (end_pos = lseek (fd, (off_t) 0, SEEK_END)) != -1){/* Be careful here. The current position may actually bebeyond the end of the file. As in the example above. */ bytes = end_pos < current_pos ? 0 : end_pos - current_pos;}else{while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0){if (bytes_read == SAFE_READ_ERROR){error (0, errno, "%s", file);ok = false;break;}bytes += bytes_read;}}}else if (!count_chars && !count_complicated){/* Use a separate loop when counting only lines or lines and bytes -- but not chars or words. */while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0){char *p = buf;if (bytes_read == SAFE_READ_ERROR){error (0, errno, "%s", file);ok = false;break;}while ((p = memchr (p, '\n', (buf + bytes_read) - p))){++p;++lines;}bytes += bytes_read;}}#if MB_LEN_MAX > 1# define SUPPORT_OLD_MBRTOWC 1else if (MB_CUR_MAX > 1){bool in_word = false;uintmax_t linepos = 0;DECLARE_ZEROED_AGGREGATE (mbstate_t, state);bool in_shift = false;# if SUPPORT_OLD_MBRTOWC/* Back-up the state before each multibyte character conversion and move the last incomplete character of the buffer to the frontof the buffer. This is needed because we don't know whetherthe `mbrtowc' function updates the state when it returns -2, -this is the ISO C 99 and glibc-2.2 behaviour - or not - amendedANSI C, glibc-2.1 and Solaris 5.7 behaviour. We don't have anautoconf test for this, yet. */size_t prev = 0; /* number of bytes carried over from previous round */ # elseconst size_t prev = 0;# endifwhile ((bytes_read = safe_read (fd, buf + prev, BUFFER_SIZE - prev)) > 0){const char *p;# if SUPPORT_OLD_MBRTOWCmbstate_t backup_state;# endifif (bytes_read == SAFE_READ_ERROR){error (0, errno, "%s", file);ok = false;break;}bytes += bytes_read;p = buf;bytes_read += prev;do{wchar_t wide_char;size_t n;if (!in_shift && is_basic (*p)){/* Handle most ASCII characters quickly, without callingmbrtowc(). */n = 1;wide_char = *p;}else{in_shift = true;# if SUPPORT_OLD_MBRTOWCbackup_state = state;# endifn = mbrtowc (&wide_char, p, bytes_read, &state);if (n == (size_t) -2){# if SUPPORT_OLD_MBRTOWCstate = backup_state;# endifbreak;}if (n == (size_t) -1){/* Remember that we read a byte, but don't complainabout the error. Because of the decoding error,this is a considered to be byte but not acharacter (that is, chars is not incremented). */p++;bytes_read--;continue;}if (mbsinit (&state))in_shift = false;if (n == 0){wide_char = 0;n = 1;}}p += n;bytes_read -= n;chars++;switch (wide_char){case '\n':lines++;/* Fall through. */case '\r':case '\f':if (linepos > linelength)linelength = linepos;linepos = 0;goto mb_word_separator;case '\t':linepos += 8 - (linepos % 8);goto mb_word_separator;case ' ':linepos++;/* Fall through. */case '\v':mb_word_separator:words += in_word;in_word = false;break;default:if (iswprint (wide_char)){int width = wcwidth (wide_char);if (width > 0)linepos += width;if (iswspace (wide_char))goto mb_word_separator;in_word = true;}break;}}while (bytes_read > 0);# if SUPPORT_OLD_MBRTOWCif (bytes_read > 0){if (bytes_read == BUFFER_SIZE){/* Encountered a very long redundant shift sequence. */p++;bytes_read--;}memmove (buf, p, bytes_read);}prev = bytes_read;# endif}if (linepos > linelength)linelength = linepos;words += in_word;}#endifelse{bool in_word = false;uintmax_t linepos = 0;while ((bytes_read = safe_read (fd, buf, BUFFER_SIZE)) > 0) {const char *p = buf;if (bytes_read == SAFE_READ_ERROR){error (0, errno, "%s", file);ok = false;break;}bytes += bytes_read;do{switch (*p++){case '\n':lines++;/* Fall through. */case '\r':case '\f':if (linepos > linelength)linelength = linepos;linepos = 0;goto word_separator;case '\t':linepos += 8 - (linepos % 8);goto word_separator;case ' ':linepos++;/* Fall through. */case '\v':word_separator:words += in_word;in_word = false;break;default:if (isprint (to_uchar (p[-1]))){linepos++;if (isspace (to_uchar (p[-1])))goto word_separator;in_word = true;}break;}}while (--bytes_read);}if (linepos > linelength)linelength = linepos;words += in_word;}if (count_chars < print_chars)chars = bytes;write_counts (lines, words, chars, bytes, linelength, file_x); total_lines += lines;total_words += words;total_chars += chars;total_bytes += bytes;if (linelength > max_line_length)max_line_length = linelength;return ok;}static boolwc_file (char const *file, struct fstatus *fstatus){if (! file || STREQ (file, "-")){have_read_stdin = true;if (O_BINARY && ! isatty (STDIN_FILENO))xfreopen (NULL, "rb", stdin);return wc (STDIN_FILENO, file, fstatus);}else{int fd = open (file, O_RDONLY | O_BINARY);if (fd == -1){error (0, errno, "%s", file);return false;}else{bool ok = wc (fd, file, fstatus);if (close (fd) != 0){error (0, errno, "%s", file);return false;}return ok;}}}/* Return the file status for the NFILES files addressed by FILE.Optimize the case where only one number is printed, for just onefile; in that case we can use a print width of 1, so we don't needto stat the file. Handle the case of (nfiles == 0) in the same way;that happens when we don't know how long the list of file names will be. */ static struct fstatus *get_input_fstatus (int nfiles, char *const *file){struct fstatus *fstatus = xnmalloc (nfiles ? nfiles : 1, sizeof *fstatus);if (nfiles == 0|| (nfiles == 1&& ((print_lines + print_words + print_chars+ print_bytes + print_linelength)== 1)))fstatus[0].failed = 1;else{int i;for (i = 0; i < nfiles; i++)fstatus[i].failed = (! file[i] || STREQ (file[i], "-")? fstat (STDIN_FILENO, &fstatus[i].st): stat (file[i], &fstatus[i].st));}return fstatus;}/* Return a print width suitable for the NFILES files whose status is recorded in FSTATUS. Optimize the same special case thatget_input_fstatus optimizes. */static intcompute_number_width (int nfiles, struct fstatus const *fstatus) {int width = 1;if (0 < nfiles && fstatus[0].failed <= 0){int minimum_width = 1;uintmax_t regular_total = 0;int i;for (i = 0; i < nfiles; i++)if (! fstatus[i].failed){if (S_ISREG (fstatus[i].st.st_mode))regular_total += fstatus[i].st.st_size;elseminimum_width = 7;}for (; 10 <= regular_total; regular_total /= 10)width++;if (width < minimum_width)width = minimum_width;}return width;}intmain (int argc, char **argv){bool ok;int optc;int nfiles;char **files;char *files_from = NULL;struct fstatus *fstatus;struct Tokens tok;initialize_main (&argc, &argv);set_program_name (argv[0]);setlocale (LC_ALL, "");bindtextdomain (PACKAGE, LOCALEDIR);textdomain (PACKAGE);atexit (close_stdout);/* Line buffer stdout to ensure lines are written atomically and immediately so that processes running in parallel do not intersperse their output. */ setvbuf (stdout, NULL, _IOLBF, 0);print_lines = print_words = print_chars = print_bytes = false;print_linelength = false;total_lines = total_words = total_chars = total_bytes = max_line_length = 0; while ((optc = getopt_long (argc, argv, "clLmw", longopts, NULL)) != -1) switch (optc){case 'c':print_bytes = true;break;case 'm':print_chars = true;break;case 'l':print_lines = true;break;case 'w':print_words = true;break;case 'L':print_linelength = true;break;case FILES0_FROM_OPTION:files_from = optarg;break;case_GETOPT_HELP_CHAR;case_GETOPT_VERSION_CHAR (PROGRAM_NAME, AUTHORS);default:usage (EXIT_FAILURE);}if (! (print_lines || print_words || print_chars || print_bytes|| print_linelength))print_lines = print_words = print_bytes = true;bool read_tokens = false;struct argv_iterator *ai;if (files_from){FILE *stream;/* When using --files0-from=F, you may not specify any fileson the command-line. */if (optind < argc){error (0, 0, _("extra operand %s"), quote (argv[optind]));fprintf (stderr, "%s\n",_("file operands cannot be combined with --files0-from"));usage (EXIT_FAILURE);}if (STREQ (files_from, "-"))stream = stdin;else{stream = fopen (files_from, "r");if (stream == NULL)error (EXIT_FAILURE, errno, _("cannot open %s for reading"),quote (files_from));}/* Read the file list into RAM if we can detect its size and thatsize is reasonable. Otherwise, we'll read a name at a time. */ struct stat st;if (fstat (fileno (stream), &st) == 0&& S_ISREG (st.st_mode)&& st.st_size <= MIN (10 * 1024 * 1024, physmem_available () / 2)){read_tokens = true;readtokens0_init (&tok);if (! readtokens0 (stream, &tok) || fclose (stream) != 0)error (EXIT_FAILURE, 0, _("cannot read file names from %s"),quote (files_from));files = tok.tok;nfiles = tok.n_tok;ai = argv_iter_init_argv (files);}else{files = NULL;nfiles = 0;ai = argv_iter_init_stream (stream);}}else{static char *stdin_only[] = { NULL };files = (optind < argc ? argv + optind : stdin_only);nfiles = (optind < argc ? argc - optind : 1);ai = argv_iter_init_argv (files);}fstatus = get_input_fstatus (nfiles, files);number_width = compute_number_width (nfiles, fstatus);int i;ok = true;for (i = 0; /* */; i++){bool skip_file = false;enum argv_iter_err ai_err;char *file_name = argv_iter (ai, &ai_err);if (ai_err == AI_ERR_EOF)break;if (!file_name){switch (ai_err){case AI_ERR_READ:error (0, errno, _("%s: read error"), quote (files_from));skip_file = true;continue;case AI_ERR_MEM:xalloc_die ();default:assert (!"unexpected error code from argv_iter");}}if (files_from && STREQ (files_from, "-") && STREQ (file_name, "-")){/* Give a better diagnostic in an unusual case:printf - | wc --files0-from=- */error (0, 0, _("when reading file names from stdin, ""no file name of %s allowed"),quote (file_name));skip_file = true;}if (!file_name[0]){/* Diagnose a zero-length file name. When it's oneamong many, knowing the record number may help.FIXME: currently print the record number only with--files0-from=FILE. Maybe do it for argv, too? */if (files_from == NULL)error (0, 0, "%s", _("invalid zero-length file name"));else{/* Using the standard `filename:line-number:' prefix here isnot totally appropriate, since NUL is the separator, not NL,but it might be better than nothing. */unsigned long int file_number = argv_iter_n_args (ai);error (0, 0, "%s:%lu: %s", quotearg_colon (files_from),file_number, _("invalid zero-length file name"));}skip_file = true;}if (skip_file)ok = false;elseok &= wc_file (file_name, &fstatus[nfiles ? i : 0]);}/* No arguments on the command line is fine. That means read from stdin.However, no arguments on the --files0-from input stream is an error means don't read anything. */if (ok && !files_from && argv_iter_n_args (ai) == 0)ok &= wc_file (NULL, &fstatus[0]);if (read_tokens)readtokens0_free (&tok);if (1 < argv_iter_n_args (ai))write_counts (total_lines, total_words, total_chars, total_bytes,max_line_length, _("total"));argv_iter_free (ai);free (fstatus);if (have_read_stdin && close (STDIN_FILENO) != 0)error (EXIT_FAILURE, errno, "-");exit (ok ? EXIT_SUCCESS : EXIT_FAILURE);}。