我想检查文件是否存在,如果不存在,则创建它。
考虑使用以下C代码,但使用shell脚本。
if(!exist) {
command;
command;
}
else {
command;
command;
}
答案 0 :(得分:17)
检查文件是否存在是一项非常常见的任务。要搜索相关问题,请使用搜索栏(右上角)。我得到了lots of results,其中包含“bash脚本文件存在”
在任何情况下,您都需要test
内置或其语义等效[ ]
:
[ ! -e your_file ] && >your_file
或
test ! -e your_file && >your_file
首先test
不存在your_file
(!
)-e
,如果是这种情况,则创建它。
有关您可以运行的不同测试的更多信息(-e
除外),您可以输入:
help -m test | less
答案 1 :(得分:15)
您可以使用:
if [ ! -e "$file" ]; then touch file else ... fi
答案 2 :(得分:7)
if [ ! -e "$path" ]
then
touch -- "$path"
fi
更简单的版本只是touch -- "$path"
- 如果文件不存在,它会创建文件,如果文件存在则只更新访问和修改时间。 double dash(--
)确保您可以创建文件,即使它以短划线开头,并且$path
周围{{1}}是必需的。
答案 3 :(得分:7)
不要这样做,它不仅受竞争条件的限制,而且还可以[ -e /path/file ]
检查你是否可以对文件执行stat(2)
,因此它会因为不同的原因而返回false,而不是只是因为文件不存在。
示例是不存在的文件的符号链接或您没有搜索权限的目录中的文件。
更好的方法是在open(2)
系统调用使用正确的标志,即O_CREAT|O_EXCL
。这样,如果文件不存在,open()
将失败,而您不必更早地检查数百万个CPU时钟。
使用类似Bourne的shell:
if (set -C && : > "$file") 2> /dev/null; then
print '%s\n' "$file has been created
else
print '%s\n' "It hasn't, possibly because it was already there"
fi
(set -C
是启用O_EXCL
标志。
另外,为什么要创建一个空文件?您可能希望在该文件中存储某些内容。然后,就这样做:
set -C
{
echo blah
other-commands that-generate-the-content
} > "$file"
然后,只有在file
不存在的情况下才能执行该命令组(并且可以创建它)。
如果您想测试文件是否存在,请至少写一下:
[ -e "$file" ] || [ -L "$file" ]
或
ls -d -- "$file" > /dev/null 2>&1
如果你关心它可能是一个符号链接。如果文件确实存在但仍无权对其进行验证,那么仍会返回false。
现在,如果您想要一个关于测试文件存在的更长且历史性的答案:
最初,test
命令(在Unix v7中首次出现)had no -e
(nor -h
/-L
option or -a
unary)选项。
测试文件存在的方法是使用ls
。 ls
(带有-d
)列出文件并报告错误(如果由于某种原因无法查找文件,则会返回 false 退出状态)。 Unix最初没有符号链接,但是当它们被引入时,ls
被修改为对文件而不是lstat(2)
执行stat(2)
。也就是说,如果符号链接ls
返回有关符号链接文件本身的信息,而不是符号链接指向的路径上的文件。
首先在Korn shell test
builtin中引入test
(又名[
)用于测试文件“存在”的选项。那是-a
,而不是-e
。 -a
用于可访问(我相信),这是一个比现有更准确的术语。
我不知道何时或什么介绍-e
,可能是POSIX。在-e
上选择-a
的POSIX says,以避免与-a
二进制运算符混淆(对于和)。
在任何情况下,-a
和-e
都会在文件上尝试stat(2)
,而不是lstat(2)
。那就是:
[ -e "$file" ]
相当于:
ls -Ld -- "$file" > /dev/null 2>&1
因此,严格来说,如果在测试完成后,可以在解析符号链接后查找路径,并且stat(2)
失败,则忽略失败的原因,则返回true
stat
), ENOENT
可能会失败,即文件不存在或存在但是是不存在的文件的符号链接,但也有很多其他原因。查看the possible error codes of stat(2)
会给出一些想法:
EACCESS
:在解析路径期间(可以是任何路径组件和任何符号链接的路径),您对一个目录组件没有搜索权限(请注意,您仍然可以通过其他路径访问该文件。)ELOOP
:无法解决路径,因为太多的符号链接已经解决了。ENOTDIR
。例如,在/etc/passwd/foo
或符号链接上。