【问题标题】:How to check if a file exists in a shell script如何检查文件是否存在于 shell 脚本中
【发布时间】:2016-10-17 09:05:51
【问题描述】:

我想编写一个 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 脚​​本时。代码有什么问题?

【问题讨论】:

标签: shell


【解决方案1】:

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

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

【讨论】:

  • 我最后加了两个空格,一个在左方括号之后,一个在右方括号之前:[ -e archived_sensor_data.json ] && rm archived_sensor_data.json。该脚本现在似乎可以工作了。
  • 这也适用于if [ -e "$1" ](文件名输入参数)。
  • 这里的主要区别在于您使用的是“bash”脚本而不是“shell”脚本。请注意,您添加的第一行是#!/bin/bash,因此您是在告诉机器使用“bash”而不是 sh。因为 sh 不承认那个论点“-e”
【解决方案2】:

这是使用ls的替代方法:

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

如果您想隐藏来自ls 的任何输出以便只看到是或否,请将stdoutstderr 重定向到/dev/null

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

【讨论】:

  • 这段代码的意思是:“如果ls成功,则有这样的文件,否则,没有”。如果ls 失败,并不意味着该文件丢失。可能是其他一些错误。例如,在root拥有的目录中创建文件,并尝试在普通用户下执行ls。它将失败并显示Permission denied,这不等于文件不存在。
  • @Tigran 这是一个很好的区别,在我的情况下并不重要,但感谢您指出。
【解决方案3】:

我的解决方案推荐的背景是一个朋友的故事,他在第二周 他的第一份工作,擦掉了一半的构建服务器。所以基本任务是确定文件是否存在, 如果是这样,让我们​​删除它。但这条河上有几处险峻的急流:

  • 一切都是文件。

  • 脚本只有在解决一般任务时才能真正发挥作用

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

  • 我们经常在脚本中使用 -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

什么?它应该返回一个错误......这就是故事的开始 文件夹不小心被删除了

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

<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】:

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

    rm filename
    

    然后它就会消失,无论它是否存在。
    使用 rm -f 是您不想要任何有关不存在文件的消息。

    如果您需要在文件不存在的情况下采取一些措施,那么您必须自己进行测试。根据您的示例代码,本例中并非如此。

    【讨论】:

    • 这实际上是 rm 命令的一个非常有效的答案。对于其他命令,我建议使用 -e 进行测试。
    • 除非问题不是问的。
    • 如果您阅读了 whole 问题,包括“......并且(如果是的话)......删除它”部分,这就是问题所要问的。
    • 请不要那样做。大多数系统现在不会提示确认删除文件。
    【解决方案5】:

    如果您使用的是 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">
    

    【讨论】:

    • test[ 是同义词。您也可以将timeout[ 一起使用,如果NFS 挂起,test 也会冻结。
    • 容器化验证太棒了!!!谢谢
    【解决方案6】:

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

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-11-23
      • 2017-09-11
      • 1970-01-01
      • 1970-01-01
      • 2015-09-13
      • 2014-03-30
      • 2016-05-14
      • 1970-01-01
      相关资源
      最近更新 更多