代码之家  ›  专栏  ›  技术社区  ›  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
    

    如果我只想检查文件是否正确,那么正确的语法是什么 存在

    #!/bin/bash
    
    FILE=$1     
    if [ $FILE does not exist ]; then
       echo "File $FILE does not exist."
    fi
    
    17 回复  |  直到 8 年前
        1
  •  4973
  •   John Feminella    10 年前

    这个 test [ 这里)有一个“not”逻辑运算符,它是感叹号(类似于许多其他语言)。试试这个:

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

    -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
    -w filename -检查文件是否可写
    -x filename

    如何使用:

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

    A. 测试表达式 可以使用 ! 操作人员

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

    可以用“!”来否定表达式:

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

    man test 或者,相当于, man [ help test help [

        4
  •  145
  •   ormaaj    10 年前
    [[ -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    10 年前

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

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

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

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

    POSIX

    $ [ -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    8 年前

    要测试文件是否存在,参数可以是以下任意一个:

    -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 icecrime    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" ]
    

    这个 [ 命令执行以下操作: stat() (不是 lstat() $file 返回 符合事实的 stat() 是“ ".

    所以如果 [ -f "$file" ] stat() ).

    但是如果它回来 错误的 [ ! -f "$file" ] ! [ -f "$file" ]

    • 该文件不存在
    • 该文件存在,但不是一个 文件(可以是设备、fifo、目录、套接字…)
    • 文件存在,但您没有父目录的搜索权限
    • 文件存在,但访问该文件的路径太长
    • 该文件是常规文件的符号链接,但您没有对符号链接解析中涉及的某些目录的搜索权限。
    • ... 还有其他原因吗 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
    

    要确定该文件不存在,我们需要 返回的系统调用,错误代码为 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 shell,您可以使用 $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    8 年前

    1. 用bash否定退出状态(没有其他答案这么说):

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

      或:

      ! [ -e "$file" ] && echo "file does not exist"
      
    2. 在test命令中取消测试 [

      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 Solaris 10或更早版本)中缺少管道否定运算符的( ! ):

      if [ -e "$file" ]; then
          :
      else
          echo "file does not exist"
      fi
      
        12
  •  11
  •   user2350426 user2350426    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!"
    
        13
  •  10
  •   Peter Mortensen icecrime    11 年前

    test 事情可能也很重要。它对我有效(基于 Bash Shell: Check File Exists or Not

    test -e FILENAME && echo "File exists" || echo "File doesn't exist"
    
        14
  •  10
  •   Lemon Kazi    9 年前

    这段代码也可以工作。

    #!/bin/bash
    FILE=$1
    if [ -f $FILE ]; then
     echo "File '$FILE' Exists"
    else
     echo "The File '$FILE' Does Not Exist"
    fi
    
        15
  •  7
  •   Asclepius    9 年前

    最简单的方法

    FILE=$1
    [ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
    
        16
  •  6
  •   Jonathan Leffler    9 年前

    此shell脚本还可用于在目录中查找文件:

    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
    
        17
  •  6
  •   Andre    8 年前

    有时它可能很方便使用&&和| |运算符。

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

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

    test -b $FILE || echo File there!
    
        18
  •  4
  •   Bill the Lizard    5 年前

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

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

    您还可以在一个命令行中对多个命令进行分组

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

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

    test1
    test2
    test3
    

    注意:(…)在子shell中运行,{…;}在同一shell中运行。 花括号表示法仅适用于bash。

        20
  •  3
  •   kta    4 年前
    envfile=.env
    
    if [ ! -f "$envfile" ]
    then
        echo "$envfile does not exist"
        exit 1
    fi