如果目标文件不存在,如何退出shell脚本

ami*_*ine 24 linux bash shell exit

鉴于下面的脚本,如果文件不存在,我想避免执行管道.

如果找不到txt文件,我怎么能立即退出脚本?

ls */*.txt | grep ab1 | awk '{print $1, $1}' | sed "s/\"/\"\"/g" | xargs -L1 mv
Run Code Online (Sandbox Code Playgroud)

pax*_*blo 42

您可以使用以下内容检查文件是否存在:

if [[ -f x.txt ]] ; then
    echo file exists.
fi
Run Code Online (Sandbox Code Playgroud)

要退出,如果没有,这样的东西就足够了:

if [[ ! -f x.txt ]] ; then
    echo 'File "x.txt" is not there, aborting.'
    exit
fi
Run Code Online (Sandbox Code Playgroud)

-f <file>只是您可以使用的众多条件表达式中的一个.如果你查看下面的bashman-page CONDITIONAL EXPRESSIONS,你会看到它们中的一大部分.


如果(如问题更新中所述)您希望检查通配符是否导致文件,您可以简单地展开它,丢弃错误.如果没有,您将得到一个空字符串,可以通过以下方式检测到-z:

if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then
    echo 'There are no "*/*.txt" files.'
    exit
fi
Run Code Online (Sandbox Code Playgroud)

请注意,我习惯-1每行强制一个文件,即使Linux ls默认情况下输出设备不是终端(来自内存)也是如此.这是为了防止你在一台机器上尝试这种情况,在这种情况下不会强制每行一个.


但请记住,如果文件名中包含空格,则使用ls然后awk提取第1列将无法正常工作.例如,该文件abc ab1.txt将导致仅提取该abc位.

使用findwith -print0,with xargswith -0是正确处理可能包含"特殊"字符的文件的常用方法.您还可以使用许多其他选项find来确保仅处理所需的文件,例如-maxdepth限制目录树的走向,以及-name正确过滤文件名.

但是,如果你知道你永远不会有这些类型的文件,那么使用这个ls解决方案可能没问题,只要确保你对它的缺点感到满意.


bri*_*ice 11

使用 test

一种快速而简短的存在测试方法:

test -e $FILENAME || exit
Run Code Online (Sandbox Code Playgroud)

你可以通过这样做来链接它:

test -e $FILENAME && something | something-else 
Run Code Online (Sandbox Code Playgroud)

在这种情况下something,something-else只有在文件存在时才会执行.

例如:

? test -e ~/.bashrc && echo True || echo False
True
? test -e ./exists-not && echo True || echo False
False
Run Code Online (Sandbox Code Playgroud)

旁白:注意这[是别名test.语义[[由bash定义,可以在bash联机帮助页上找到

然而...

...你可能最好find用来获取你的文件:

find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \;
Run Code Online (Sandbox Code Playgroud)

由于输出ls无法可靠解析.do-something-to-filename如果文件名存在,这也只会执行命令,这是我认为你要做的.

{}将被每个调用的文件名替换do-something-to-filename.