bash case 语句末尾的“esac”是什么意思?是必需的吗?

Grn*_*eye 75 bash case

我在 bash case 语句的末尾发现了多个“esac”的例子,但我没有找到任何关于它使用的明确文档。手册页使用它,甚至在这个词上有一个索引(https://www.gnu.org/software/bash/manual/bashref.html#index-esac),但没有定义它的用途。这是结束案例陈述、最佳实践或纯技术所需的方式吗?

Jac*_*all 125

fiforifdonefor 一样foresac是结束case语句的必需方式。

esaccase落后的拼写,而不是像fiif拼写落后。我不知道为什么结束for块的令牌不是rof.

  • 你的意思是为什么结束一个 `do` 块不是 `od` 吗?:) (41认同)
  • @Wildcard 它是 `fi` 而不是 `neht`,所以通过类比,它会是 `rof`(或 `elihw`)而不是 `od`(当然,`od` 也已经被采用了)......但也许这是对最自相矛盾的语言之一的期望过高。 (14认同)
  • 想象一下,每次要使用该实用程序时都必须键入 `\od`!这是罕见的,但我的观点是;) (4认同)
  • 把你从 666 中拉出来。不客气:P。和很好的答案! (2认同)
  • 它是 `done`,因为语句以 `do` 开头,而不是 `for` 或 `while`。 (2认同)
  • ROTFL 没什么好说的 (2认同)

jll*_*gre 65

esac关键字确实是一个需要分隔符结束case的声明bash在Unix / Linux中使用的除外,最炮弹csh家庭。

最初的Bourne shell是由之前在ALGOL68上工作的Steve Bourne创建的。这种语言发明了这种反字技术来分隔块。

case/esac

if/fi

do/od
Run Code Online (Sandbox Code Playgroud)

后者是没有更多do/oddo/done在Bourne和所有派生壳包括bash因为od已经存在的作为自创建以来UNIX命令(ø CTAL d UMP)。

请注意,do/done功能块用任一引入forwhile,或until指令。forwhile并且until不需要终止done就足够了。这就是为什么不需要假设rofelihw令牌的原因。


Nev*_*DNZ 6

esac”终止了较早的“ case”以形成“代码块”。

在 Algol68 中使用它们,通常使用引入关键字的反转字符序列来终止外壳,例如 ( if ~ then ~ else ~ fi, case ~ in ~ out ~ esac, for ~ while ~ do ~ od ).

Edsger Dijkstra和他的Guarded Command Language之后,我将它们称为“Guarded Blocks” 。

od由于Unix “od”命令的预先存在,大概没有在Bourne Shell中使用。

历史:

“Guarded Block”的想法似乎来自 ALGOL 68例如英语:

proc days in month = (int year, month)int:

  case month in
    31,
    if year mod 4=0 ? year mod 100?0  ?  year mod 400=0 then 29 else 28 fi,
    31, 30, 31, 30, 31, 31, 30, 31, 30, 31
  esac;
Run Code Online (Sandbox Code Playgroud)

苏联的Algol68 LGU 实现也做了同样的事情:在英语中,Algol68 的崇敬 case 语句读取为case ~ in ~ out ~ esac,在西里尔文中读取为??? ~ ? ~ ???? ~ ???

然后在 1975 年,Algol68 的代码块被Edsger Dijkstra借用于他的Guarded Command Language。例如

if a ? b ? max := a
| b ? a ? max := b
fi
Run Code Online (Sandbox Code Playgroud)

推测 Dijstra 使用“Guarded Blocks”来克服在Algol60 中实现的Dangling else歧义,然后在C 编程语言中重新设计。(参见shift-reduce 冲突。

最后——来自 Algol68——" esac" 将它放入 1977 Bourne shell(你发现的地方esac),由Stephen R. Bourne 提供,他开发了早期的 Algol68 编译器,称为ALGOL 68C

著名的 Stephen 还在名为macro.h的“C 头文件”中使用了这些相同的 Guarded Blocks

#define IF  if(
#define THEN    ){
#define ELSE    } else {
#define ELIF    } else if (
#define FI  ;}
Run Code Online (Sandbox Code Playgroud)

著名的软件天才Landon Curt NollLarry Bassel于 1984 年在 National Semiconductor 的 Genix 移植小组工作时偶然发现了 Steve 的 macro.h 代码,并努力理解其应用程序。因此,Landon 和 Larry 然后创建了国际混淆 C 代码竞赛......

从 1984 年到今天,已经有数千种其他“更好”的编程语言不使用 Dijkstra 的受保护命令。史蒂文·伯恩 (Steven Bourne) 对它们的使用macro.h现在经常在 IT 本科生的“软件开发论文”中被引用,作为他们在讲座中没有睡觉的证据。:-)