cat vs echo或printf将数据传递给程序的标准输出

时间:2015-10-28 15:31:51

标签: shell printf echo cat

假设我们有以下名为myprog的程序:

#include <stdio.h>
#include <stdlib.h>

void main(){
        char buffer[32];
        gets(buffer);
        system("/bin/sh");
}
  1. 占用缓冲区的空间
  2. 等待来自标准输入的数据并将其复制到缓冲区,直到找到换行符
  3. 它作为子进程执行shell,然后它将等待来自stdin的命令
  4. 因此我们有2条指令可以从stdin中查找数据。

    假设我们想要将此数据传递给其他程序的标准输出重定向到myprog的标准输出,让echocat为示例

    $ cat > cmds
    ls
    $ { echo "My string" ; cat cmds ; } | ./myprog
    file1 file2 cmds myprog 
    

    到目前为止一直很好:echo会在&#34;我的字符串&#34;的末尾自动添加换行符,这会导致gets停止阅读并/bin/sh阅读来自cat的输出。

    但是,让我们尝试其他解决方案:

    1. echo "My string" ls | ./myprog

    2. printf "My string\nls\n" | ./myprog

    3. {echo "My string" ; echo ls ; } | ./myprog

    4. 这些解决方案似乎都不起作用。 使用单个文件和cat的单个调用都不起作用:

      $ cat > file
       My string
       ls
      $ cat file | ./myprog
      

      为什么会这样?每种情况都会发生什么?

1 个答案:

答案 0 :(得分:1)

我认为你对程序的方法有点困惑,它将从stdin获取输入。如果我正确理解您的目标是让system("/bin/sh");等待"ls"作为来自stdin的输入,那么如果您成功了,您会看到错误:

/usr/bin/ls: /usr/bin/ls: cannot execute binary file

您已在gets上看过评论 - 从不使用它。如果您的老师建议您使用它,您可以告诉他,由于其安全漏洞,它已从C标准库中删除。请改用fgets

也就是说,如果您希望从stdin获取输入并且想要在system调用中使用该输入,那么您需要创建一个包含您期望的命令的字符串{{ 1}}执行 - 包括所需的任何参数。简单地调用system将无效,因为system("/bin/sh");子shell 中执行其命令。

只需构建要执行的system字符串即可。一个简单的例子可能是:

system

它基本上从#include <stdio.h> #include <stdlib.h> #include <string.h> #define MAXC 32 int main (void) { char buffer[MAXC] = {0}; char script[MAXC] = {0}; /* read line 1 into buffer & print */ fgets (buffer, MAXC, stdin); printf ("\n buffer: %s", buffer); /* read line 2 into buffer & print */ fgets (buffer, MAXC, stdin); printf ("\n buffer: %s", buffer); /* copy "/bin/sh" to script */ strncpy (script, "/bin/sh ", strlen ("/bin/sh ") + 1); /* concatenate script & buffer ( "/bin/sh + line 2" ) */ strcat (script, buffer); /* execute script */ system (script); return 0; } 获取line 1并打印出来,然后用stdin覆盖它,其中包含line 2要调用的命令(脚本名称)。您可以使用简单的测试脚本,如:

/bin/sh

现在,您可以使用#!/bin/sh printf "\n %s executed : %s\n\n" "$0" "hello /bin/sh" exit 0 将第1行和第2行传递给您的程序,类似于:

printf

一次将一行传递给您的程序。运行您希望看到的代码:

$ printf "%s\n%s\n" "buffer - line 1" "myscript.sh"

如果您还有其他问题,请询问。