我想知道关于 if/then/else 的最佳实践是什么;我倾向于使用以下形式(因为我发现它更容易阅读)
#!/usr/bin/ksh
#
[[ -f /path/to/target/file ]] && {
echo "File exists"
} || {
echo "No such file"
}
而不是这种形式
#!/usr/bin/ksh
#
if [ -f /path/to/target/file ] ; then
echo "File exists"
else
echo "No such file"
fi
我还在复杂块true
之前添加了一条语句} || {
,以确保“else”部分不会被执行。
您有什么建议?
答案1
这种风格的问题在于这两种形式并不等同。当您使用:
if command; then
foo
else
bar
fi
那么要么将被调用,要么不会同时被调用foo
。bar
当同时使用&&
和 时||
,可以采用两条路径:
$ [[ -d / ]] && {
> echo "Path 1 taken"
> false
> } || {
> echo "Path 2 taken"
> }
Path 1 taken
Path 2 taken
$
使用表单时,调用的if cmd; then foo; else bar; fi
条件是返回false。使用表单时,调用的条件是返回false。bar
cmd
cmd && foo || bar
bar
cmd && foo
编辑:我刚刚注意到,在你的问题中,你承认你需要放在true
块的末尾才能使你的版本正常工作。如果您愿意这样做,我不知道任何其他重大问题 - 但我认为,如果有任何可能,则需要您无条件添加“true”作为块中的最后一个命令的样式之前的命令可能会失败,只是保证您最终会忘记它,并且事情看起来会正常工作,直到实际情况并非如此。
答案2
在我看来,对于用任何其他语言编写的人来说,if-then-else 更容易阅读。但我的建议是仅对仅包含和
之一的单行代码使用短符号(使用 && 或 ||)。 有些代码像 &&
||
[[ -d mustExist ]] || errorFunction "Dir mustExist is missing"
[[ -f toBeSend ]] && sendFile toBeSend
if [[ -d sometimes ]]; then
writeTrueBlock
else
writeFalseBlock
fi
编辑:新想法:这样写可能会更好
test -d mustExist || errorFunction "Dir mustExist is missing"
test -f toBeSend && sendFile toBeSend
if [[ -d sometimes ]]; then
writeTrueBlock
else
writeFalseBlock
fi
答案3
可读性和风格
我倾向于在脚本编写中大量使用&&
和运算符。||
我什至在一条语句中使用多个,但仅在检查是否继续在当前区块中。
示例1:
for word in $list; do
condition1 $word || continue
condition2 $word || continue
: do stuff with $word
: do more stuff with $word
done
条件1和条件2作为断言。我们得到了例外情况 让开,并继续执行这段代码应该执行的操作。
在这种情况下使用if
……就有点尴尬了then
。fi
替代符号:
示例2:
for word in $list; do
if condition1 $word && condition2 $word; then
: do stuff with $word
: do more stuff with $word
fi
done
在例子2我们有另一个级别的缩进,而没有发生任何额外的事情。
例3:
for word in $list; do
condition1 $word && condition2 $word || continue
: do stuff with $word
: do more stuff with $word
done
如果这两个条件可以简单地表达,我有时会像示例3一样将它们组合起来。
PS:我最初为 shell 程序员添加了一个练习:三个示例中只有两个是完全等效的。哪一个是奇怪的?
碰巧的是,我认为存在的差异并不存在。我实际上写了一个shpec
测试:
describe "continue"
it "discards last exit status"
(for i in 1; do
false || continue
done
)
assert equal 0 $?
end
end
shpec/continue_shpec.sh
continue
discards last exit status
1 examples, 0 failures