【问题标题】:Cron stops the script if the file is not found如果找不到文件,cron 会停止脚本
【发布时间】:2022-08-16 03:30:16
【问题描述】:

我有以下简单的脚本:

#!/bin/sh

a() {
  echo 1
}

a

b() {
  for file in \"${DOWNLOADS}\"123_*; do
    mv \"${file}\" \"${DOWNLOADS}321\"
  done
}

b

c() {
  echo 2
}

c

它是可执行的,如果我从终端调用它,它工作得完全正确:甲,乙,丙.但是如果我尝试通过cron而且没有\"123_{某事}\" 文件中的\"${下载}\" 目录,则只有函数一个执行,并开始 for 循环。功能C不调用,因为脚本停止。

crontab -l

=>

10 20 * * * zsh /user/file

调试显示如下:

10 20 * * * zsh /user/file >> ~/tmp/cron.txt 2>&1

=>

+/user/file:47> a
+a:1> echo 1
1
+/user/file:67> b
file:12: no matches found: /Users/ivan/Downloads/123_*

可以看出,在找不到文件后脚本的执行立即停止。

我不明白为什么要通过这个脚本执行cron如果找不到文件,则停止,以及如何避免这种情况;谁能解释一下?

或者也许这只是我环境的限制?

  • 不确定这是否相关,但您有一个带有#!/bin/sh shebang 的脚本,但您使用zsh 调用它。也许您需要检查您的(cron)环境中哪些 zsh 选项处于活动状态?

标签: shell cron zsh


【解决方案1】:

我不明白如果找不到文件,为什么通过 cron 执行此脚本会停止,以及如何避免这种情况;谁能解释一下?

使用不匹配任何内容的 glob 是错误的:

% print nope*
zsh: no matches found: nope*

您可以通过设置 null_glob 选项来解决此问题:

% setopt null_glob
% print nope*
[no output, as nothing was found]

您可以通过在末尾添加 (N) 来为单个模式设置此设置:

% print nope*(N)

因此,在您的示例中,您最终会得到以下结果:

b() {
  for file in ${DOWNLOADS}123_*(N); do
    mv $file ${DOWNLOADS}321
  done
}

笔记:这只适用于zsh;在您的脚本中,顶部有#!/bin/sh,但您使用zsh 运行它。如果您打算使用 zsh,最好将其更改为 #!/usr/bin/env zsh

在标准 /bin/sh 中,它的行为有所不同:不匹配的模式被模式本身替换:

% sh
$ echo nope*
nope*

在这种情况下,您需要检查循环中的$file 是否与nope* 匹配,如果匹配则继续。但是您正在运行 zsh,因此它并不真正适用:请注意 /bin/sh 和 zsh 在默认设置下的行为完全不同(如果您想使用 setopt no_nomatch,您也可以在 zsh 中获得相同的行为)。

【讨论】:

    猜你喜欢
    • 2017-02-10
    • 2018-12-29
    • 2016-03-29
    • 2020-09-28
    • 2020-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多