我使用以下脚本来查看文件是否存在:
#!/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
John Feminel.. 4296
该测试命令([
在这里)有一个"非"逻辑运算符是感叹号(类似于许多其他语言).试试这个:
if [ ! -f /tmp/foo.txt ]; then echo "File not found!" fi
更简洁地说:[!-f /tmp/foo.txt] &&回显“找不到文件!” (186认同)
@DavidWinterbottom更加多汁:`[ - f /tmp/foo.txt] || echo"找不到文件!"` (141认同)
我努力寻找"如果两个文件中不存在任何文件"的正确语法.以下两者都有效:`if [!\(-f"f1"-a -f"f2"\)]; 然后回声MISSING; 如果[!] -f"f1"] || [!-f"f2"]; 然后回声MISSING; fi` (36认同)
参数可以是以下任何一种:`-e:返回true值,如果file存在``-f:返回true值,如果file存在且常规文件``-r:返回true值,如果file存在且可读``-w:返回true值,如果文件存在且可写``-x:返回true值,如果file存在且可执行``-d:返回true值,如果存在且是目录` (24认同)
使用`时存在不对称性!-f`与`&&`使用`-f`和`||`.这与非/存在检查返回的退出代码有关.如果您需要使用退出代码0来彻底退出行(有时您不需要此约束),则这两种方法不可互换.或者,只需使用`if`语句,您就不必再担心非/存在检查的退出代码. (5认同)
如果要在if操作中使用2个条件,请使用-a运算符,这意味着AND.我认为如果使用[[]]运算符,也可以使用& (2认同)
BlueCacti.. 617
Bash文件测试
-b filename
- 阻止特殊文件
-c filename
- 特殊字符文件
-d directoryname
- 检查目录是否存在
-e filename
- 检查文件是否存在,无论类型(节点,目录,套接字等)
-f filename
- 检查常规文件是否存在而不是目录
-G filename
- 检查文件是否存在且是否属于有效组ID
-G filename set-group-id
- 如果文件存在则为真且为set-group-id
-k filename
- 粘滞位
-L filename
- 符号链接
-O filename
- 如果文件存在并且由有效用户ID拥有则为真
-r filename
- 检查文件是否可读
-S filename
- 检查文件是否为套接字
-s filename
- 检查是否file是非零大小
-u filename
- 检查文件set-user-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
小智.. 283
你可以用"!"来否定表达式:
#!/bin/bash FILE=$1 if [ ! -f "$FILE" ] then echo "File $FILE does not exist" fi
相关的手册页是man test
或者等效地man [
- help test
或者help [
对于内置的bash命令.
该测试命令([
在这里)有一个"非"逻辑运算符是感叹号(类似于许多其他语言).试试这个:
if [ ! -f /tmp/foo.txt ]; then echo "File not found!" fi
Bash文件测试
-b filename
- 阻止特殊文件
-c filename
- 特殊字符文件
-d directoryname
- 检查目录是否存在
-e filename
- 检查文件是否存在,无论类型(节点,目录,套接字等)
-f filename
- 检查常规文件是否存在而不是目录
-G filename
- 检查文件是否存在且是否属于有效组ID
-G filename set-group-id
- 如果文件存在则为真且为set-group-id
-k filename
- 粘滞位
-L filename
- 符号链接
-O filename
- 如果文件存在并且由有效用户ID拥有则为真
-r filename
- 检查文件是否可读
-S filename
- 检查文件是否为套接字
-s filename
- 检查是否file是非零大小
-u filename
- 检查文件set-user-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
你可以用"!"来否定表达式:
#!/bin/bash FILE=$1 if [ ! -f "$FILE" ] then echo "File $FILE does not exist" fi
相关的手册页是man test
或者等效地man [
- help test
或者help [
对于内置的bash命令.
[[ -f $FILE ]] || printf '%s does not exist!\n' "$FILE"
此外,文件可能是破坏的符号链接,或非常规文件,例如套接字,设备或fifo.例如,要添加对损坏的符号链接的检查:
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
值得一提的是,如果你需要执行一个命令,你可以缩写
if [ ! -f "$file" ]; then echo "$file" fi
至
test -f "$file" || echo "$file"
要么
[ -f "$file" ] || echo "$file"
我更喜欢以POSIX shell兼容格式执行以下单行程序:
$ [ -f "/$DIR/$FILE" ] || echo "$FILE NOT FOUND" $ [ -f "/$DIR/$FILE" ] && echo "$FILE FOUND"
对于一些命令,就像我在脚本中所做的那样:
$ [ -f "/$DIR/$FILE" ] || { echo "$FILE NOT FOUND" ; exit 1 ;}
一旦我开始这样做,我很少再使用完全类型化的语法!
要测试文件是否存在,参数可以是以下任何一个:
-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
你可以这样做:
[[ ! -f "$FILE" ]] && echo "File doesn't exist"
要么
if [[ ! -f "$FILE" ]]; then echo "File doesn't exist" fi
如果要同时检查文件和文件夹,请使用-e
选项代替-f
.-e
对常规文件,目录,套接字,字符特殊文件,块特殊文件等返回true.
你应该小心运行test
一个不带引号的变量,因为它可能会产生意想不到的结果:
$ [ -f ] $ echo $? 0 $ [ -f "" ] $ echo $? 1
建议通常是让测试变量用双引号括起来:
#!/bin/sh FILE=$1 if [ ! -f "$FILE" ] then echo "File $FILE does not exist." fi
有三种不同的方法可以做到这一点:
用bash否定退出状态(没有其他答案说过这个):
if ! [ -e "$file" ]; then echo "file does not exist" fi
要么:
! [ -e "$file" ] && echo "file does not exist"
否定测试命令中的测试[
(这是之前大多数答案的方式):
if [ ! -e "$file" ]; then echo "file does not exist" fi
要么:
[ ! -e "$file" ] && echo "file does not exist"
根据测试结果为负(||
而不是&&
):
只要:
[ -e "$file" ] || echo "file does not exist"
这看起来很愚蠢(IMO),除非您的代码必须可移植到/bin/sh
缺少管道否定operator(!
)的Bourne shell(如Solaris 10或更早版本),否则不要使用它:
if [ -e "$file" ]; then : else echo "file does not exist" fi
在
[ -f "$file" ]
该[
命令对存储在其中的路径执行stat()
(非lstat()
)系统调用,如果系统调用成功并且返回的文件类型为"regular" ,则$file
返回truestat()
.
因此,如果[ -f "$file" ]
返回true,则可以告诉文件确实存在,并且是常规文件或符号链接最终解析为常规文件(或者至少它是在当时stat()
).
但是,如果它返回false(或者if [ ! -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
告诉我们其中一个路径组件不是目录是另一种情况,我们可以告诉该文件不存在于那条道路上).不幸的是,[
命令并没有让我们知道.无论错误代码是ENOENT,EACCESS(权限被拒绝),ENAMETOOLONG还是其他任何内容,它都将返回false.
该[ -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
,zsh
在使用最新版本构建的某些版本时gcc
,支持会被破坏).
要反转测试,请使用"!".这相当于其他语言中的"非"逻辑运算符.试试这个:
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
可以写入(使用"和"运算符:&&)作为:
[ ! -f /tmp/foo.txt ] && echo "File not found!"
看起来像这样短:
[ -f /tmp/foo.txt ] || echo "File not found!"
该test
事可算过.它适用于我(基于Bash Shell:检查文件是否存在):
test -e FILENAME && echo "File exists" || echo "File doesn't exist"
这段代码也有效.
#!/bin/bash FILE=$1 if [ -f $FILE ]; then echo "File '$FILE' Exists" else echo "The File '$FILE' Does Not Exist" fi
最简单的方法
FILE=$1 [ ! -e "${FILE}" ] && echo "does not exist" || echo "exists"
此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