Java学习者论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

手机号码,快捷登录

恭喜Java学习者论坛(https://www.javaxxz.com)已经为数万Java学习者服务超过8年了!积累会员资料超过10000G+
成为本站VIP会员,下载本站10000G+会员资源,购买链接:点击进入购买VIP会员
JAVA高级面试进阶视频教程Java架构师系统进阶VIP课程

分布式高可用全栈开发微服务教程

Go语言视频零基础入门到精通

Java架构师3期(课件+源码)

Java开发全终端实战租房项目视频教程

SpringBoot2.X入门到高级使用教程

大数据培训第六期全套视频教程

深度学习(CNN RNN GAN)算法原理

Java亿级流量电商系统视频教程

互联网架构师视频教程

年薪50万Spark2.0从入门到精通

年薪50万!人工智能学习路线教程

年薪50万!大数据从入门到精通学习路线年薪50万!机器学习入门到精通视频教程
仿小米商城类app和小程序视频教程深度学习数据分析基础到实战最新黑马javaEE2.1就业课程从 0到JVM实战高手教程 MySQL入门到精通教程
查看: 249|回复: 0

[默认分类] How do I tell if a regular file does not exist in Bash?

[复制链接]
  • TA的每日心情
    开心
    2021-12-13 21:45
  • 签到天数: 15 天

    [LV.4]偶尔看看III

    发表于 2018-5-18 14:55:51 | 显示全部楼层 |阅读模式
    I"ve used the following script to see if a file exists:
    我使用下面的脚本查看是否存在文件:
    1. [code]#!/bin/bash
    2. FILE=$1     
    3. if [ -f $FILE ]; then
    4.    echo "File $FILE exists."
    5. else
    6.    echo "File $FILE does not exist."
    7. fi
    复制代码
    [/code]
    What"s the correct syntax to use if I only want to check if the file does not exist?
    如果我只想检查文件是否不存在,正确的语法是什么?
    1. [code]#!/bin/bash
    2. FILE=$1     
    3. if [ $FILE does not exist ]; then
    4.    echo "File $FILE does not exist."
    5. fi
    复制代码
    [/code]17 个解决方案#1
    3363  The test command (
    1. [
    复制代码
    here) has a "not" logical operator which is the exclamation point (similar to many other languages). Try this:
    test命令(这里)有一个“not”逻辑运算符,它是感叹号(类似于许多其他语言)。试试这个:
    1. [code]if [ ! -f /tmp/foo.txt ]; then
    2.     echo "File not found!"
    3. fi
    复制代码
    [/code]#2
    378  Bash File Testing
    Bash文件测试
    1. -b filename
    复制代码
    - Block special file
    1. -c filename
    复制代码
    - Special character file
    1. -d directoryname
    复制代码
    - Check for directory Existence
    1. -e filename
    复制代码
    - Check for file existence, regardless of type (node, directory, socket, etc.)
    1. -f filename
    复制代码
    - Check for regular file existence not a directory
    1. -G filename
    复制代码
    - Check if file exists and is owned by effective group ID
    1. -G filename set-group-id
    复制代码
    - True if file exists and is set-group-id
    1. -k filename
    复制代码
    - Sticky bit
    1. -L filename
    复制代码
    - Symbolic link
    1. -O filename
    复制代码
    - True if file exists and is owned by the effective user id
    1. -r filename
    复制代码
    - Check if file is a readable
    1. -S filename
    复制代码
    - Check if file is socket
    1. -s filename
    复制代码
    - Check if file is nonzero size
    1. -u filename
    复制代码
    - Check if file set-user-id bit is set
    1. -w filename
    复制代码
    - Check if file is writable
    1. -x filename
    复制代码
    - Check if file is executable
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -等)- f文件名——检查常规文件的存在不是一个目录- g文件名,检查文件是否存在,是否拥有有效的组ID - g文件名set-group-id——如果文件存在,set-group-id - k文件名——粘贴位- l文件名——符号链接- o文件,如果文件存在,属于有效用户ID - r文件名-检查文件是否可读- s文件名检查文件是否插座- s文件名-检查文件是否非零大小- u文件名检查文件是否set-user-id设置-w文件名-检查文件是否可写-x文件名-检查文件是否可执行?
    How to use:
    如何使用:
    1. [code]#!/bin/bash
    2. file=./file
    3. if [ -e "$file" ]; then
    4.     echo "File exists"
    5. else
    6.     echo "File does not exist"
    7. fi
    复制代码
    [/code]
    A test expression can be negated by using the
    1. !
    复制代码
    operator
    一个测试表达式可以通过使用!操作符
    1. [code]#!/bin/bash
    2. file=./file
    3. if [ ! -e "$file" ]; then
    4.     echo "File does not exist"
    5. else
    6.     echo "File exists"
    7. fi
    复制代码
    [/code]#3
    245  You can negate an expression with "!":
    你可以用“!”来否定一个表达式。
    1. [code]#!/bin/bash
    2. FILE=$1
    3. if [ ! -f "$FILE" ]
    4. then
    5.     echo "File $FILE does not exist"
    6. fi
    复制代码
    [/code]
    The relevant man page is
    1. man test
    复制代码
    or, equivalently,
    1. man [
    复制代码
    -- or
    1. help test
    复制代码
    or
    1. help [
    复制代码
    for the built-in bash command.
    相关的man页面是man测试,或者,等价地,man[——或者帮助测试或帮助(用于内置bash命令)。#4
    107
    1. [code][[ -f $FILE ]] || printf "%s does not exist!\n" "$FILE"
    复制代码
    [/code]
    Also, it"s possible that the file is a broken symbolic link, or a non-regular file, like e.g. a socket, device or fifo. For example, to add a check for broken symlinks:
    另外,文件可能是一个损坏的符号链接,或者是一个非规则文件,比如一个插座、设备或fifo。例如,要添加检查断开的符号链接:
    1. [code]if [[ ! -f $FILE ]]; then
    2.     if [[ -L $FILE ]]; then
    3.         printf "%s is a broken symlink!\n" "$FILE"
    4.     else
    5.         printf "%s does not exist!\n" "$FILE"
    6.     fi
    7. fi
    复制代码
    [/code]#5
    79  It"s worth mentioning that if you need to execute a single command you can abbreviate
    值得一提的是,如果您需要执行一个命令,您可以缩写。
    1. [code]if [ ! -f "$file" ]; then
    2.     echo "$file"
    3. fi
    复制代码
    [/code]
    to
    1. [code]test -f "$file" || echo "$file"
    复制代码
    [/code]
    or
    1. [code][ -f "$file" ] || echo "$file"
    复制代码
    [/code]#6
    54  I prefer to do the following one-liner, in POSIX shell compatible format:
    我更喜欢用POSIX shell兼容格式做以下一行:
    1. [code]$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND"
    2. $ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
    复制代码
    [/code]
    For a couple of commands, like I would do in a script:
    对于一些命令,如我在脚本中所做的:
    1. [code]$  [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
    复制代码
    [/code]
    Once I started doing this, I rarely use the fully typed syntax anymore!!
    一旦我开始这样做,我就很少使用完全类型化的语法了!!#7
    35  To test file existence, the parameter can be any one of the following:
    为了测试文件的存在,参数可以是以下任何一个:
    1. [code]-e: Returns true if file exists (regular file, directory, or symlink)
    2. -f: Returns true if file exists and is a regular file
    3. -d: Returns true if file exists and is a directory
    4. -h: Returns true if file exists and is a symlink
    复制代码
    [/code]
    All the tests below apply to regular files, directories, and symlinks:
    下面的所有测试都适用于常规文件、目录和符号链接:
    1. [code]-r: Returns true if file exists and is readable
    2. -w: Returns true if file exists and is writable
    3. -x: Returns true if file exists and is executable
    4. -s: Returns true if file exists and has a size > 0
    复制代码
    [/code]
    Example script:
    示例脚本:
    1. [code]#!/bin/bash
    2. FILE=$1
    3. if [ -f "$FILE" ]; then
    4.    echo "File $FILE exists"
    5. else
    6.    echo "File $FILE does not exist"
    7. fi
    复制代码
    [/code]#8
    28  You should be careful about running
    1. test
    复制代码
    for an unquoted variable, because it might produce unexpected results:
    对于未引用的变量,您应该注意运行测试,因为它可能会产生意想不到的结果:
    1. [code]$ [ -f ]
    2. $ echo $?
    3. 0
    4. $ [ -f "" ]
    5. $ echo $?
    6. 1
    复制代码
    [/code]
    The recommendation is usually to have the tested variable surrounded by double quotation marks:
    建议通常使用双引号包围的测试变量:
    1. [code]#!/bin/sh
    2. FILE=$1
    3. if [ ! -f "$FILE" ]
    4. then
    5.    echo "File $FILE does not exist."
    6. fi
    复制代码
    [/code]#9
    17  There are three distinct ways to do this:
    有三种不同的方法:

    Negate the exit status with bash (no other answer has said this):用bash否定退出状态(没有其他回答说过):
    1. [code]if ! [ -e "$file" ]; then
    2.     echo "file does not exist"
    3. fi
    复制代码
    [/code] Or:或者:
    1. [code]! [ -e "$file" ] && echo "file does not exist"
    复制代码
    [/code]
    Negate the test inside the test command
    1. [
    复制代码
    (that is the way most answers before have presented):在测试命令中否定测试[(这是大多数回答之前的方法):
    1. [code]if [ ! -e "$file" ]; then
    2.     echo "file does not exist"
    3. fi
    复制代码
    [/code] Or:或者:
    1. [code][ ! -e "$file" ] && echo "file does not exist"
    复制代码
    [/code]
    Act on the result of the test being negative (
    1. ||
    复制代码
    instead of
    1. &&
    复制代码
    ):测试结果为阴性(||而不是&&): Only:只有:
    1. [code][ -e "$file" ] || echo "file does not exist"
    复制代码
    [/code] This looks silly (IMO), don"t use it unless your code has to be portable to the Bourne shell (like the
    1. /bin/sh
    复制代码
    of Solaris 10 or earlier) that lacked the pipeline negation operator (
    1. !
    复制代码
    ):这看起来很傻(IMO),除非您的代码必须能够移植到Bourne shell(比如Solaris 10或更早的版本的/bin/sh),否则就不要使用它,因为它缺少管道的否定操作符(!)
    1. [code]if [ -e "$file" ]; then
    2.     :
    3. else
    4.     echo "file does not exist"
    5. fi
    复制代码
    [/code]
    #10
    11  In
    1. [code][ -f "$file" ]
    复制代码
    [/code]
    the
    1. [
    复制代码
    command does a
    1. stat()
    复制代码
    (not
    1. lstat()
    复制代码
    ) system call on the path stored in
    1. $file
    复制代码
    and returns true if that system call succeeds and the type of the file as returned by
    1. stat()
    复制代码
    is "regular".
    命令执行一个stat()(而不是lstat())系统调用存储在$file中的路径,如果系统调用成功,则返回true,而stat()返回的文件类型为“regular”。
    So if
    1. [ -f "$file" ]
    复制代码
    returns true, you can tell the file does exist and is a regular file or a symlink eventually resolving to a regular file (or at least it was at the time of the
    1. stat()
    复制代码
    ).
    因此,如果[-f "$file"]返回true,您可以告诉该文件确实存在,并且是一个常规文件或一个符号链接,最终解析为一个普通文件(或者至少是在stat()的时候)。
    However if it returns false (or if
    1. [ ! -f "$file" ]
    复制代码
    or
    1. ! [ -f "$file" ]
    复制代码
    return true), there are many different possibilities:
    但是如果它返回false(或者[!-f "$file"]或![-f "$file"]返回true),有许多不同的可能性:

    the file doesn"t exist
    该文件不存在
    the file exists but is not a regular file
    文件存在,但不是常规文件。
    the file exists but you don"t have search permission to the parent directory
    文件存在,但您没有搜索权限到父目录。
    the file exists but that path to access it is too long
    文件存在,但是访问它的路径太长。
    the file is a symlink to a regular file, but you don"t have search permission to some of the directories involved in the resolution of the symlink.
    这个文件是一个普通文件的符号链接,但是你没有搜索权限到一些涉及到符号链接解析的目录。
    ... any other reason why the
    1. stat()
    复制代码
    system call may fail.
    …stat()系统调用可能失败的其他原因。

    In short, it should be:
    简而言之,它应该是:
    1. [code]if [ -f "$file" ]; then
    2.   printf ""%s" is a path to a regular file or symlink to regular file\n" "$file"
    3. elif [ -e "$file" ]; then
    4.   printf ""%s" exists but is not a regular file\n" "$file"
    5. elif [ -L "$file" ]; then
    6.   printf ""%s" exists, is a symlink but I cannot tell if it eventually resolves to an actual file, regular or not\n" "$file"
    7. else
    8.   printf "I cannot tell if "%s" exists, let alone whether it is a regular file or not\n" "$file"
    9. fi
    复制代码
    [/code]
    To know for sure that the file doesn"t exist, we"d need the
    1. stat()
    复制代码
    system call to return with an error code of
    1. ENOENT
    复制代码
    (
    1. ENOTDIR
    复制代码
    tells us one of the path components is not a directory is another case where we can tell the file doesn"t exist by that path). Unfortunately the
    1. [
    复制代码
    command doesn"t let us know that. It will return false whether the error code is ENOENT, EACCESS (permission denied), ENAMETOOLONG or anything else.
    要确定该文件不存在,我们需要stat()系统调用返回带有ENOENT的错误代码(ENOTDIR告诉我们其中一个路径组件不是目录,这是另一个我们可以告诉文件不存在该路径的情况)。不幸的是,[命令不让我们知道]。如果错误代码是ENOENT、EACCESS(权限被拒绝)、ENAMETOOLONG或其他任何东西,它将返回false。
    The
    1. [ -e "$file" ]
    复制代码
    test can also be done with
    1. ls -Ld -- "$file" > /dev/null
    复制代码
    . In that case,
    1. ls
    复制代码
    will tell you why the
    1. stat()
    复制代码
    failed, though the information can"t easily be used programmatically:
    也可以用ls -Ld—“$file”> /dev/null来测试[-e“$file”]测试。在这种情况下,ls将告诉您为什么stat()失败了,尽管这些信息不容易以编程的方式使用:
    1. [code]$ file=/var/spool/cron/crontabs/root
    2. $ if [ ! -e "$file" ]; then echo does not exist; fi
    3. does not exist
    4. $ if ! ls -Ld -- "$file" > /dev/null; then echo stat failed; fi
    5. ls: cannot access "/var/spool/cron/crontabs/root": Permission denied
    6. stat failed
    复制代码
    [/code]
    At least
    1. ls
    复制代码
    tells me it"s not because the file doesn"t exist that it fails. It"s because it can"t tell whether the file exists or not. The
    1. [
    复制代码
    command just ignored the problem.
    至少ls告诉我这不是因为文件不存在,它失败了。因为它不能判断文件是否存在。这个命令忽略了这个问题。
    With the
    1. zsh
    复制代码
    shell, you can query the error code with the
    1. $ERRNO
    复制代码
    special variable after the failing
    1. [
    复制代码
    command, and decode that number using the
    1. $errnos
    复制代码
    special array in the
    1. zsh/system
    复制代码
    module:
    使用zsh shell,您可以在失败[命令]之后,用$ERRNO特殊变量查询错误代码,并使用zsh/system模块中的$errnos特殊数组对该数字进行解码:
    1. [code]zmodload zsh/system
    2. ERRNO=0
    3. if [ ! -f "$file" ]; then
    4.   err=$ERRNO
    5.   case $errnos[err] in
    6.     ("") echo exists, not a regular file;;
    7.     (ENOENT|ENOTDIR)
    8.        if [ -L "$file" ]; then
    9.          echo broken link
    10.        else
    11.          echo does not exist
    12.        fi;;
    13.     (*) echo "can"t tell"; syserror "$err"
    14.   esac
    15. fi
    复制代码
    [/code]
    (beware the
    1. $errnos
    复制代码
    support is broken with some versions of
    1. zsh
    复制代码
    when built with recent versions of
    1. gcc
    复制代码
    ).
    (请注意,在使用最新版本的gcc时,$errnos支持会被某些版本的zsh破坏)。#11
    10  You can use Bash specific:
    您可以使用Bash特定:
    1. [code][[ ! -f "$FILE" ]] && echo "File doesn"t exist"
    复制代码
    [/code]
    or
    1. [code]if [[ ! -f "$FILE" ]]; then
    2.     echo "File doesn"t exist"
    3. fi
    复制代码
    [/code]
    If you want to check for file and folder both, then use
    1. -e
    复制代码
    option instead of
    1. -f
    复制代码
    .
    如果您想要检查文件和文件夹,那么使用-e选项而不是-f。#12
    7  To reverse a test, use "!". That is equivalent to the "not" logical operator in other languages. Try this:
    要反转测试,请使用“!”这相当于其他语言中的“not”逻辑运算符。试试这个:
    1. [code]if [ ! -f /tmp/foo.txt ];
    2. then
    3.     echo "File not found!"
    4. fi
    复制代码
    [/code]
    Or written in a slightly different way:
    或者以一种稍微不同的方式写:
    1. [code]if [ ! -f /tmp/foo.txt ]
    2.     then echo "File not found!"
    3. fi
    复制代码
    [/code]
    Or you could use:
    或者你可以使用:
    1. [code]if ! [ -f /tmp/foo.txt ]
    2.     then echo "File not found!"
    3. fi
    复制代码
    [/code]
    Or, presing all together:
    或者,总统在一起:
    1. [code]if ! [ -f /tmp/foo.txt ]; then echo "File not found!"; fi
    复制代码
    [/code]
    Which may be written (using then "and" operator: &&) as:
    可以写(然后用“和”操作符:&&)作为:
    1. [code][ ! -f /tmp/foo.txt ] && echo "File not found!"
    复制代码
    [/code]
    Which looks shorter like this:
    它看起来更短:
    1. [code][ -f /tmp/foo.txt ] || echo "File not found!"
    复制代码
    [/code]#13
    7  The
    1. test
    复制代码
    thing may count too. It worked for me (based on Bash Shell: Check File Exists or Not):
    测试的结果也有可能。它为我工作(基于Bash Shell:检查文件是否存在):
    1. [code]test -e FILENAME && echo "File exists" || echo "File doesn"t exist"
    复制代码
    [/code]#14
    7  This code also working .
    这段代码也可以工作。
    1. [code]#!/bin/bash
    2. FILE=$1
    3. if [ -f $FILE ]; then
    4. echo "File "$FILE" Exists"
    5. else
    6. echo "The File "$FILE" Does Not Exist"
    7. fi
    复制代码
    [/code]#15
    4  The simplest way
    最简单的方法
    1. [code]FILE=$1
    2. [ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
    复制代码
    [/code]#16
    2  This shell script also works for finding a file in a directory:
    这个shell脚本也适用于在目录中查找文件:
    1. [code]echo "enter file"
    2. read -r a
    3. if [ -s /home/trainee02/"$a" ]
    4. then
    5.     echo "yes. file is there."
    6. else
    7.     echo "sorry. file is not there."
    8. fi
    复制代码
    [/code]#17
    1  sometimes it may be handy to use && and || operators.
    有时使用&&和||操作符可能很方便。
    Like in (if you have command "test"):
    像in(如果你有命令“测试”):
    1. [code]test -b $FILE && echo File not there!
    复制代码
    [/code]
    or
    1. [code]test -b $FILE || echo File there!
    复制代码
    [/code]
    回复

    使用道具 举报

    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    QQ|手机版|Java学习者论坛 ( 声明:本站资料整理自互联网,用于Java学习者交流学习使用,对资料版权不负任何法律责任,若有侵权请及时联系客服屏蔽删除 )

    GMT+8, 2024-5-17 06:58 , Processed in 0.374824 second(s), 37 queries .

    Powered by Discuz! X3.4

    © 2001-2017 Comsenz Inc.

    快速回复 返回顶部 返回列表