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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-18 09:34:06  来源:igfitidea点击:

If-else-statement is working wrong in crontab?

bashshellif-statementcrontab

提问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 mvattemps 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/ficonstructs 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 mvfails, croncaptures what is written to standard error and mails it to the owner, then runs the mailcommand. You can suppress the error message from mvto 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/chkfilesto 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:

重要笔记:

  1. Before running the script, you need to change the dir_where_files_are_or_not, dir_where_files_should_goand save_dirvars to your needs.
  2. Do NOTinclude trailing slashes in the dirs, otherwise the rsync and mv might not do what you really want
  1. 在运行脚本之前,您需要根据需要更改dir_where_files_are_or_not,dir_where_files_should_gosave_dirvars 。
  2. 不要包括在迪尔斯尾随斜杠,否则的rsync和mv可能不是你真正想要的

Regards

问候