代码之家  ›  专栏  ›  技术社区  ›  Bill the Lizard

如何判断Bash中是否不存在常规文件?

  •  2802
  • Bill the Lizard  · 技术社区  · 16 年前

    这将检查文件是否存在:

    #!/bin/bash
    
    FILE=$1     
    if [ -f $FILE ]; then
       echo "File $FILE exists."
    else
       echo "File $FILE does not exist."
    fi
    

    17 回复  |  直到 9 年前
        1
  •  4973
  •   John Feminella    11 年前

    test 命令(写作 [ 这里)具有“not”逻辑运算符, !

    if [ ! -f /tmp/foo.txt ]; then
        echo "File not found!"
    fi
    
        2
  •  783
  •   BlueCacti    9 年前

    Bash文件测试

    -b filename -阻止特殊文件
    -c filename
    -d directoryname -检查目录是否存在
    -e filename -检查文件是否存在,无论类型如何(节点、目录、套接字等)
    -f filename
    -G filename -检查文件是否存在以及是否由有效组ID拥有
    -G filename set-group-id
    -k filename
    -L filename -符号链接
    -O filename -如果文件存在并且由有效用户id拥有,则为True
    -r filename
    -S filename -检查文件是否为套接字
    -s filename
    -u filename -检查是否设置了文件集用户id位
    -w filename
    -x filename -检查文件是否可执行

    #!/bin/bash
    file=./file
    if [ -e "$file" ]; then
        echo "File exists"
    else 
        echo "File does not exist"
    fi 
    

    ! 操作员

    #!/bin/bash
    file=./file
    if [ ! -e "$file" ]; then
        echo "File does not exist"
    else 
        echo "File exists"
    fi 
    
        3
  •  304
  •   starbeamrainbowlabs Trevor    8 年前

    否定里面的表达式 test (为此 [ 是别名)使用 ! :

    #!/bin/bash
    FILE=$1
    
    if [ ! -f "$FILE" ]
    then
        echo "File $FILE does not exist"
    fi
    

    相关手册页为 man test 或者等效地, man [ help test help [ 对于内置的bash命令。

    测试 使用:

    if ! [ -f "$FILE" ]
    then
        echo "File $FILE does not exist"
    fi
    

    “和” 复合命令 ".

        4
  •  145
  •   ormaaj    11 年前
    [[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"
    

    if [[ ! -f $FILE ]]; then
        if [[ -L $FILE ]]; then
            printf '%s is a broken symlink!\n' "$FILE"
        else
            printf '%s does not exist!\n' "$FILE"
        fi
    fi
    
        5
  •  109
  •   ormaaj    11 年前

    值得一提的是,如果你需要执行一个命令,你可以缩写

    if [ ! -f "$file" ]; then
        echo "$file"
    fi
    

    test -f "$file" || echo "$file"
    

    [ -f "$file" ] || echo "$file"
    
        6
  •  73
  •   Peter Mortensen Pieter Jan Bonestroo    10 年前

    POSIX shell兼容格式:

    $ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
    
    $ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
    

    $  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
    

    一旦我开始这样做,我就很少再使用全类型语法了!!

        7
  •  58
  •   codeforester    9 年前

    -e: Returns true if file exists (regular file, directory, or symlink)
    -f: Returns true if file exists and is a regular file
    -d: Returns true if file exists and is a directory
    -h: Returns true if file exists and is a symlink
    

    -r: Returns true if file exists and is readable
    -w: Returns true if file exists and is writable
    -x: Returns true if file exists and is executable
    -s: Returns true if file exists and has a size > 0
    

    示例脚本:

    #!/bin/bash
    FILE=$1
    
    if [ -f "$FILE" ]; then
       echo "File $FILE exists"
    else
       echo "File $FILE does not exist"
    fi
    
        8
  •  45
  •   Jahid Ramsy de Vos    7 年前

    您可以这样做:

    [[ ! -f "$FILE" ]] && echo "File doesn't exist"
    

    if [[ ! -f "$FILE" ]]; then
        echo "File doesn't exist"
    fi
    

    如果您想同时检查文件和文件夹,请使用 -e 选项而不是 -f . e 对于常规文件、目录、套接字、字符特殊文件、块特殊文件等返回true。

        9
  •  39
  •   Peter Mortensen Pieter Jan Bonestroo    10 年前

    你应该小心跑步 test

    $ [ -f ]
    $ echo $?
    0
    $ [ -f "" ]
    $ echo $?
    1
    

    通常建议将测试变量用双引号括起来:

    #!/bin/sh
    FILE=$1
    
    if [ ! -f "$FILE" ]
    then
       echo "File $FILE does not exist."
    fi
    
        10
  •  27
  •   Stephane Chazelas Ash Wilson    6 年前

    [ -f "$file" ]
    

    [ 命令执行a stat() (不是 lstat() )存储在路径上的系统调用 $file 并返回 如果该系统调用成功,并且返回的文件类型为 stat() 是“ 常规的 ".

    [ -f "$file" ] stat() ).

    但是,如果它回来了 [ ! -f "$file" ] ! [ -f "$file" ] return true),有许多不同的可能性:

    • 文件不存在
    • 常规的
    • 文件存在,但访问它的路径太长
    • 该文件是指向常规文件的符号链接,但您对解析符号链接所涉及的某些目录没有搜索权限。
    • stat() 系统调用可能会失败。

    简而言之,它应该是:

    if [ -f "$file" ]; then
      printf '"%s" is a path to a regular file or symlink to regular file\n' "$file"
    elif [ -e "$file" ]; then
      printf '"%s" exists but is not a regular file\n' "$file"
    elif [ -L "$file" ]; then
      printf '"%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n' "$file"
    else
      printf 'I cannot tell if "%s" exists, let alone whether it is a regular file or not\n' "$file"
    fi
    

    stat() ENOENT ( ENOTDIR 告诉我们其中一个路径组件不是目录,这是另一种情况,我们可以通过该路径判断文件不存在)。不幸的是 [

    [ -e "$file" ] ls -Ld -- "$file" > /dev/null ls 会告诉你为什么 stat() 失败了,尽管这些信息不能很容易地以编程方式使用:

    $ file=/var/spool/cron/crontabs/root
    $ if [ ! -e "$file" ]; then echo does not exist; fi
    does not exist
    $ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
    ls: cannot access '/var/spool/cron/crontabs/root': Permission denied
    stat failed
    

    至少 ls [ 命令只是忽略了这个问题。

    随着 zsh $ERRNO [ 命令,并使用 $errnos 特殊数组 zsh/system 模块:

    zmodload zsh/system
    ERRNO=0
    if [ ! -f "$file" ]; then
      err=$ERRNO
      case $errnos[err] in
        ("") echo exists, not a regular file;;
        (ENOENT|ENOTDIR)
           if [ -L "$file" ]; then
             echo broken link
           else
             echo does not exist
           fi;;
        (*) syserror -p "can't tell: " "$err"
      esac
    fi
    

    $errnos support was broken with some versions of zsh when built with recent versions of gcc ).

        11
  •  24
  •   Stephane Chazelas Ash Wilson    9 年前

    1. if ! [ -e "$file" ]; then
          echo "file does not exist"
      fi
      

      或者:

      ! [ -e "$file" ] && echo "file does not exist"
      
    2. [

      if [ ! -e "$file" ]; then
          echo "file does not exist"
      fi
      

      或者:

      [ ! -e "$file" ] && echo "file does not exist"
      
    3. 根据测试结果为阴性采取行动( || 而不是 && ):

      仅限于:

      [ -e "$file" ] || echo "file does not exist"
      

      /bin/sh ! ):

      if [ -e "$file" ]; then
          :
      else
          echo "file does not exist"
      fi
      
        12
  •  11
  •   user2350426 user2350426    12 年前
    envfile=.env
    
    if [ ! -f "$envfile" ]
    then
        echo "$envfile does not exist"
        exit 1
    fi
    
        13
  •  10
  •   Peter Mortensen Pieter Jan Bonestroo    12 年前

    这相当于其他语言中的“not”逻辑运算符。试试这个:

    if [ ! -f /tmp/foo.txt ];
    then
        echo "File not found!"
    fi
    

    或者用稍微不同的方式写:

    if [ ! -f /tmp/foo.txt ]
        then echo "File not found!"
    fi
    

    或者,您可以使用:

    if ! [ -f /tmp/foo.txt ]
        then echo "File not found!"
    fi
    

    if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
    

    可以写成(使用then“and”运算符:&):

    [ ! -f /tmp/foo.txt ] && echo "File not found!"
    

    [ -f /tmp/foo.txt ] || echo "File not found!"
    
        14
  •  10
  •   Lemon Kazi    10 年前

    test 事情可能也很重要。它为我工作(基于 Bash Shell: Check File Exists or Not ):

    test -e FILENAME && echo "File exists" || echo "File doesn't exist"
    
        15
  •  7
  •   Asclepius    10 年前

    这段代码也在工作。

    #!/bin/bash
    FILE=$1
    if [ -f $FILE ]; then
     echo "File '$FILE' Exists"
    else
     echo "The File '$FILE' Does Not Exist"
    fi
    
        16
  •  6
  •   Jonathan Leffler    10 年前

    FILE=$1
    [ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
    
        17
  •  6
  •   Andre    8 年前

    echo "enter file"
    
    read -r a
    
    if [ -s /home/trainee02/"$a" ]
    then
        echo "yes. file is there."
    else
        echo "sorry. file is not there."
    fi
    
        18
  •  4
  •   Bill the Lizard    6 年前

    如(如果你有命令“test”):

    test -b $FILE && echo File not there!
    

    test -b $FILE || echo File there!
    
        19
  •  3
  •   upteryx    6 年前

    test 而不是 [] ! 要得到否定:

    if ! test "$FILE"; then
      echo "does not exist"
    fi
    
        20
  •  3
  •   kta    5 年前

    [ -f "filename" ] || ( echo test1 && echo test2 && echo test3 )

    [ -f "filename" ] || { echo test1 && echo test2 && echo test3 ;}

    如果filename没有退出,输出将是

    test1
    test2
    test3
    

    Note :(…)在子shell中运行,{…;}在同一shell中运行。