I have the following code that checks whether either of two input args are supplied, and depending on their existance runs a certain piece of code. I'm running into syntax errors in my if statements however, because I'm getting an unexpected token `else' error
我有以下代码检查是否提供了两个输入args,并根据它们的存在运行特定的代码段。我在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
Is it an issue with my or condition.? That's the only thing I can really think of. Any help would be greatly appreciated.
这与我的条件有关吗?这是我唯一能想到的。如有任何帮助,我们将不胜感激。
//Here's what I had before I tried to add the index parameters, so what HVD said about the broken while makes sense..
//这是我在添加索引参数之前所得到的,所以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 个解决方案
#1
4
You're lacking a body to your while
block, it should have the form while <condition>; do <actions>; done
你缺少一个身体到你的while块,它应该有形式,而 <条件> ; <行动> ;完成
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
Explaination
- used bash test
[[ … ]]
so you can use the boolean OR inside as[[ … || … ]]
, discard if you need portability; - 使用bash测试[[…]],因此您可以使用布尔值或内部的布尔值[[…],如果您需要可移植性,则丢弃;
- replaced some of your command by
…
just for clarity - 为了清晰起见,用…代替你的一些命令
- escaped newline,
\
at the end of line (no spaces must follow), to get a clearer script - 避免换行,在行尾(没有空格必须跟随),以获得更清晰的脚本。
- added missing block with dummy
echo $deviceGuid
command. - 添加了缺少的块与虚拟echo $deviceGuid命令。
#2
5
You cannot mix control structures like that. If you originally had
你不能像那样混合控制结构。如果你最初
a | while b
do
c
done
and now you want a
to be customisable, you cannot do
现在你想要一个可定制的,你不能做。
if d
then
e | while b
else
f | while b
fi
do
c
done
Shells just don't work like that. (Nor do most other languages.) while b; do c; done
was a single statement, and cannot be broken up like that.
壳层不像这样工作。(大多数其他语言也是如此);c;done只是一个语句,不能这样分解。
Instead, you should change it to
相反,您应该将它改为
if d
then
e
else
f
fi | while b
do
c
done
The whole if d; then e; else f; fi
is a single statement, and its output, regardless of which of the commands it comes from, will be piped to the while
statement.
如果d;然后e;其他f;fi是一个单独的语句,它的输出,不管它来自哪个命令,都将被引导到while语句。
#3
3
This is really a comment on Édouard Lopez's answer: DRY -- pull out all the common code:
这实际上是对爱德华·洛佩兹的回答的评论:干——拿出所有的通用代码:
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
Note to MrTunaDeluxe: ${var}
is different from "$var"
-- you should prefer the latter. The first form is required for array element expansion, the various parameter substitutions, and also to disambiguate the variable from surrounding text (e.g. echo "${var}text"
), but just using braces will not prevent word splitting or filename expansions.
MrTunaDeluxe注意:${var}与“$var”不同——您应该更喜欢后者。第一个表单用于数组元素展开、各种参数替换,以及从周围的文本(例如echo“${var}text”)中消除变量的歧义,但是仅仅使用大括号并不会阻止单词拆分或文件名扩展。
#1
4
You're lacking a body to your while
block, it should have the form while <condition>; do <actions>; done
你缺少一个身体到你的while块,它应该有形式,而 <条件> ; <行动> ;完成
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
Explaination
- used bash test
[[ … ]]
so you can use the boolean OR inside as[[ … || … ]]
, discard if you need portability; - 使用bash测试[[…]],因此您可以使用布尔值或内部的布尔值[[…],如果您需要可移植性,则丢弃;
- replaced some of your command by
…
just for clarity - 为了清晰起见,用…代替你的一些命令
- escaped newline,
\
at the end of line (no spaces must follow), to get a clearer script - 避免换行,在行尾(没有空格必须跟随),以获得更清晰的脚本。
- added missing block with dummy
echo $deviceGuid
command. - 添加了缺少的块与虚拟echo $deviceGuid命令。
#2
5
You cannot mix control structures like that. If you originally had
你不能像那样混合控制结构。如果你最初
a | while b
do
c
done
and now you want a
to be customisable, you cannot do
现在你想要一个可定制的,你不能做。
if d
then
e | while b
else
f | while b
fi
do
c
done
Shells just don't work like that. (Nor do most other languages.) while b; do c; done
was a single statement, and cannot be broken up like that.
壳层不像这样工作。(大多数其他语言也是如此);c;done只是一个语句,不能这样分解。
Instead, you should change it to
相反,您应该将它改为
if d
then
e
else
f
fi | while b
do
c
done
The whole if d; then e; else f; fi
is a single statement, and its output, regardless of which of the commands it comes from, will be piped to the while
statement.
如果d;然后e;其他f;fi是一个单独的语句,它的输出,不管它来自哪个命令,都将被引导到while语句。
#3
3
This is really a comment on Édouard Lopez's answer: DRY -- pull out all the common code:
这实际上是对爱德华·洛佩兹的回答的评论:干——拿出所有的通用代码:
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
Note to MrTunaDeluxe: ${var}
is different from "$var"
-- you should prefer the latter. The first form is required for array element expansion, the various parameter substitutions, and also to disambiguate the variable from surrounding text (e.g. echo "${var}text"
), but just using braces will not prevent word splitting or filename expansions.
MrTunaDeluxe注意:${var}与“$var”不同——您应该更喜欢后者。第一个表单用于数组元素展开、各种参数替换,以及从周围的文本(例如echo“${var}text”)中消除变量的歧义,但是仅仅使用大括号并不会阻止单词拆分或文件名扩展。