if / else 命令中的语法错误

if / else 命令中的语法错误

这个命令有什么问题吗?似乎存在语法错误,但我不知道在哪里:

sh -c 'mongodump --host mongo_db --gzip --db db $$(if [ $TYPE = "hour" ]; then echo "--archive=/backup/hour/$$(date +"%H").gz"; elif [ $TYPE = "day" ]; then echo --archive=/backup/day/$$(date +"%d").gz; fi)'

我需要根据 TYPE 变量设置存档名称。

  • 如果类型是“小时”,输出应该是例如/backup/hour/10.gz
  • 如果类型是“day”,输出应该是例如/backup/day/1.gz
  • 如果类型是“月”,输出应该是例如/backup/2017-09.gz

答案1

sh -c 'echo mongodump --host mongo_db --gzip --db db --archive="$(
    case "$1" in 
        hour)  f="%H";; 
        day)   f="%d";; 
        month) f="%Y-%m";; 
        *)     f="unknown"; set -- "";; 
    esac
    date "+/backup/$1/$f.gz"
)"' x "$TYPE"
  • 干燥
  • case比 long 更具可读性if/elif/elif...
  • x "$TYPE"是一种将“外部”变量传递到 sh 主体中而无需玩引用游戏的方法。 sh 主体中的“x”变为 $0,$TYPE 变为 $1。
  • 内部允许换行$(...)
  • 您可以在格式字符串%中放置非指令date

答案2

您有未加引号的变量 ( $TIME) 和语法错误 ( $$(...))。此外,如果TYPE是 shell 变量(而不是环境变量),则其值在单引号脚本中根本不可见sh -c

该声明应该类似于

sh -c "mongodump --host mongo_db --gzip --db db \"$(if [ \"$TYPE\" = \"hour\" ]; then echo \"--archive=/backup/hour/$(date +%H).gz\"; elif [ \"$TYPE\" = \"day\" ]; then echo --archive=/backup/day/$(date +%d).gz; fi)\""

(或者其他的东西...)

正确引用是有问题的,因为您希望 shell$TYPE在最里面的子 shell 中展开,并且仍然用双引号引起来。

如果你不需要sh -c(我可以看到没有什么需要它),它会变得更容易一些:

mongodump --host mongo_db --gzip --db db "$(if [ "$TYPE" = "hour" ]; then echo "--archive=/backup/hour/$(date +%H).gz"; elif [ "$TYPE" = "day" ]; then echo "--archive=/backup/day/$(date +%d).gz"; fi)"

但是,由于这会给出一个空的命令替换 if $TYPEis isn't dayNor hour,所以我建议您这样做:

case "$TYPE" in
    hour) archive="/backup/hour/$(date +%H).gz" ;;
    day)  archive="/backup/day/$(date +%d).gz"  ;;
    *)
       printf 'Error: Unknown TYPE "%s"\n' "$TYPE" >&2
       exit 1 ;;
esac

sh -c "mongodump --host mongo_db --gzip --db db --archive=$archive"

# or just

mongodump --host mongo_db --gzip --db db --archive="$archive"

这使得它更容易阅读、理解和维护。

答案3

如果TYPE未设置、为空或完全由空格组成,则您的语句归结为if [ = "hour" ]语法错误。

由于您使用的是sh,因此常见的解决方法是使用前缀:if [ "x$TYPE" = "xhour" ]

您不能简单地使用弱引号,因为 a""也会解析为if [ = "hour" ];至少与sh. bash当使用更强大的双括号语法(例如if [[ "$TYPE" = "hour" ]])时,将做正确的事情,而无需求助于前缀或后缀。

相关内容