根据我的理解,你可以在bash中执行C-style for和while循环。
LIMIT=10
for ((a=1; a <= LIMIT ; a++)) # Double parentheses, and "LIMIT" with no "$".
do
echo -n "$a "
done # A construct borrowed from 'ksh93'.
甚至是三元运营商。
(( var0 = var1<98?9:21 ))
您如何使用if
声明执行此操作?
另外为什么他们不像C一样实施大括号呢?使用done
,do
,if
和fi
等所有关键字的逻辑是什么?我将编写一些脚本,但bash看起来非常不同。
是否有任何bash样式技术或bash替代品/插件?我想遵循标准,但来自C,Java和PHP背景bash看起来很奇怪。可维护性和标准很重要。
答案 0 :(得分:12)
bash(和sh
家族的其他shell)有一些与if有关的语法特性:
基本if语句的语法为if condition-command ; then list ; fi
(可以为其他分支添加elif
和else
。)
condition-command
可以是bash支持的任何命令(我认为,即使是另一个命令),然后执行返回值。 (实际上,它也可以是一个命令列表,但这可能会使读者感到困惑。最后一个命令的返回值会计入条件。)false
,其他一切都是true
。)list
(if
的返回值是列表的结果)。如果它不是-0(假),则不执行列表(但elif
或else
分支(如果有)。 (如果没有执行任何列表,则if的返回值为0.)一些有用的命令作为条件(这些也可以作为while loops
中的条件):
[ ... ]
实际上是写test ...
的另一种方式 - 这只是一个可能返回0(真)或1(假)的命令,具体取决于你给出的参数。 (这是shell的构建。)[[ ... ]]
是条件表达式命令。它支持[
支持的一些相同的参数,还有一些,如括号,<
,>
和(
... )
条件嵌套,并处理有点不同的扩展,因为它是一个特殊的语法结构而不是buildin命令。整个事情是一个返回0(真)或1(假)的命令。 (( ... ))
是一个算术表达式(或其中几个)作为命令的包装器。当(last)表达式的结果为非0时,结果为0(true);当(last)表达式的结果为0时,结果为1(false)。(您可以改为写let ...
。)
在算术表达式中,shell变量可以在没有$
的情况下使用,并且所有内容都被解释为整数(具有固定宽度,但我没有找到哪个)。您可以使用这些运算符:
++
,--
,+
,-
,!
,~
(如C中所示)**
(指数),*
,/
,%
,+
,-
<<
,>>
<=
,>=
,<
,>
,==
,!=
(我认为这些返回1(真)或0(假))&
,^
,|
&&
,||
,当然还有三元运营商:... ? ... : ...
=
,*=
,/=
,%=
,+=
,-=
,<<=
,{{1 }},>>=
,&=
,^=
|=
(只是连接两个表达式,返回最后一个的值)我认为一般来说这很像C整数表达式。 (这些大致按优先顺序排列,但有时每组内都有分歧。请查看,
了解详细信息。)
info '(bash)Shell Arithmetic'
是一个不做任何事情并且总是返回0的构建。true
是一个不做任何事情并且总是返回1的构建。解释
false
是一个命令列表,在子shell中执行。此子shell中的变量赋值不会传播回来。( ... )
是一个命令列表,它不会创建子shell。 { ...; }
是列表中命令的简单分隔符,但也可以换成换行符。;
是仅在第一个返回0时执行第二个命令的命令的分隔符。&&
是仅在第一个返回not-0时执行第二个命令的命令的分隔符。||
是命令的分隔符,并行执行这两个命令(后台的第一个命令)。所以,你可以用{括号和圆括号'来编写&
- 命令,但仍然需要if
和then
:
fi
这里的括号简直是多余的,因为if (( i > 0 ))
then {
echo "i > 0"
}
else {
echo "i <= 0"
}
fi
,then
和else
之间的命令无论如何都是(每个)一个列表。 (另请注意在此处关闭括号之前和之前需要换行或fi
。)
但正如其他人所说,如果你想使用类似C的语法,更好地使用另一种语言。
答案 1 :(得分:1)
在bash中,if语句没有像()
这样的括号,例如bash中的某些语法
if [[ ... ]];then
..
fi
if [ ... ];then
...
fi
if $(grep .. file) ;then #note the () is part of $().
...
fi
我没有反对Bash,但IMO,你最好使用一种编程语言,它可以为你提供编写脚本/编程工作所需的所有东西,比如Python,Ruby或Perl。 Bash有一些局限性,比如执行浮点数学等。另外,如果你的任务很复杂,过度使用* nix工具可能会导致脚本“膨胀”,从而影响性能。如果你想要“干净”的语法和可维护性,Ruby / Python可能适合你。 IMO,有或没有括号只是语言设计考虑因素,如果我有选择,我个人不会想要括号。
答案 2 :(得分:1)
当前语法的原因主要是历史性的。你问的大多数都是基于最初的Bourne shell(sh)。 Bourne选择将语法基于Algol而不是C。
要拥有更像C的语法(和not be csh),有人必须从头开始。
正如其他人所说,出于多种目的,您可以用其他语言编写脚本。
您可能希望查看可用于将C源作为shell脚本运行的Tiny C Compiler。
#!/usr/bin/tcc -run
#include <stdio.h>
int main()
{
printf("Hello World\n");
return 0;
}
答案 3 :(得分:1)
&&
和||
command lists和弯括号 group commands 在下面的示例中,true
,false
或test 0 -eq 0
可以用 any 命令替换,包括(( i > 0 ))
等算术表达式>
true && {
echo "true command returns zero (aka success)"
# more commands here
# and here
} || {
echo "true command never returns non-zero"
# more commands here
# and here
}
# I don't like this one so much
false && echo "false never returns zero" || echo "false returns always 1"
# here the draw-back are back slashes
test 0 -eq 0 \
&& echo "Surprise, zero is equal to zero" \
|| echo "Apocalypse is near if zero is not zero"
注意:我可以断言上述技术可以奏效,但是我不知道它们是否存在性能缺陷。
答案 4 :(得分:0)
如果由于某些原因你没有特别依赖bash,我会鼓励你使用更现代的结构化脚本语言,如Ruby,Python或PHP,并简单地使用适当的脚本头来使它们像一个bash脚本。我个人非常喜欢控制台上的bash one-liners,但是当它用作脚本语言时发现它完全是钝的。
大多数现代脚本语言都可以让您轻松访问类似ARGV
的数组,以获取命令行参数,并支持熟悉的循环和控制结构。
因此,例如,您编写了一个Ruby脚本,并以#!/usr/bin/ruby
为前缀,如下所示:
#!/usr/bin/ruby
for a in 1..10
puts ( a >= 5 ) ? "a >= 5" : "a < 5"
end