Linux 如果目标文件不存在,如何退出 shell 脚本
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16826657/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to exit a shell script if targeted file doesn't exist
提问by amine
Given the script below, I would like to avoid the execution of the pipeline if a file does not exist.
鉴于下面的脚本,如果文件不存在,我想避免执行管道。
How may I exit the script straight away if the txt file is not found?
如果找不到 txt 文件,如何立即退出脚本?
ls */*.txt | grep ab1 | awk '{print , }' | sed "s/\"/\"\"/g" | xargs -L1 mv
采纳答案by paxdiablo
You can check for file existence with something like:
您可以使用以下内容检查文件是否存在:
if [[ -f x.txt ]] ; then
echo file exists.
fi
To exit if it doesn't,something like this would suffice:
如果没有退出,这样的事情就足够了:
if [[ ! -f x.txt ]] ; then
echo 'File "x.txt" is not there, aborting.'
exit
fi
The -f <file>
is only oneof the many conditional expressions you can use. If you look at the bash
man-page under CONDITIONAL EXPRESSIONS
, you'll see a whole host of them.
这-f <file>
只是您可以使用的众多条件表达式之一。如果您查看 下的bash
手册页CONDITIONAL EXPRESSIONS
,您会看到一大堆。
If (as stated in a question update) you wish to check if a wildcard results in files, you can simply expand it, throwing away the errors. If there are none, you'll end up with an empty string which can be detected with -z
:
如果(如问题更新中所述)您希望检查通配符是否导致文件,您可以简单地扩展它,丢弃错误。如果没有,您最终会得到一个空字符串,可以使用以下命令检测到-z
:
if [[ -z "$(ls -1 */*.txt 2>/dev/null | grep ab1)" ]] ; then
echo 'There are no "*/*.txt" files.'
exit
fi
Note that I've used -1
to force one file per line even though Linux ls
does that by default if the output device is not a terminal (from memory). That's just in case you try this on a machine that doesn'tforce one per line in that case.
请注意,如果输出设备不是终端(来自内存),-1
即使 Linuxls
默认情况下也会强制每行一个文件。以防万一您在不强制每行一个的机器上尝试这种情况。
Keep in mind however that, if you have spaces in your filenames, using ls
and then awk
to extract column 1 is not going to work too well. For example, the file abc ab1.txt
will result in the extraction of only the abc
bit.
但是请记住,如果您的文件名中有空格,则使用ls
然后awk
提取第 1 列的效果不会太好。例如,文件abc ab1.txt
将导致仅提取abc
位。
Using find
with -print0
, combined with xargs
with -0
is the usual way to properly process files which may have "special" characters in them. There are many other options you can give to find
to ensure only the files required are processed, such as -maxdepth
to limit how far down the directory tree you go, and -name
to properly filter file names.
使用find
with -print0
, with xargs
with-0
是正确处理可能包含“特殊”字符的文件的常用方法。您还可以提供许多其他选项find
以确保只处理所需的文件,例如-maxdepth
限制您在目录树下的位置,以及-name
正确过滤文件名。
However, if you knowthat you will never have these types of files, it's probably okay to use the ls
solution, just make sure you're comfortable with its shortcomings.
但是,如果您知道您永远不会拥有这些类型的文件,那么使用该ls
解决方案可能没问题,只需确保您对它的缺点感到满意。
回答by brice
Use test
用 test
A quick and short way of testing for existence:
一种快速而简短的存在性测试方法:
test -e $FILENAME || exit
You can chain it by doing:
您可以通过执行以下操作来链接它:
test -e $FILENAME && something | something-else
In which case something
and something-else
will only execute if the file exists.
在这种情况下something
,something-else
只有在文件存在时才会执行。
For example:
例如:
? test -e ~/.bashrc && echo True || echo False
True
? test -e ./exists-not && echo True || echo False
False
Aside:Note that [
is an alias for test
. The semantics of [[
are defined by bash and can be found on the bash manpage
旁白:请注意,这[
是test
. 的语义[[
由 bash 定义,可以在 bash 联机帮助页上找到
However...
然而...
...you are probably better off using find
to get your files:
...您可能最好使用find
来获取您的文件:
find ./ -maxdepth 2 -name "*ab1*.txt" -exec do-something-to-filename '{}' \;
As the output of ls
can not be reliably parsed. This will also only execute the command do-something-to-filename
if the filename exist, which is what I think you are trying to do.
由于ls
无法可靠解析的输出。do-something-to-filename
如果文件名存在,这也只会执行命令,这就是我认为您正在尝试执行的操作。
{}
will be replaced by the filename for each invocation of do-something-to-filename
.
{}
将被每次调用的文件名替换do-something-to-filename
。
回答by Kevin
find ... -exec ...
or find ... -print0 | xargs -0 ...
is generally fine, but you can do it directly with a glob using bash's nullglob
option:
find ... -exec ...
或者find ... -print0 | xargs -0 ...
一般都可以,但是您可以使用 bash 的nullglob
选项直接使用 glob 来完成:
bash-3.2$ echo *foo
*foo
bash-3.2$ shopt -s nullglob
bash-3.2$ echo *foo
bash-3.2$
Depending on the rest of your script, you may or may not want to re-unset that with shopt -u nullglob
.
根据脚本的其余部分,您可能想也可能不想用shopt -u nullglob
.
回答by Kishan B
I tried this and this worked for me
我试过这个,这对我有用
test -s <<your file path>> && exit 0 || <<things to do when file NOT exists>>
Note that i am actually exiting when the file is not present
请注意,当文件不存在时,我实际上正在退出