Linux C+最简单的外壳+/C#/Java程序员
Linux C+最简单的外壳+/C#/Java程序员,linux,shell,unix,Linux,Shell,Unix,我对bash编程有点纠结,因为我似乎不理解语法规则。例如: read confirm if [ "$confirm" == "yes" ]; then echo "Thank you for saying yes" else echo "Why did you say no?" fi 在这段代码中,您可以使用许多表单来执行相同的操作: "$confirm" == "yes" $confirm == "yes" "$confirm" == yes $confirm == yes
我对bash编程有点纠结,因为我似乎不理解语法规则。例如:
read confirm
if [ "$confirm" == "yes" ]; then
echo "Thank you for saying yes"
else
echo "Why did you say no?"
fi
在这段代码中,您可以使用许多表单来执行相同的操作:
"$confirm" == "yes"
$confirm == "yes"
"$confirm" == yes
$confirm == yes
那么规则是什么呢?除此之外,它是非常严格的,所以如果你写上面的if语句时没有“[”和“””之间的空格,你会得到一个错误。所以我的问题是:
Rafid的一个问题是,如果您这样做:
if [ $foo == "bar" ] ...
如果$foo为空,则会出现语法错误
# prepend both with an 'x' (or any other char)
if [ x$foo == "xbar" ] ..
# or enclosing in quotes (not sure this works on all shells)
if [ "$foo" == "bar" ] ...
将内容放在引号内还可以确保保留空白以便进行比较
今天,还有其他更高级的方法在if语句中使用表达式,例如双括号
if [[ $foo == bar ]]
有关详细信息,请参阅
至于选择要学习的脚本方言,我建议学习bash,因为它是目前为止最常见的一种。如果您想编写可移植的脚本,那么就把自己限制在旧的“sh”方言上,这种方言没有那么高级,但几乎所有unix shell都应该支持
对于C风格的程序员来说,语法方面的规则可能更容易学习(因为语法与C的匹配更紧密),但它在野外不太常见bash中最基本的语法规则是:
<command> <space>+ <arguments>
+
也就是说,命令和参数必须用一个或多个空格分隔。[
是一个命令,因此在它之后省略空格是一个错误
至于哪个“更好”,我附和j_random_hacker的评论:
所有的shell语言都很可怕,尽管有些比其他语言更可怕,而且都比Windows的cmd.exe好。我的建议是坚持使用最流行的bash
我建议你去看看。它的语法更类似于C。这里有一些关于bash技巧的有用链接:
- (因此,质询)
"$confirm" == "yes"
因为这样可以确保BASH将两个值都看作字符串。否则,它们将受到扩展/替换,这可能会导致意想不到的结果或语法错误。 至于语法错误,当您使用ommit时,大括号和引号之间的空格--opening brace“[”只是“test”shell内置的别名。因此您的条件也可以写成:
read confirm
if test "$confirm" == "yes"; then
echo "Thank you for saying yes"
else
echo "Why did you say no?"
fi
事实上,在某些系统上,/usr/bin中有一个名为[]的文件,该文件链接到test命令(如果某些shell没有“[”作为shell内置命令).所有的shell语言都很可怕,尽管有些比其他的更可怕,而且都比Windows的cmd.exe好。我的建议是坚持使用最流行的bash。
manbash
应该给你(庞大而复杂的)语法规则。更多关于[
、测试和[
请参见以下答案:
规则很简单,但很微妙。您给出的示例并不完全相同,它们有着微妙的不同含义。您可以阅读一个相当好的参考资料,它涵盖了POSIX Shell。大多数Shell,当然包括bash、zsh和ksh,都是POSIX Shell,并且至少会实现其中列出的内容。一些Shell可能符合前面的v规范或规范的版本应相似但不一致
如果您正在学习Unix shell脚本,您需要记住的主要规则是:表达式用空格分隔。从技术上讲,它们用变量$IFS中列出的任何字符分隔,但在正常情况下这相当于空白
如果您在bash中说[“$a”=“$b”]
,shell会尝试将整个字符串作为命令读取,计算$a和$b。假设$a
的值是文本a
,而$b
的值是文本b
,shell会尝试执行名为[a=b]的命令
,这是一个合法的文件名。shell将引号解释为特殊的,但[
不是,因为它只有作为单独的标记写入时才是特殊的。它没有用空格分隔
在shell中看到和执行的几乎所有操作都是命令。字符[
不是语法,而是命令。命令使用参数,用空格分隔。这些参数的含义取决于命令,而不是shell。在Cif(a==b)
中,除了a和b的值之外,所有操作都由解析器处理。在bashif[“$a“==”$b“]
首先由shell解析,它计算变量$a和$b,然后执行命令[
。有时这是一个shell内置命令,有时它实际上是一个单独的可执行文件(在系统中查找/bin/[
)。这意味着a==b]
完全不是由bash解释的,而是一种由[
解释的领域特定语言,也称为test
。事实上,如果test“$a”==“$b”
,您可以编写。在这种形式下,test
不需要关闭]
,但其他一切都是一样的。要查看test
将如何处理这些参数,请阅读help test
或man test
学习Unix shell脚本时要记住的另一条规则是:首先展开变量,然后计算命令。这意味着如果变量中有空格,例如foo=“a b”
然后shell将在变量展开后看到空格:ls$foo
自身将抱怨找不到文件a
,并且