如何检查shell脚本中是否存在文件

时间:2016-10-17 09:05:51

标签: 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脚本时。代码有什么问题?

6 个答案:

答案 0 :(得分:280)

您在括号与-e之间缺少必要的空格:

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

答案 1 :(得分:19)

以下是使用ls的替代方法:

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

如果您要隐藏ls的任何输出,因此您只看到是或否,请将stdoutstderr重定向到/dev/null

(ls x.txt >> /dev/null 2>&1 && echo yes) || echo no

答案 2 :(得分:5)

在内部,无论如何rm命令必须测试文件是否存在,
那为什么还要添加另一个测试?刚刚发出

rm filename

无论那里是否存在,它都会消失。
如果您不需要有关不存在文件的任何消息,请使用rm -f。

如果文件不存在,如果需要采取一些措施,则必须自己进行测试。根据您的示例代码,在这种情况下不是这种情况。

答案 3 :(得分:4)

我的解决方案建议的背景是一个朋友的故事,他一直到 他的第一份工作是擦拭了一半的构建服务器。因此,基本任务是确定文件是否存在, 如果是这样,我们将其删除。但是这条河上有一些险恶的急流:

  • 一切都是文件。

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

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

  • 我们经常在脚本中使用-f force以避免手动干预

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

请考虑以下情形:

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

此文件名存储在变量中

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

我们也有一个path变量来使事情变得真正灵活

<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

什么?它应该返回错误...这是整个故事的开始 文件夹被意外删除

另一种选择是专门针对我们理解为“文件”的内容进行测试

<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)

答案 4 :(得分:0)

如果您正在使用NFS,则“测试”是一种更好的解决方案,因为如果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">

答案 5 :(得分:0)

您也可以使用 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