Bash:意外令牌'else'附近的语法错误

时间:2014-08-21 14:05:16

标签: bash

我有以下代码检查是否提供了两个输入参数中的任何一个,并且根据它们的存在运行某段代码。我在if语句中遇到了语法错误,因为我收到了一个意外的令牌“else”错误

if [ -z "${4}" ] || [ -z "${5}" ]
then
    echo "Missing index argument(s). Defaulting to entire file."
    cat ${devicesFile} | cut -d "," -f 4 | tr [:upper:] [:lower:] | awk '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' | while read deviceGuid
else
    i1=${4}
    i2=${5}
    head -n ${i1} ${devicesFile} | tail -n ${i2} | cut -d "," -f 4 | tr [:upper:] [:lower:] | awk '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' | while read deviceGuid
fi

这是我或病情的问题。?这是我唯一能想到的。任何帮助将不胜感激。

//这是我在尝试添加索引参数之前所拥有的内容,所以HVD对破坏的说法虽然有意义..

cat ${devicesFile}  | cut -d "," -f 4 | tr [:upper:] [:lower:] | awk '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' | while read deviceGuid
do
    # now=`date +"%Y%m%d %H%M%S"`
    currentTime=`date +"%H%M%S"`
    currentHour=`date +"%H"`
    currentDate=`date +"%Y%m%d"`
    # create parent directory
    mkdir -p ${crashlogFolder}/${currentDate}/${currentHour}/${crashCode}/
    # create crash log for device
    touch ${crashlogFolder}/${currentDate}/${currentHour}/${crashCode}/${currentTime}_${deviceGuid}.log
done

3 个答案:

答案 0 :(得分:5)

你不能混合这样的控制结构。如果你原来有

a | while b
do
  c
done

现在你希望a可以自定义,你不能

if d
then
  e | while b
else
  f | while b
fi
do
  c
done

贝壳不能那样工作。 (大多数其他语言也没有。)while b; do c; done是一个单一的陈述,不能像那样分解。

相反,您应该将其更改为

if d
then
  e
else
  f
fi | while b
do
  c
done

整个if d; then e; else f; fi是一个单独的语句,无论它来自哪个命令,它的输出都将被传送到while语句。

答案 1 :(得分:4)

您的while区块缺少正文,其格式应为while <condition>; do <actions>; done

if [[ -z "${4}" || -z "${5}" ]]; then
    # …
    cat ${devicesFile} \
    | … \
    | while read deviceGuid; do echo $deviceGuid; done
else
    # …
    head -n ${i1} ${devicesFile} \
    | … \
    | while read deviceGuid; do echo $deviceGuid; done
fi

  1. 使用bash test [[ … ]],因此你可以使用布尔OR作为[[ … || … ]],如果你需要可移植性则丢弃;
  2. 为了清楚起见,
  3. 替换了一些命令
  4. 转义换行符,行末尾为\(不得有空格),以获得更清晰的脚本
  5. 使用虚拟echo $deviceGuid命令添加了缺失块。

答案 2 :(得分:3)

这是对ÉdouardLopez的回答的真实评论:DRY - 取出所有常用代码:

if [[ -z "${4}" || -z "${5}" ]]; then
    cat ${devicesFile} 
else
    head -n ${i1} ${devicesFile} | tail -n ${i2}
fi |
  cut -d "," -f 4 | 
  tr [:upper:] [:lower:] | 
  awk -F, '{print substr($1,1,8)"-"substr($1,9,4)"-"substr($1,13,4)"-"substr($1,17,4)"-"substr($1,21,12)}' |
  while read deviceGuid; do 
    : 
  done

MrTunaDeluxe注意:${var}"$var"不同 - 您应该更喜欢后者。第一种形式是数组元素扩展,各种参数替换,以及消除周围文本的变量(例如echo "${var}text")所必需的,但只是使用大括号不会阻止单词拆分或文件名扩展。