我能找出为什么我不能写入shell脚本中的文件吗?

时间:2014-11-26 14:46:23

标签: bash shell sh zsh

是否有一种编程方式可以找出我为什么不能在shell脚本中写入文件(文件存在,访问被拒绝,文件系统已满等)?

例如,在C中,我使用errno变量:

FILE *fp = fopen("/etc/passwd", "w");
if (!fp) {
    if (errno == EACCES) {
        // ...
    }
    else if (errno == EEXISTS) {
        // ...
    }
}

我可以使用shell脚本执行类似的操作吗?

我的测试脚本:

#!/bin/sh

err=$(echo 'x' 2>&1 > /etc/passwd)
if [ $? -ne 0 ]; then
    echo "An error occured: $err"
    exit 1
fi

以非root用户身份运行此操作将为您提供:

An error occured: 'test.sh: line 3: /etc/passwd: Permission denied'

检查$err的内容是不是一个非常好的解决方案恕我直言;错误消息可能在将来发生变化,并且取决于用户的locale设置。

我也知道我可以做stat&在创建文件之前或退出代码非零之后的一些其他检查;但如果你想检查所有可能的错误,这很快就会失控。在某些情况下,它也容易受到竞争条件的影响(例如文件正在test -f之间创建并实际写入它。)

我使用的是POSIX外壳,并希望以符合POSIX标准的方式进行,但也可以使用bashzsh扩展程序。

2 个答案:

答案 0 :(得分:0)

您的命令将调用的大多数程序捕获错误,解释errno并打印描述性(但不是机器可读)错误消息。因此errno的正式信息通常会丢失;您所能做的就是解释人类可读的错误消息。

另一方面,任意命令失败的实际原因都取决于智能,除非你想为此编程一个人为的,否则你将无法成功。如果文件/a/b/c/d上的写入失败,则可能是因为d没有设置写权限位,或者因为abc中的任何一个没有执行权限,或者因为写入过程中存在I / O错误,或者因为文件系统是以只读方式挂载的。而且我确定我忘记了更多的可能性。这只是为了对文件进行非常简单的写入。如果你试图直接使用任意命令,那就太过分了。

仅仅是文件访问主题(基于权限),你可以使用faccessat(2)来获取某个地方(但我不知道它的shell接口)。

答案 1 :(得分:0)

有几个操作系统内置函数可以检查文件的特殊功能:

它存在,但你不能写/读它 - 它的0字节 - 它是一个目录(!) - 它是一个象征性的联系 - 还有一些

通过

检查
man test

或通过以下方式快速检查: http://unixhelp.ed.ac.uk/CGI/man-cgi?test

此外,您还可以检查文件本身的目录是否存在。这可能是文件不存在的原因。您可以使用DIRNAME:

http://linux.die.net/man/1/dirname