如果没有文件与全局匹配,请阻止“ mv”命令引发错误例如“ mv * .json / dir /

问题描述

我想将在詹金斯工作中创建的所有JSON文件移动到另一个文件夹。

该作业可能不会创建任何json文件在这种情况下,mv命令会引发错误,从而导致作业失败。

如果找不到文件,如何防止mv命令引发错误

解决方法

这是预期的行为-这是为什么在没有匹配项时,外壳会*.json展开而未展开,从而允许mv显示有用的错误。

但是,如果您不希望这样做,则始终可以自己检查文件列表,然后再将其传递给mv。作为一种适用于所有POSIX兼容shell的方法,不仅限于bash:

#!/bin/sh

# using a function here gives us our own private argument list.
# that's useful because minimal POSIX sh doesn't provide arrays.
move_if_any() {
  dest=$1; shift  # shift makes the old $2 be $1,the old $3 be $2,etc.
  # so,we then check how many arguments were left after the shift;
  # if it's only one,we need to also check whether it refers to a filesystem
  # object that actually exists.
  if [ "$#" -gt 1 ] || [ -e "$1" ] || [ -L "$1" ]; then
    mv -- "$@" "$dest"
  fi
}

# put destination_directory/ in $1 where it'll be shifted off
# $2 will be either nonexistent (if we were really running in bash with nullglob set)
# ...or the name of a legitimate file or symlink,or the string '*.json'
move_if_any destination_directory/ *.json

...或者,作为一种更加针对bash的方法:

#!/bin/bash

files=( *.json )
if (( ${#files[@]} > 1 )) || [[ -e ${files[0]} || -L ${files[0]} ]]; then
  mv -- "${files[@]}" destination/
fi
,

欢迎来到。

为什么不想要该错误?

如果您只是不想看到该错误,则可以随时将其2>/dev/null丢弃,但是请不要这样做。并非每个错误都是您所期望的,这是一个调试噩梦。您可以使用2>$logpath将其写入日志,然后构建逻辑以读取该内容以确保一切正常,然后忽略或相应地进行响应-

mv *.json /dir/ 2>$someLog
executeMyLogParsingFunction # verify expected err is the ONLY err

如果是因为您拥有set -etrap,并且您知道,则mv失败是可以的(这可能不是因为没有文件!),则可以使用此技巧-

mv *.json /dir/ || echo "(Error ok if no files found)"

mv *.json /dir/ ||: # : is a no-op synonym for "true" that returns 0

请参阅https://www.gnu.org/software/bash/manual/html_node/Conditional-Constructs.html

(如果仅因为mv作为最后一条命令返回非零而失败,您也可以添加一个显式的exit 0,但也不要这样做-解决实际问题而不是解决任何其他解决方案都应解决此问题,但我想指出的是,除非有set -etrap捕获到错误,否则除非脚本导致失败,否则除非这是最后一个命令。)

更好的做法是专门处理您期望的问题,而不禁用其他问题的错误处理。

shopt -s nullglob # globs with no match do not eval to the glob as a string
for f in *.json; do mv "$f" /dir/; done # no match means no loop entry

c.f。 https://www.gnu.org/software/bash/manual/html_node/The-Shopt-Builtin.html
或者如果您不想使用shopt

for f in *.json; do [[ -e "$f" ]] && mv "$f" /dir/; done

请注意,我仅测试存在性,因此它将包括所有匹配项,包括目录,符号链接,命名管道...您可能希望使用[[ -f "$f" ]] && mv "$f" /dir/

c.f。 https://www.gnu.org/software/bash/manual/html_node/Bash-Conditional-Expressions.html