shell 无用的猫?

vdzxcuhz  于 2023-03-03  发布在  Shell
关注(0)|答案(9)|浏览(127)

bounty将于明天到期。回答此问题可获得+500声望奖励。tripleee希望奖励现有答案:我想奖励乔纳森·莱弗勒简洁而明智的回答

这可能是在许多常见问题解答-而不是使用:

cat file | command

(这叫做猫的无用之用),正确的方法应该是:

command < file

在第二个,“正确”的方式-操作系统不必产生一个额外的进程。
尽管知道这一点,我继续使用无用的猫有两个原因。
1.更美观-我喜欢数据只从左到右均匀移动。而且更容易用其他东西替换catgzcatecho,...),添加第二个文件或插入新的过滤器(pvmbuffergrep...)。
1.我“感觉”在某些情况下它可能会更快。更快是因为有2个进程,第一个(cat)做阅读,第二个做任何事情。而且它们可以并行运行,这意味着有时执行速度更快。
我的逻辑正确吗(第二个原因)?

91zkwejq

91zkwejq1#

我不知道这个奖项,直到今天,当一些新手试图把UUOC钉在我的答案之一。这是一个cat file.txt | grep foo | cut ... | cut ...。我给了他一块我的想法,只有这样做后,访问了链接,他给我指的是奖项的起源和这样做的做法。进一步的搜索导致我这个问题。有点不幸的是,尽管有意识的考虑,这些答复都没有包括我的理由。
我并不想为他辩护,毕竟,在我年轻的时候,我会把命令写成grep foo file.txt | cut ... | cut ...,因为每当你频繁地执行一个grep时,你就知道了文件参数的位置,并且已经知道第一个是模式,后面的是文件名。
我在回答这个问题时有意识地选择使用cat,部分原因是“品味高”(用Linus Torvalds的话来说),但主要原因是功能强大。
后一个原因更重要,所以我将首先提出它。当我提供管道作为解决方案时,我希望它是可重用的。很有可能一个管道将被添加到另一个管道的末尾或拼接到另一个管道中。在这种情况下,使用grep的文件参数会破坏可重用性。并且如果文件参数存在的话,很有可能会 * 静默地 * 这样做,而不显示错误消息。grep foo xyz | grep bar xyz | wc将给予您xyz中有多少行包含bar,而您期望的是同时包含foobar的行数。在使用管道中的命令之前,必须更改其参数,这很容易出错,再加上可能出现静默失败,这就变成了一种特别危险的做法。
前一个原因也不是不重要,因为很多“good taste“仅仅是一个直觉的潜意识的理由,像上面的沉默的失败,你不能认为正确的时刻,当一些人在需要教育说“但不是那只猫无用”的事情.
然而,我也会尝试意识到我提到的前一个“好品味”的原因。这个原因与Unix的正交设计精神有关。grep不是cutls也不是grep。因此,至少grep foo file1 file2 file3违背了设计精神。正交的方法是cat file1 file2 file3 | grep foo。现在,X1 M15 N1 X只不过是X1 M16 N1 X的一个特例,如果你不以同样的方式对待它,你至少是在耗尽大脑时钟周期,试图避免无用的猫奖。
这就引出了grep foo file1 file2 file3是连接的,而cat是连接的,所以cat file1 file2 file3是正确的,但是因为catcat file1 | grep foo中不是连接的,所以我们违反了cat和万能的Unix的精神。如果是这种情况,那么Unix将需要不同的命令来读取一个文件的输出,并将其发送到stdout(不分页它或任何东西,只是一个纯粹的吐到stdout)。所以你会遇到这样的情况,你说cat file1 file2dog file1,并自觉地记住避免cat file1,以避免获奖,同时还避免了dog file1 file2,因为如果指定多个文件,dog的设计可能会抛出错误。
希望此时您能同情Unix设计者,因为他们没有包含一个单独的命令来将文件拆分到stdout,同时还将cat命名为concatenate,而不是给它取其他名称。<edit>删除了<上的不正确注解,事实上,<是一种高效的无拷贝工具,用于将文件拆分到stdout,您可以将其定位在管道的开始位置,因此Unix设计人员确实包含了一些专门用于此的功能</edit>
下一个问题是,为什么仅仅将一个文件或几个文件连接到stdout而不进行任何进一步处理的命令很重要?一个原因是避免让每个操作标准输入的Unix命令都知道如何解析至少一个命令行文件参数,并将其用作输入(如果存在)。第二个原因是避免用户必须记住:(a)文件名参数的位置;以及(B)避免如上所述的无声流水线缺陷。
这就引出了为什么grep具有额外的逻辑,其基本原理是允许用户流畅地使用频繁使用的命令,并且是在“独立”的基础上使用的(而不是作为流水线)。它是正交性的轻微妥协,以获得可用性的显著增益。并非所有命令都应该这样设计,不常用的命令应该完全避免文件参数的额外逻辑(记住额外的逻辑会导致不必要的脆弱性(bug的可能性))例外是允许文件参数,就像grep的情况一样(顺便说一句,注意ls有一个完全不同的原因,不仅接受文件参数,而且几乎需要文件参数)

