【问题标题】:Exit shell script if file doesn't exist如果文件不存在则退出 shell 脚本
【发布时间】:2021-11-15 20:08:32
【问题描述】:

我有一个 .sql 作业,它根据某些条件创建文件,它使用前缀 TEMP_ 写入这些文件,因为我们有一个适配器来拾取文件,我们不希望在写入完成之前拾取它们。 我需要放置一个重命名这些文件的发布作业,我已经设置了许多其他作业,但它们每次运行时都会创建文件。该作业仅创建有时运行的文件,具体取决于系统中的数据。 我需要检查文件是否存在,如果不存在则退出。

我找到了一些示例,但它们似乎都失败了,这就是我想检查是否没有文件的地方,如果没有文件则退出,但它失败并显示: “第 16 行的语法错误:`TEMP_SUBCON*.csv' 意外”

这是我目前所拥有的,第 16 行是第一行 - 上面只是 cmets:

    if [[ ! -f $OUT_DIR -name TEMP_SUBCON*.csv ]] ; then
    exit $?
    fi
    
    TEMP_DATA_FILE=$(find $OUT_DIR -name TEMP_SUBCON_QTY_output*.csv)
    DATA_FILE=$(basename $TEMP_DATA_FILE | cut -c6-)
    
    echo $TEMP_DATA_FILE
    echo $DATA_FILE

## Rename the file name, remove the phrase TEMP_, so that EAI can pick the file ##
mv $TEMP_DATA_FILE $OUT_DIR/$DATA_FILE

你能帮忙指导一下我做错了什么吗?

谢谢

【问题讨论】:

  • -f $OUT_DIR -name TEMP_SUBCON*.csv 看起来像是从 find 的调用中提取的,这不是 [[...]] 的有效语法。

标签: shell file ksh


【解决方案1】:

如果我理解正确,您想在 $OUT_DIR 中找到带有 TEMP_ 前缀的文件,然后如果有的话,将它们重命名为不带前缀的文件。那么这应该可以解决问题

for file in $OUT_DIR/TEMP_SUBCON_*.txt; do
    if [[ -e $file ]]; then
        mv $file $OUT_DIR/${file#*SUBCON_}
    fi
done
exit

它将通过目录找到每个 TEMP_ 文件并在没有它的情况下重命名它们。如果没有,它不会做任何事情。

【讨论】:

  • 谢谢@Andre Gelinas 已经尝试过了(好吧,一个稍微修改过的版本,因为它应该只重命名以 TEMP_SUBCON 开头的文件但是我收到错误:mv: cannot stat `/opt/scripts/data/out/TEMP_SUBCON *.csv': 没有这样的文件或目录有什么想法吗?
  • 好评。我已经编辑了答案。
  • 没有错误,它没有重命名任何东西,然后我意识到输出实际上是 .txt 所以我在上面的示例中将 .csv 更改为 .txt 但现在文件正在消失。如果我删除发布作业,我可以看到文件已创建,但随着作业它们以某种方式被移动或删除。我确实尝试修改您的代码以使 mv $file $OUT_DIR/${file#*_} 以防它们被写入另一个目录但没有运气,同样的结果文件只是消失了
  • 你能举一个文件名的真实例子吗?
  • 当然,文件名是 TEMP_SUBCON_DATE_output20210922.txt 和 TEMP_SUBCON_QTY_output20210922.txt
【解决方案2】:

该语法对[[ ... ]] 测试无效。

为什么不使用后续find命令的结果来检查指定目录下是否有匹配的文件,如果没有返回文件则退出(即结果变量为空则退出)?

例子:

TEMP_DATA_FILE=$(find $OUT_DIR -name "TEMP_SUBCON_QTY_output*.csv" )
if [[ -z ${TEMP_DATA_FILE:=""} ]]  ; then
   exit 1
fi

注意 1:您应该引用 find 命令的模式参数,如图所示。

注意 2:在您的 ksh 脚本中使用 set -u 如果变量在使用时未初始化(通常是错误的原因)会导致 ksh 中止,而不是使用默认值,这很有用。但是,如果你使用 use set -u 那么在任何测试中你都应该明确地给出你自己的默认值。这就是使用 ${TEMP_DATA_FILE:=""} 而不是 ${TEMP_DATA_FILE} 的原因 - 以支持通常非常有用的 set -u 选项。即使你不使用set -u,测试内部的 ${TEMP_DATA_FILE:=""} 也会明确应该发生什么,而不是依赖隐式行为。

注意 3:在调试和研究输出的每一行时,您应该使用set -x,它会准确地向您显示哪些命令与哪些参数一起运行以及结果是什么。这有助于您学习如何在 ksh 和类似的 shell 中编码。

【讨论】:

  • 谢谢@mao - 我已经尝试了各种来自在线指南的推导,这只是我最新的,所以它无效并不奇怪。感谢您的示例,当我尝试这样做时,虽然它仍然出错,但这一次它没有给我任何类型的错误消息,它只是在日志中显示 FAILED。完整代码现在是:TEMP_DATA_FILE=$(find $OUT_DIR -name TEMP_SUBCON_QTY_output*.csv) if [[ -z ${TEMP_DATA_FILE:=""} ]] ; then exit 1 fi DATA_FILE=$(basename $TEMP_DATA_FILE | cut -c6-) echo $TEMP_DATA_FILE echo $DATA_FILE mv $TEMP_DATA_FILE $OUT_DIR/$DATA_FILE exit $?
  • ${TEMP_DATA_FILE:=""} 在这里有点奇怪。如果脚本要退出,那么分配是没有意义的,所以你最好写"${TEMP_DATA_FILE}"
  • 谢谢@WilliamPursell,已经尝试过您的建议,但也失败了。尝试的代码是:TEMP_DATA_FILE=$(find $OUT_DIR -name TEMP_SUBCON_QTY_output*.csv) if [[ -z "${TEMP_DATA_FILE}" ]] ; then exit 1 fi DATA_FILE=$(basename $TEMP_DATA_FILE | cut -c6-) echo $TEMP_DATA_FILE echo $DATA_FILE ## Rename the file name, remove the phrase TEMP_, so that EAI can pick the file ## mv $TEMP_DATA_FILE $OUT_DIR/$DATA_FILE 日志信息不再显示错误,但确实显示失败状态,而我希望/需要它成功
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-06-23
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-02-28
相关资源
最近更新 更多