猫是怎么回事? file1.txt file2.txt解释?

时间:2017-04-15 06:05:54

标签: shell unix

我尝试了这个命令并输出了file2.txt。为什么会这样?我问这个问题因为我正在写一个c shell,所以也许你知道如何避免这个问题

2 个答案:

答案 0 :(得分:1)

它按预期工作:

  

cat实用程序按顺序读取文件,将它们写入标准   输出。处理文件操作数        在命令行顺序。如果file是单个短划线(` - ')或缺席,则cat从标准输入读取。

创建一些演示文件:

for i in 1 2 3; do echo this is d$i > d$i; done

cat d1显示

this is d1

这就是您所期望的 - d1cat的参数。 cat < d3显示

this is d3

同样,它可以正常工作 - 这里不是任何参数,因此猫会显示它的标准输入。最后,

cat d1 - d3 < d2显示

this is d1
this is d2
this is d3

E.g。猫读它的论据,例如首先d1然后找到-(作为stdin的指标,因此显示d2(因为< d2)并继续d3 <作为参数中的最后一个文件。当然,

cat - d1 d3 < d2

将显示

this is d2
this is d1
this is d3

每个程序默认附加3个文件描述符。 stdinstdoutstderr。程序正在做什么与它们,以及如何完全在给定的程序职责中。 cat的设计与文档中描述的相同,例如它从他的参数打印到stdout文件(并使用fopen在内部打开它们并从打开的描述符中读取文件内容)并在找到-(或没有参数)时读取stdin。所以你的问题是:

cat d1 < d2

会找到d1作为参数,因此cat会打开文件d1并打印它的内容。因为这里不是-,所以完全忽略stdin并仅打印

this is d1

另请注意,3个默认描述符std(in|out|err)始终附加到进程。即使进程是没有 shell也是如此。让我们从一些守护进程或直接使用fork/exec的程序中说出来。区别在于:当它从shell启动时,shell已将所有上述描述符连接到您的终端。所以,当你要运行cat时:

  • shell fork s本身(例如,这里将是两个相同的进程,并且两者并排运行 - 父对象和子对象。两者之间的唯一差异是{{ 1}})。
  • 分叉进程具有与父进程相同的描述符,例如它们已经连接到终端,或者,如果你在shell中进行了一些重定向,那么PID之前的子进程会用来自/到给定文件的描述符替换它的标准描述符。 (参见exec系统调用)
  • 接下来,孩子将被dup(2)计划(cat
  • 取代

答案 1 :(得分:0)

这不是shell问题,而是由于cat的行为方式。

cat

  1. 从标准输入读取(如果没有给出文件参数)
  2. 从参数给定文件中读取
  3. 但不是两者(基本行为)。正如你给file2.txt作为参数cat只读取该文件并忽略其标准输入(从file1.txt重定向)。

    存在一个特殊的参数来强制从标准输入(-)中读取,您必须使用该参数来使cat考虑到重定向。