最后,如果在指定文件参数时标准输入也可用,那么grep(但不一定是ls)等异常命令会生成错误,这本可以做得更好。

ar7v8xwq

ar7v8xwq2#

不要!
首先,重定向发生在命令的什么地方并不重要,所以如果你喜欢重定向到命令的左边,那就很好:

< somefile command

等于

command < somefile

第二,当你使用管道的时候,会有 * n +1 * 个进程和一个子shell出现,这无疑是比较慢的,在某些情况下,* n * 会是零(例如,当你重定向到一个shell内置程序时),所以使用cat你完全没有必要添加一个新进程。
一般来说,无论何时发现自己在使用管道,都值得花30秒的时间看看是否可以消除它。(但可能不值得花超过30秒的时间。)下面是一些经常不必要地使用管道和进程的示例:

for word in $(cat somefile); … # for word in $(<somefile); … (or better yet, while read < somefile)

grep something | awk stuff; # awk '/something/ stuff' (similar for sed)

echo something | command; # command <<< something (although echo would be necessary for pure POSIX)

请随意编辑以添加更多示例。

7fyelxc5

7fyelxc53#

为了保护猫:
是的,

< input process > output

process < input > output

更有效,但是许多调用没有性能问题,所以您不必关心。

人体工程学原因:

我们习惯于从左到右阅读,所以像这样的命令

cat infile | process1 | process2 > outfile

是很难理解的。

process1 < infile | process2 > outfile

必须跳过进程1,然后从左向右读取。这可以通过以下方法修复:

< infile process1 | process2 > outfile

不知何故,看起来好像有一个箭头指向左边,那里什么都没有。更令人困惑和看起来像花哨的引用是:

process1 > outfile < infile

并且生成脚本通常是迭代过程,

cat file 
    cat file | process1
    cat file | process1 | process2 
    cat file | process1 | process2 > outfile

你可以看到你的进步,而

< file

甚至不起作用。简单的方法不太容易出错,符合人体工程学的命令连锁是简单的与猫。
另一个主题是,大多数人接触到〉和〈作为比较运算符,早在使用计算机之前,当使用计算机作为程序员时,更经常接触到这些运算符。
将两个操作数与进行比较是反交换的,也就是说< and > is contra commutative, which means

(a > b) == (b < a)

我记得第一次使用〈进行输入重定向时,我担心

a.sh < file

意思可能和

file > a.sh

并以某种方式覆盖我的www.example.com脚本。也许这对许多初学者来说是个问题。a.sh script. Maybe this is an issue for many beginners.

罕见差异

wc -c journal.txt
15666 journal.txt
cat journal.txt | wc -c 
15666

