/ dev / null总是可以打开吗?

时间:2018-02-23 19:23:50

标签: c dev-null

我想通过将目标文件重定向到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");

3 个答案:

答案 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,请另外写两行来致电exitwhereToPrint。老实说,即使一次性的测试程序,我也会包含它,只有我才能运行。打字的时间不超过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}}”不可能“失败”将会发生什么?

  1. 如果您的程序检查/dev/null失败,它会打印fopen之类的消息,并且会清楚发生了什么。

  2. 如果您的程序无法检查"Impossible error! Can't open /dev/null"失败,它会在第一次尝试将内容打印到fopen时出现神秘崩溃,并且您的用户将会想知道出了什么问题。

  3. 神秘崩溃的程序是坏的。告诉你正在发生什么的程序是好的。

    你越能告诉你的用户发生了什么,就越好。我建议打印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); } 函数当然有一个错误:它每次打开文件(也许)它被称为,但永远不会关闭它。

    “好”使用三元运算符 - 或任何其他“漂亮”技巧 - 写起来很有趣,如果它们有效则它们很好,但请不要以牺牲它们为代价您的代码的其他更重要的方面,例如确保它在所有情况下都能正常运行。 : - )