问题描述
我想将在詹金斯工作中创建的所有JSON文件移动到另一个文件夹。
该作业可能不会创建任何json文件。 在这种情况下,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 -e
或trap
,并且您知道,则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 -e
或trap
捕获到错误,否则除非脚本导致失败,否则除非这是最后一个命令。)
更好的做法是专门处理您期望的问题,而不禁用其他问题的错误处理。
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