是否有一种编程方式可以找出我为什么不能在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标准的方式进行,但也可以使用bash
或zsh
扩展程序。
答案 0 :(得分:0)
您的命令将调用的大多数程序捕获错误,解释errno
并打印描述性(但不是机器可读)错误消息。因此errno
的正式信息通常会丢失;您所能做的就是解释人类可读的错误消息。
另一方面,任意命令失败的实际原因都取决于智能,除非你想为此编程一个人为的,否则你将无法成功。如果文件/a/b/c/d
上的写入失败,则可能是因为d
没有设置写权限位,或者因为a
,b
,c
中的任何一个没有执行权限,或者因为写入过程中存在I / O错误,或者因为文件系统是以只读方式挂载的。而且我确定我忘记了更多的可能性。这只是为了对文件进行非常简单的写入。如果你试图直接使用任意命令,那就太过分了。
仅仅是文件访问主题(基于权限),你可以使用faccessat(2)
来获取某个地方(但我不知道它的shell接口)。
答案 1 :(得分:0)
有几个操作系统内置函数可以检查文件的特殊功能:
它存在,但你不能写/读它 - 它的0字节 - 它是一个目录(!) - 它是一个象征性的联系 - 还有一些
通过
检查man test
或通过以下方式快速检查: http://unixhelp.ed.ac.uk/CGI/man-cgi?test
此外,您还可以检查文件本身的目录是否存在。这可能是文件不存在的原因。您可以使用DIRNAME: