我想通过将目标文件重定向到fprintf
来禁止某些/dev/null
次调用。但我能确定,fopen("/dev/null", "w");
永远不会返回NULL
。换句话说,是否每次都可以打开这个“文件”?
如果是这样,我可以使用这个漂亮的三元运算符:
FILE *whereToPrint = (strcmp(custom_topic, ERROR_TOPIC) == 0) ? fopen("/dev/null", "w") : stdout;
fprintf(whereToPrint, "Message sent!\n\n");
答案 0 :(得分:6)
是的,在功能正常的系统上,/dev/null
是世界可写的:
ls -l /dev/null
crw-rw-rw- 1 root root 1, 3 Jul 20 2017 /dev/null
所以它总能奏效。这不是最有效的抑制输出的方法..如果你不想这样做,最好不要尝试写...但如果不是很多输出,那就不重要了。
有人指出root
可以设置/dev/null
的权限,以便other
无法写入/dev/null
。或者他们可以完全删除设备。这是真的..但它会导致unix损坏。 fopen()
应该具有我上面显示的权限..它以这种方式安装,永远不应该被更改。不过,每当打开任何文件时,您都应该检查open()
或dat <- data.frame(Var1 = c("aa1", "aa1", "aa1", "bb1", "bb1"), Var2 = c("X1", "Y2", "Z1", "Y1", "Y2"), stringsAsFactors = FALSE)
cbind(Var1 = unique(dat$Var1),
Var2 = sapply(unique(dat$Var1), function(x) paste0(dat$Var2[dat$Var1 == x], collapse = ", "), USE.NAMES = F))
Var1 Var2
[1,] "aa1" "X1, Y2, Z1"
[2,] "bb1" "Y1, Y2"
的返回值。
答案 1 :(得分:3)
/dev/null
可能是不可写入或遗失的。我的意思是,你可以打开一个root shell并输入rm /dev/null
并按下RETURN,它会愉快地继续并删除设备节点。
如果/dev/null
不可写或丢失,则您的程序失败是合理的。很多其他程序都有这个属性。但 。如果fopen("/dev/null", "w")
为perror
,请另外写两行来致电exit
和whereToPrint
。老实说,即使是一次性的测试程序,我也会包含它,只有我才能运行。打字的时间不超过10秒,谁知道呢?也许我遇到的问题会变成一些错误的系统脚本在我背后删除/ dev / null!
编辑:我刚刚想到你可能会因为额外的输入错误而检查NULL
的结果而犹豫不决,但因为你不想搞砸你的“很好的三元表达”。没有必要弄乱它;你刚刚把支票放在后面:
fopen
如果FILE *whereToPrint = (strcmp(custom_topic, ERROR_TOPIC) == 0) ? fopen("/dev/null", "w") : stdout;
if (!whereToPrint) {
perror("/dev/null");
exit(1);
}
已设置为whereToPrint
,那么它将不会是stdout
,并且检查会成功。
如果你有这些错误主题的完整束,那么你应该把它们和它们的名字放在一个表中,这样你就可以在初始化时循环它们,而且也不需要打开{ {1}}不止一次:
NULL
答案 2 :(得分:2)
是的,/dev/null
始终可以打开 - 除非它不是。
听起来很傻,但我不是在开玩笑。如果/dev/null
无法打开,您可能会有一个严重破坏,可能是边界无功能的系统 - 但是知道这与保证文件可以打开是不一样的。
总是打开文件失败的原因。你永远不应该找借口不检查fopen
失败的返回值。
你可能永远不会知道,它可能永远不会发生在一个功能正常的系统上,但问问自己,如果“{1}}”不可能“失败”将会发生什么?
如果您的程序检查/dev/null
失败,它会打印fopen
之类的消息,并且会清楚发生了什么。
如果您的程序无法检查"Impossible error! Can't open /dev/null"
失败,它会在第一次尝试将内容打印到fopen
时出现神秘崩溃,并且您的用户将会想知道出了什么问题。
神秘崩溃的程序是坏的。告诉你正在发生什么的程序是好的。
你越能告诉你的用户发生了什么,就越好。我建议打印whereToPrint
,这比没有好,但它实际上仍然非常不完整。您应该编写行为类似的代码:
"Impossible error! Can't open /dev/null"
现在,在失败的“不可能”的情况下,它会告诉你为什么它无法打开#include <stdio,h>
#include <string.h>
#include <errno.h>
FILE *whereToPrint;
if(strcmp(custom_topic, ERROR_TOPIC) != 0)
whereToPrint = stdout;
else if((whereToPrint = fopen("/dev/null", "w")) == NULL) {
fprintf(stderr, "Impossible error! Can't open /dev/null: %s\n", strerror(errno));
exit(1);
}
,这可能是非常有用的信息。它可能会打印
/dev/null
如果Impossible error! Can't open /dev/null: No such file or directory
某种程度上不存在。或者它可能会打印
/dev/null
如果像其他人所建议的那样,有人错误地限制了系统Impossible error! Can't open /dev/null: Permission denied
上的权限。或者它可能会打印
/dev/null
事实上, ,即使在正确配置的系统上,由于程序中的错误,它仍然可能会失败!
例如,回到你的“好三元运算符”,如果你曾经写过类似
的东西Impossible error! Can't open /dev/null: Too many open files
你很可能迟早会得到“太多打开的文件”错误,因为我在这里编写的void log_message(const char *msg)
{
FILE *whereToPrint = (strcmp(custom_topic, ERROR_TOPIC) == 0) ?
fopen("/dev/null", "w") : stdout;
fprintf(whereToPrint, "%s", msg);
}
函数当然有一个错误:它每次打开文件(也许)它被称为,但永远不会关闭它。
“好”使用三元运算符 - 或任何其他“漂亮”技巧 - 写起来很有趣,如果它们有效则它们很好,但请不要以牺牲它们为代价您的代码的其他更重要的方面,例如确保它在所有情况下都能正常运行。 : - )