后者可直接用于计算。

factor $(cat journal.txt | wc -c)

当然,这里也可以使用〈来代替文件参数:

< journal.txt wc -c 
15666
wc -c < journal.txt
15666

但谁在乎呢一万五
如果我偶尔会遇到问题,我肯定会改变我的习惯,调用猫。
当使用非常大或很多很多的文件时,避免使用cat是可以的。对于大多数问题来说,使用cat是正交的,偏离主题,不是问题。
开始这些无用的无用使用猫讨论每第二个 shell 主题只是恼人和无聊,得到一个生活,等待你的成名分钟,当处理性能问题。

km0tfn4u

km0tfn4u4#

我不同意大多数过于自鸣得意的UUOC奖的例子,因为当教别人的时候,cat是一个方便的占位符,用于任何命令或生成适合所讨论的问题或任务的输出的复杂命令管道。
这在Stack Overflow、ServerFault、Unix & Linux或任何SE站点上尤其如此。
如果有人特别问到优化,或者如果你想增加额外的信息,那么,很好,谈谈使用cat是如何低效的,但是不要因为人们选择了简单和易于理解的例子而不是复杂的例子而责骂他们。
简而言之,因为猫并不总是猫。
还有一个原因是,大多数喜欢到处给UUOC颁奖的人之所以这么做,是因为他们更关心炫耀自己有多"聪明",而不是帮助或教导别人。事实上,他们证明了自己可能只是又一个找到了一根小棍子来击败同龄人的新手。

    • 更新**

下面是我在https://unix.stackexchange.com/a/301194/7696上发布的另一个UUOC:

sqlq() {
  local filter
  filter='cat'

  # very primitive, use getopts for real option handling.
  if [ "$1" == "--delete-blank-lines" ] ; then
    filter='grep -v "^$"'
    shift
  fi

  # each arg is piped into sqlplus as a separate command
  printf "%s\n" "$@" | sqlplus -S sss/eee@sid | $filter
}

UUOCMaven会说这是一个UUOC,因为很容易使$filter默认为空字符串,并使if语句执行filter='| grep -v "^$"',但IMO不将管道字符嵌入到$filter中,这个"无用的" cat服务于自文档化printf行上的$filter不仅仅是sqlplus的另一个参数的事实的极其有用的目的,它是一个可选的用户可选输出滤波器。
如果需要多个可选输出过滤器,选项处理可以根据需要将| whatever附加到$filter-管道中的一个额外cat不会造成任何损害或导致任何明显的性能损失。

gzszwxb4

gzszwxb45#

在UUoC版本中,cat必须将文件读入内存,然后将其写入管道,命令必须从管道中读取数据,因此内核必须复制整个文件 * 三 * 次,而在重定向的情况下,内核只需复制文件一次。
使用:

cat "$@" | command

cat的一种完全不同的用法,也不一定是无用的用法。如果该命令是一个接受零个或多个文件名参数并依次处理它们的标准过滤器,它仍然是无用的。请考虑tr命令:它是一个纯粹的过滤器,忽略或拒绝文件名参数,要向它馈送多个文件,必须使用cat,如图所示(当然,还有另外一个讨论,tr的设计不是很好;没有真正的理由不能将其设计为标准过滤器。)如果您希望命令将所有输入视为单个文件而不是多个单独的文件,即使命令接受多个单独的文件,这也可能是有效的:例如wc就是这样的命令。
cat single-file的情况是无条件无用的。

8aqjt8rx

8aqjt8rx6#

