如果我以这种方式在 unix 中创建管道:
int fds[] = {0, 0};
pipe(fds);
Run Code Online (Sandbox Code Playgroud)
然后,使FILE *从fds[0]这种方式:
FILE *pipe_read = fdopen(fds[0], "rt");
Run Code Online (Sandbox Code Playgroud)
那么我应该如何关闭这个文件(pipe_read)?
fclose(pipe_read)pclose(pipe_read)close(fileno(pipe_read))我正在为学校做一个项目,我不确定我试图解决它的方式是否可行。该项目涉及制作一个程序,分叉出 2 个孩子,然后必须用其他程序替换他们的 pid,并让 2 个孩子通过使用 read() 和 write() 通过管道交谈。
我的问题是使用 execve 并将管道传递给那个孩子。我现在所拥有的是:
父程序 - 分叉并让孩子调用 execve:
#include <unistd.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <fcntl.h>
#define BUF_SIZE 16
/* 2 cmd line arguments
1. file already in system (to be copied)
2. file to be created (the copy)
create pipe (for communication) + 2 child processes
first child replace pid with reader
second child with writer
wait for both children to terminate before exiting
*/
int …Run Code Online (Sandbox Code Playgroud) 在 MIPS 平台上试过这个:
> uname -a
Linux (none) 2.6.29 #2 Mon Jan 14 13:26:04 PST 2013 mips GNU/Linux
> ulimit -c unlimited
> which gzip
/bin/gzip
> echo "|/bin/gzip - > /home/core-%t-%s-%e.gz" > /proc/sys/kernel/core_pattern
> ./fault
hello there
Segmentation fault (core dumped)
> ls /home/core*.gz
ls: /home/core*: No such file or directory
Run Code Online (Sandbox Code Playgroud)
即管道到程序不起作用。如果我指定一个文件:
> echo "/home/core-%t-%s-%e" > /proc/sys/kernel/core_pattern
Run Code Online (Sandbox Code Playgroud)
那么它的工作原理。我错过了什么?
关于此有许多讨论:将输出输出到bash函数
我只想知道为什么:
#bin/sh
function myfunc () {
echo $1
}
ls -la | myfunc
Run Code Online (Sandbox Code Playgroud)
将给空行。请问为什么我们的输出ls不被视为$1函数?其背后的机制是什么?
如果我们尝试:
#bin/sh
function myfunc () {
i=${*:-$(</dev/stdin)}
echo $i
}
ls -la | myfunc
Run Code Online (Sandbox Code Playgroud)
然后我们有:
total 32 drwxr-xr-x 6 phil staff 204 Sep 11 21:18 . drwx------+ 17 phil staff 578 Sep 10 21:34 .. lrwxr-xr-x 1 phil staff 2 Sep 10 21:35 s1 -> t1 lrwxr-xr-x 1 phil staff 2 Sep 10 21:35 s2 -> t2 lrwxr-xr-x 1 phil …
我的老师说如果管道的写入结束关闭,子进程就不能再读取管道的读取端,而读取会产生一个BROKEN _PIPE错误.但是,在封闭管上读取时,我无法获取此代码以生成任何错误:
#include <stdio.h>
#include <unistd.h>
#include <wait.h>
int main(void) {
int pipefd[2];
char c;
pipe(pipefd);
if (fork() == 0) {
close(pipefd[1]);
sleep(5);
// The parent has already closed pipefd[1]
while (read(pipefd[0], &c, 1)) {
printf("%c", c);
}
close(pipefd[0]);
return 0;
}
close(pipefd[0]);
char str[] = "foo";
write(pipefd[1], str, 4);
close(pipefd[1]);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
5秒后stdout上的输出是foo.所以我理解的是关闭写端只是在已经存在的字符之后添加EOF并且不会在任何即将到来的读取上发送EOF(因此孩子可以读取已经发送的所有字符).我对吗 ?
我想编写一个函数,可以将一系列数字分开\n
并在列表中打印.但是我无法对badarg错误做出任何进展.我该如何处理此代码?想法是将数字传递给这个程序,但是当我传递多个数字时,我得到了这个错误:
exception error: bad argument
in function io:format/3
called as io:format(<0.62.0>,"~w~n",[3,2,1])
in call from erl_eval:local_func/6 (erl_eval.erl, line 564)
in call from escript:interpret/4 (escript.erl, line 788)
in call from escript:start/1 (escript.erl, line 277)
in call from init:start_em/1
in call from init:do_boot/3
Run Code Online (Sandbox Code Playgroud)
这是我的代码:
-module(prog).
-export([read_stdin/1]).
-export([main/0]).
read_stdin(Acc) ->
case io:fread(standard_io, '', "~d") of
eof -> Acc;
{ok, Line} -> read_stdin(Line ++ Acc)
end.
main() ->
Data = read_stdin([]),
io:format("~w~n", Data).
Run Code Online (Sandbox Code Playgroud) 我从文件中读取了一些数据,并通过管道发送.当我从管道中读取数据时,有时会出现额外的字符.额外的字符也不一致,但通常在末尾是一个额外的"R".
我从文件中读取的数据是正确的,因为它始终是应该的.只有在从管道上读到它后才会遇到问题.
你能帮我找到错误吗?我多年来一直盯着这个,我找不到它.
这是我的代码中给我带来麻烦的一部分.
谢谢你的帮助.
int main (int argc, char **argv) {
int nClients;
int file_name_HTML[2];
create_pipes(file_name_HTML, server_access_request);
init_free_pipes();
nClients = getHTMLFilesIntoPipe(file_name_HTML);
int clients[nClients];
for(int i=0; i < nClients; i++)
{
if((clients[i] = fork()) == 0)
{
clientFunction(file_name_HTML, server_access_request);
}
}
.....
}
int getHTMLFilesIntoPipe(int *file_name_HTML)
{
int i, n = 0;
char (*lines)[MAXCHAR] = NULL;
FILE *fp;
fp = fopen("./data/listado_html.txt", "r");
if (!fp) { /* valdiate file open for reading */
err_exit("error: file open failed.\n");
}
if (!(lines = …Run Code Online (Sandbox Code Playgroud) 我是kubectl的日常用户,但不是linux的专家.最近我需要在部署后编辑一些服务类型,所以搜索并使用kubectl 替换它并且运行良好.
cat yaml | kubectl replace -f -
service/tracs-pool-1sv replaced
Run Code Online (Sandbox Code Playgroud)
但是我不明白为什么要在最后添加短划线 -.该文件只说:
根据传入stdin的JSON替换pod.
我搜索并发现了这个问题,并且学到了kubectl命令可能是那种不读取标准输入的命令(我是对的吗?).
我试过了
cat yaml |xargs kubectl replace -f
Run Code Online (Sandbox Code Playgroud)
但错误返回:
the path "apiVersion:" does not exist
Run Code Online (Sandbox Code Playgroud)
所以是结束短破折号( - )语法kubectl内置ONLY?或者是linux bash stdin管道的一些更常见的语法?有人可以解释为什么xargs不能在这里工作,我必须在最后放一个短划线( - )?
几种unix实用程序,例如fmt,head和cat,可以通过以下三种方式中的任何一种来接收数据:来自标准输入的管道;或重定向“ <”。例如:
printf '%b' 'dog \ncat \nrat\n' > dogcatrat
fmt dogcatrat
cat dogcatrat | fmt
fmt < dogcatrat
Run Code Online (Sandbox Code Playgroud)
可以编写一种功能相同的perl脚本吗?还是有充分的理由不尝试这样做?“标准输入的管道”是引用以cat开头的代码行的正确方法吗?
我想编写myfmt.pl,以这三种方式中的任何一种使用。
我要写:
... | my_filter | myperlprogram
Run Code Online (Sandbox Code Playgroud)
但是my_filter直到开始我才知道如何运行myperlprogram。
我可以在阅读之前以某种方式在myperlprogramSTDIN 中循环my_filter吗?
我在想类似的东西:
pipe($a,$b);
if(not fork()) {
close STDOUT;
open STDOUT, $b;
exec "my_filter --with the correct --options";
} else {
close STDIN
open STDIN, $a
}
# continue reading STDIN now looped through `my_filter`
Run Code Online (Sandbox Code Playgroud)