bash if-else-statement 在 crontab 中运行出错?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/21779144/
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
If-else-statement is working wrong in crontab?
提问by user3310114
When i use this:
当我使用这个时:
*/5 6-18 * * 1-6 [ "$(ls -A /DIR_WHERE_FILES_ARE_OR_NOT/)" ] &&
rsync -au /DIR_WHERE_FILES_ARE_OR_NOT/ /DIR_WHERE_FILES_SHOLD_GO; \
mv /DIR_WHERE_FILES_ARE_OR_NOT/* /SAVE_DIR/ ||
mail -s "DIR IS EMPTY" [email protected] <<< "message"
i get two mails:
我收到两封邮件:
mv: cannot stat `/DIR_WHERE_FILES_ARE_OR_NOT/*': No such file or directory
mv:无法统计`/DIR_WHERE_FILES_ARE_OR_NOT/*':没有那个文件或目录
and
和
"DIR IS EMPTY"
“目录为空”
Why?
为什么?
回答by Jens
You get
你得到
mv: cannot stat `/DIR_WHERE_FILES_ARE_OR_NOT/*': No such file or directory
for exactly the reason stated: that directory is empty, hence it does not contain a file named *
(asterisk). It's just the way glob expansion works in the shell: if the glob doesn't match anything it is passed literally to the command. Since mv
attemps to rename a non-existing file, it complains as shown.
正是出于说明的原因:该目录是空的,因此它不包含名为*
(星号)的文件。这只是 glob 扩展在 shell 中的工作方式:如果 glob 不匹配任何东西,它就会按字面传递给命令。由于mv
尝试重命名一个不存在的文件,它会如图所示抱怨。
This would all be much more readable, if instead of a sequence of &&
and ||
operators in a crontab you would place the whole logic in a script with equivalent if/else/fi
constructs and just call the script from cron.
如果不是crontab中的一系列&&
and||
运算符,而是将整个逻辑放在具有等效if/else/fi
结构的脚本中,并且只需从 cron 调用脚本,那么这一切都将更具可读性。
You get two mails because you explicitly send the first with mail -s
. The second is from cron because the output on stderr and stdout is not empty.
您会收到两封邮件,因为您明确发送了第一封邮件mail -s
。第二个来自 cron,因为 stderr 和 stdout 上的输出不为空。
Your commands are equivalent to
你的命令相当于
if [ "$(ls ...)" ]; then
rsync
fi
if ! mv; then
mail
fi
Note that there is no else
.
请注意,没有else
.
回答by chepner
You get two mails because when mv
fails, cron
captures what is written to standard error and mails it to the owner, then runs the mail
command. You can suppress the error message from mv
to avoid the mail from cron
.
您会收到两封邮件,因为当mv
失败时,cron
捕获写入标准错误的内容并将其邮寄给所有者,然后运行该mail
命令。您可以抑制来自 的错误消息mv
以避免来自 的邮件cron
。
mv /DIR_WHERE_FILES_ARE_OR_NOT/* /SAVE_DIR/ 2> /dev/null || mail -s "DIR IS EMPTY" [email protected] <<< "message"
回答by Pedro Sousa
Just like user Jens already mentioned, and also from my experience, unless you are using a very simple and usually single command, you should stick to script files. So, in your case, I would go with a script file. I'll give you an example.
就像用户 Jens 已经提到的一样,也是根据我的经验,除非您使用非常简单且通常是单一的命令,否则您应该坚持使用脚本文件。因此,在您的情况下,我会使用脚本文件。我给你举个例子。
#!/bin/bash
dir_where_files_are_or_not=/filespath
dir_where_files_should_go=/another/filespath
save_dir=/savefiles/path
# ok, lets start by checking if dir contains files
if [ "$(ls -A $dir_where_files_are_or_not)" ]; then
# dir contains files, so lets rsync and mv them
rsync -au $dir_where_files_are_or_not/ $dir_where_files_should_go
mv $dir_where_files_are_or_not/* $save_dir
else
# dir is empty, lets send email
mail -s "DIR IS EMPTY" [email protected] <<< "message"
fi
Now, I just put this code in a file. Give it a name, for example "chkfiles" and save it in a directory (I use /usr/local/sbin for all of my scripts).
现在,我只是将这段代码放在一个文件中。给它一个名字,例如“chkfiles”并将它保存在一个目录中(我使用 /usr/local/sbin 作为我的所有脚本)。
Next, in a shell, run the command chmod +x /usr/local/sbin/chkfiles
to make the file executable. Then add the script to your crontab.
接下来,在 shell 中,运行命令chmod +x /usr/local/sbin/chkfiles
以使文件可执行。然后将脚本添加到您的 crontab。
I would suggest the following line inside crontab:
我建议在 crontab 中添加以下行:
*/5 6-18 * * 1-6 /bin/bash /usr/local/sbin/chkfiles
I used /bin/bash to call the right interpreter for this script. It should now work as expected.
我使用 /bin/bash 为这个脚本调用正确的解释器。它现在应该按预期工作。
Important Notes:
重要笔记:
- Before running the script, you need to change the
dir_where_files_are_or_not
,dir_where_files_should_go
andsave_dir
vars to your needs. - Do NOTinclude trailing slashes in the dirs, otherwise the rsync and mv might not do what you really want
- 在运行脚本之前,您需要根据需要更改
dir_where_files_are_or_not
,dir_where_files_should_go
和save_dir
vars 。 - 请不要包括在迪尔斯尾随斜杠,否则的rsync和mv可能不是你真正想要的
Regards
问候