作为一个经常指出这一点和许多其他shell编程反模式的人,我感到有义务(尽管为时已晚)加入进来。
Shell脚本在很大程度上是一种复制/粘贴语言,对于大多数编写shell脚本的人来说,他们并不是在里面学习语言;这只是他们必须克服的一个障碍,以便继续用他们实际上有点熟悉的语言做事情。
在这种情况下,我认为传播各种shell脚本反模式是破坏性的,甚至是潜在的破坏性的。人们在Stack Overflow上找到的代码在理想情况下应该可以复制/粘贴到他们的环境中,只需要最小的更改和不完全的理解。
在网络上的许多shell脚本资源中,Stack Overflow是不寻常的,因为用户可以通过编辑网站上的问题和答案来帮助塑造网站的质量。然而,code edits can be problematic是因为它很容易做出代码作者无意中做出的修改。因此,我们倾向于留下评论来建议对代码的修改。
UUCA和相关的反模式注解不仅仅针对我们所注解的代码的作者;他们是一个“告诫买者”,以帮助“读者”的网站成为意识到问题的代码,他们发现在这里。
我们不能指望出现这样的情况:Stack Overflow上没有答案推荐无用的cat(或无引号的变量,或chmod 777,或大量其他反模式问题),但我们至少可以帮助教育用户,让他们将此代码复制/粘贴到脚本的最内层紧密循环中,该循环将执行数百万次。
就技术原因而言,传统智慧是我们应该尽量减少外部进程的数量;在编写shell脚本时,这仍然是一个很好的通用指南。

eoxn13cs

eoxn13cs7#

另一个问题是管道可以静默地屏蔽一个子shell,对于这个例子,我将用echo替换cat,但是同样的问题仍然存在。

echo "foo" | while read line; do
    x=$line
done

echo "$x"

您可能希望x包含foo,但实际上并非如此。您设置的x位于为执行while循环而派生的子shell中。shell中启动管道的x具有不相关的值,或者根本没有设置。
在bash4中,您可以配置一些shell选项,以便管道的最后一个命令与启动管道的命令在同一个shell中执行,但是您可以尝试这样做

echo "foo" | while read line; do
    x=$line
done | awk '...'

并且x再次位于while的子 shell 的本地。

41zrol4v

41zrol4v8#

