如果文件不存在,如何执行某些命令?

时间:2013-11-24 19:01:18

标签: file shell

我想检查文件是否存在,如果不存在,则创建它。

考虑使用以下C代码,但使用shell脚本。

if(!exist) {
    command;
    command;
}
else {
    command;
    command;
}

4 个答案:

答案 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)选项。

测试文件存在的方法是使用lsls(带有-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或符号链接上。