如何检查一个文件是否存在于一个shell脚本

我想写一个shell脚本,它检查某个文件archived_sensor_data.json是否存在,如果存在,就删除它。在http://www.cyberciti.biz/tips/find-out-if-file-exists-with-conditional-expressions.html之后,我尝试了以下方法:

[-e archived_sensor_data.json] && rm archived_sensor_data.json

但是,这会抛出一个错误

[-e: command not found

当我尝试使用./test_controller命令运行生成的test_controller脚本时。代码出了什么问题?

555747 次浏览

括号和-e之间缺少必需的空格:

#!/bin/bash
if [ -e x.txt ]
then
echo "ok"
else
echo "nok"
fi

下面是一个使用ls的替代方法:

(ls x.txt && echo yes) || echo no

如果你想隐藏任何来自ls的输出,这样你只能看到yes或no,将stdoutstderr重定向到/dev/null:

(ls x.txt >> /dev/null 2>&1 && echo yes) || echo no
在内部,rm命令必须测试文件是否存在,
那么为什么要添加另一个测试呢?只是问题< / p >
rm filename

之后它将消失,不管它是否在那里 如果你不想要任何关于不存在的文件的消息,使用rm -f。< / p >

如果您需要在文件不存在时采取一些操作,那么您必须自己进行测试。根据您的示例代码,在这个实例中不是这样的。

我的解决方案推荐的背景是一个朋友的故事,进入第二周 他的第一份工作,清空了半个构建服务器。所以基本任务是找出一个文件是否存在, 如果是,我们把它删掉。但是这条河上有一些危险的急流:

  • 所有东西都是文件。

  • 脚本只有在解决一般任务时才有真正的力量

  • 一般来说,我们使用变量

  • 我们经常在脚本中使用-f force来避免人工干预

  • 还有-r递归,以确保我们及时地创建,复制和销毁。

考虑以下场景:

我们有一个想要删除的文件:filesexists.json

这个文件名存储在一个变量中

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"

我们还有一个路径变量来让事情变得更灵活

<host>:~/Documents/thisfolderexists pathtofile=".."


<host>:~/Documents/thisfolderexists ls $pathtofile


filesexists.json  history20170728  SE-Data-API.pem  thisfolderexists

所以让我们看看-e是否做了它应该做的事情。文件是否存在?

<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?


0

它的功能。魔法。

但是,如果文件变量不小心被求值为nuffin,会发生什么呢?

<host>:~/Documents/thisfolderexists filevariable=""


<host>:~/Documents/thisfolderexists [ -e $pathtofile/$filevariable ]; echo $?


0
< p >什么?它应该返回一个错误…这是整个故事的开始 文件夹被意外删除

另一种方法是专门测试我们所理解的“文件”

<host>:~/Documents/thisfolderexists filevariable="filesexists.json"


<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?


0

所以文件存在…

<host>:~/Documents/thisfolderexists filevariable=""


<host>:~/Documents/thisfolderexists test -f $pathtofile/$filevariable; echo $?


1

这不是一个文件,我们可能不想删除整个目录

man test有以下内容:

-b FILE


FILE exists and is block special


-c FILE


FILE exists and is character special


-d FILE


FILE exists and is a directory


-e FILE


FILE exists


-f FILE


FILE exists and is a regular file


...


-h FILE


FILE exists and is a symbolic link (same as -L)

如果你正在使用NFS,“test”是一个更好的解决方案,因为你可以为它添加一个超时,以防NFS宕机:

time timeout 3 test -f
/nfs/my_nfs_is_currently_down
real    0m3.004s <<== timeout is taken into account
user    0m0.001s
sys     0m0.004s
echo $?
124   <= 124 means the timeout has been reached

一个"[-e my_file]"构造将被冻结,直到NFS再次起作用:

if [ -e /nfs/my_nfs_is_currently_down ]; then echo "ok" else echo "ko" ; fi


<no answer from the system, my session is "frozen">

你也可以使用stat:

stat /
File: /
Size: 4096            Blocks: 8          IO Block: 4096   directory
Device: fd01h/64769d    Inode: 2           Links: 26
Access: (0755/drwxr-xr-x)  Uid: (    0/    root)   Gid: (    0/    root)
Access: 2009-01-01 02:00:00.000000000 +0200
Modify: 2009-01-01 02:00:00.000000000 +0200
Change: 2009-01-01 02:00:00.000000000 +0200
Birth: -

在一个不存在的路径上,你会得到:

stat /aaa
stat: cannot stat '/aaa': No such file or directory