我经常在例子中使用cat file | myprogram。有时候我被指责为无用地使用cat(http://porkmail.org/era/unix/award.html)。我不同意,原因如下:

  • 很容易理解正在发生的事情。

当阅读UNIX命令时,你期望命令后面跟着参数,然后是重定向。可以将重定向放在任何地方,但很少看到-因此人们将很难阅读这个例子。我相信

cat foo | program1 -o option -b option | program2

更容易阅读

program1 -o option -b option < foo | program2

如果你把重定向移到开头,你会把不习惯这个语法的人弄糊涂:

< foo program1 -o option -b option | program2

并且示例应该易于理解。

  • 这是很容易改变的。

如果您知道程序可以读取cat,通常可以假设它可以读取输出到STDOUT的任何程序的输出,因此您可以根据自己的需要调整它并获得可预测的结果。

  • 它强调如果STDIN不是文件,程序不会失败。

假设program1 < foo可以工作,那么cat foo | program1也可以工作是不安全的,但是相反的假设是安全的。如果STDIN是一个文件,这个程序可以工作,但是如果输入是一个管道,则会失败,因为它使用seek:

# works
< foo perl -e 'seek(STDIN,1,1) || die;print <STDIN>'

# fails
cat foo | perl -e 'seek(STDIN,1,1) || die;print <STDIN>'

性能成本

额外的cat是有成本的,为了了解成本,我运行了几个测试来模拟基线(cat)、低吞吐量(bzip2)、中等吞吐量(gzip)和高吞吐量(grep)。

cat $ISO | cat
< $ISO cat
cat $ISO | bzip2
< $ISO | bzip2
cat $ISO | gzip
< $ISO gzip
cat $ISO | grep no_such_string
< $ISO grep no_such_string

测试在低端系统(0.6 GHz)和普通笔记本电脑(2.2 GHz)上运行。每个系统上运行10次,并选择最佳时间来模拟每个测试的最佳情况。$ISO为ubuntu-11.04-desktop-i386.iso。(更好的表格如下:http://oletange.blogspot.com/2013/10/useless-use-of-cat.html

CPU                       0.6 GHz ARM
Command                   cat $ISO|                        <$ISO                            Diff                             Diff (pct)
Throughput \ Time (ms)    User       Sys        Real       User       Sys        Real       User       Sys        Real       User       Sys        Real
Baseline (cat)                     55      14453      33090         23       6937      33126         32       7516        -36        239        208         99
Low (bzip2)                   1945148      16094    1973754    1941727       5664    1959982       3420      10430      13772        100        284        100
Medium (gzip)                  413914      13383     431812     407016       5477     416760       6898       7906      15052        101        244        103
High (grep no_such_string)      80656      15133      99049      79180       4336      86885       1476      10797      12164        101        349        114

CPU                       Core i7 2.2 GHz
Command                   cat $ISO|           <$ISO             Diff          Diff (pct)
Throughput \ Time (ms)    User     Sys Real   User   Sys Real   User Sys Real User       Sys Real
Baseline (cat)                    0 356    215      1  84     88    0 272  127          0 423  244
Low (bzip2)                  136184 896 136765 136728 160 137131 -545 736 -366         99 560   99
Medium (gzip)                 26564 788  26791  26332 108  26492  232 680  298        100 729  101
High (grep no_such_string)      264 392    483    216  84    304   48 308  179        122 466  158

结果表明,对于中低吞吐量,成本约为1%,这完全在测量的不确定性范围内,因此在实践中没有差异。
对于高吞吐量,差异更大,并且两者之间存在明显差异。
由此得出结论:在以下情况下,应使用<而不是cat |

  • 处理的复杂性类似于简单的grep
  • 性能比可读性更重要。

否则,使用<还是cat |并不重要。
因此,只有当且仅当以下情况时,您才应授予UUoC奖项:

  • 您可以衡量绩效的显著差异(在颁奖时公布您的衡量结果)
  • 性能比可读性更重要。
6ojccjat

6ojccjat9#

我认为(传统的方式)使用管道更快一点;在我的机器上,我使用了strace命令来查看发生了什么:
无管道:

toc@UnixServer:~$ strace wc -l < wrong_output.c
execve("/usr/bin/wc", ["wc", "-l"], [/* 18 vars */]) = 0
brk(0)                                  = 0x8b50000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77ad000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=29107, ...}) = 0
mmap2(NULL, 29107, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb77a5000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0p\222\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1552584, ...}) = 0
mmap2(NULL, 1563160, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb7627000
mmap2(0xb779f000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x178) = 0xb779f000
mmap2(0xb77a2000, 10776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb77a2000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7626000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb76268d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb779f000, 8192, PROT_READ)   = 0
mprotect(0x804f000, 4096, PROT_READ)    = 0
mprotect(0xb77ce000, 4096, PROT_READ)   = 0
munmap(0xb77a5000, 29107)               = 0
brk(0)                                  = 0x8b50000
brk(0x8b71000)                          = 0x8b71000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=5540198, ...}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7426000
mmap2(NULL, 1507328, PROT_READ, MAP_PRIVATE, 3, 0x2a8) = 0xb72b6000
close(3)                                = 0
open("/usr/share/locale/locale.alias", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=2570, ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb77ac000
read(3, "# Locale name alias data base.\n#"..., 4096) = 2570
read(3, "", 4096)                       = 0
close(3)                                = 0
munmap(0xb77ac000, 4096)                = 0
open("/usr/share/locale/fr_FR.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/fr_FR.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/fr_FR/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/fr.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/fr.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale/fr/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/fr_FR.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/fr_FR.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/fr_FR/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/fr.UTF-8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/fr.utf8/LC_MESSAGES/coreutils.mo", O_RDONLY) = -1 ENOENT (No such file or directory)
open("/usr/share/locale-langpack/fr/LC_MESSAGES/coreutils.mo", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=316721, ...}) = 0
mmap2(NULL, 316721, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7268000
close(3)                                = 0
open("/usr/lib/i386-linux-gnu/gconv/gconv-modules.cache", O_RDONLY) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=26064, ...}) = 0
mmap2(NULL, 26064, PROT_READ, MAP_SHARED, 3, 0) = 0xb7261000
close(3)                                = 0
read(0, "#include<stdio.h>\n\nint main(int "..., 16384) = 180
read(0, "", 16384)                      = 0
fstat64(1, {st_mode=S_IFCHR|0620, st_rdev=makedev(136, 2), ...}) = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb7260000
write(1, "13\n", 313
)                     = 3
close(0)                                = 0
close(1)                                = 0
munmap(0xb7260000, 4096)                = 0
close(2)                                = 0
exit_group(0)                           = ?

和管道:

toc@UnixServer:~$ strace cat wrong_output.c | wc -l
execve("/bin/cat", ["cat", "wrong_output.c"], [/* 18 vars */]) = 0
brk(0)                                  = 0xa017000
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
mmap2(NULL, 8192, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb774b000
access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
open("/etc/ld.so.cache", O_RDONLY)      = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=29107, ...}) = 0
mmap2(NULL, 29107, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb7743000
close(3)                                = 0
access("/etc/ld.so.nohwcap", F_OK)      = -1 ENOENT (No such file or directory)
open("/lib/i386-linux-gnu/libc.so.6", O_RDONLY) = 3
read(3, "\177ELF\1\1\1\0\0\0\0\0\0\0\0\0\3\0\3\0\1\0\0\0p\222\1\0004\0\0\0"..., 512) = 512
fstat64(3, {st_mode=S_IFREG|0755, st_size=1552584, ...}) = 0
mmap2(NULL, 1563160, PROT_READ|PROT_EXEC, MAP_PRIVATE|MAP_DENYWRITE, 3, 0) = 0xb75c5000
mmap2(0xb773d000, 12288, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE, 3, 0x178) = 0xb773d000
mmap2(0xb7740000, 10776, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS, -1, 0) = 0xb7740000
close(3)                                = 0
mmap2(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0) = 0xb75c4000
set_thread_area({entry_number:-1 -> 6, base_addr:0xb75c48d0, limit:1048575, seg_32bit:1, contents:0, read_exec_only:0, limit_in_pages:1, seg_not_present:0, useable:1}) = 0
mprotect(0xb773d000, 8192, PROT_READ)   = 0
mprotect(0x8051000, 4096, PROT_READ)    = 0
mprotect(0xb776c000, 4096, PROT_READ)   = 0
munmap(0xb7743000, 29107)               = 0
brk(0)                                  = 0xa017000
brk(0xa038000)                          = 0xa038000
open("/usr/lib/locale/locale-archive", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=5540198, ...}) = 0
mmap2(NULL, 2097152, PROT_READ, MAP_PRIVATE, 3, 0) = 0xb73c4000
mmap2(NULL, 1507328, PROT_READ, MAP_PRIVATE, 3, 0x2a8) = 0xb7254000
close(3)                                = 0
fstat64(1, {st_mode=S_IFIFO|0600, st_size=0, ...}) = 0
open("wrong_output.c", O_RDONLY|O_LARGEFILE) = 3
fstat64(3, {st_mode=S_IFREG|0664, st_size=180, ...}) = 0
read(3, "#include<stdio.h>\n\nint main(int "..., 32768) = 180
write(1, "#include<stdio.h>\n\nint main(int "..., 180) = 180
read(3, "", 32768)                      = 0
close(3)                                = 0
close(1)                                = 0
close(2)                                = 0
exit_group(0)                           = ?
13

您可以使用stracetime命令进行一些测试,使用更多更长的命令进行良好的基准测试。

相关问题