转 关于shell中if 语法结构的广泛误解
转自 ttp://blog.csdn.net/security134/article/details/6742156
最近学习SHELL编程 这篇文章很好很重要。有些东西不能想当然。同时不是表面看起来那么简单。以为自己懂了。其实差的还远
Cuibtoy发布于 2008-8-28 http://www.linuxdiyf.com/viewarticle.php?id=105505
我打赌正在看这篇文章的你, 超过99%的可能性你对这个问题的理解是错的. 或者至少是有偏差的.
我深信这是一种教育法上的广泛错误, 那就是告诉大家说:
if [ condition ]
then
...
fi
这是bash中条件语句的"语法".
任何人, 或者说几乎任何人, 都会在这种描述下自然地认为: [ 和 ] 是这种语法结构本身的一部分, 并且,
老老实实地在自己的脚本中总是这样使用if 语句, 如果你总是在判断字符串是否相等, 或文件的各种属性, 这么做倒是没错,
只不过你可能会这样犯错:(下文都假设$1内容为-a)
if ["$1" = "-a" ]
或
if [ "$1 = "-a"]
毕竟, 很多其它语言中, 特殊符号如()、{}做分隔符时, 可以与被分隔内容亲密无间. 而bash会来答复你的这种写法:
[-a: command not found
bash: [: missing `]'
我相信, 以上这种心理模型造成的失败后果十分严重, bash的错误信息显示出它内部并不这样看待if 条件语句的结构.
上面的模型同样不能解释下面的合法bash 命令:
[ "$1" = "-a" ]
仅仅这本身就是一个合法的命令, 没有if、then、fi这些东西,当然, 下面这样的也合法
[ "$1" = "-a" ] && echo yes
你如何解释这些烂事? 当然你可以自圆其说地不断对上面的if进行补充, 呃, [ .. ] 这种结构就是这么特别, 你必需在[之后有至少一个空格,
并且在]之前也至少有一个空格, 同时[..] 结构还可以单独出现, 就象上面这样, 另外... 这样的解释简直是自欺欺人,
我敢保证企图对自己这样解释的人根本自己就在怀疑这种说法, 因为你根本不知道这个结构还有其它什么怪诞诡秘之处何时会突然跳出来让你大吃一惊.
我承认,我自己也曾经经历过这样的想法.
为了彻底批判这种错误概念, 容我再举一例:
if ps ax | grep oracle > /dev/null 2>&1 ; then
...
fi
首先, 这是合法的, 它的目的是想知道进程列表中有没有与oracle相关的东西, 当然, 如果你够牛, 就能看出这种做法有另外的问题. 但这不是我想说的重点.
我想说的是, 你前面被教导的这种if 语句的语法模型, 如何解释这个, [ 与 ] 又不见了, 并且还出现了管道, 普通的管道我们都见过, 但它能安全地出现在if 语句中吗, 并且, 让你感觉熟悉和安全的[ 和 ]又不见了.
好吧, 拨乱的部分至此为止, 如果你想获得一个关于bash中if结构的正确的健康的环保的知识, 就打起精神往下看:
1. 首先, [ 在bash中没有特殊地位, 它是一个命令, 就跟cat, ls, grep一样让你感到熟悉的命令. 它不是关键字,虽然它的更出色的胞弟"[["是
echo [
你就得到 [, 不信就试试, bash不会报告任何错误! 但这不说明它不是关键字, echo if你也能得到if
所以, 请再试:
which [
以及
ls -l $(which [)
2. 然后, if 的真正模型是:
if COMMANDS; then COMMANDS; [ elif COMMANDS; then COMMANDS; ]... [ else COMMANDS; ] fi
其实, bash中的help if就给了你正确的答案, 但我不知道什么原因无数人就是忽略了它, 而非常多的bash教学资料中都采用了本文开头提出的那种模型来告诉你关于if 结构的事.
注意: [ "$1" = "-a" ] 只一个命令, [ 是命令名!, "$1"是第一个参数, =是第二个参数, "-a"是第三个,
]是第4个. 是[这个命令, 而不是bash本身在报怨 [ "$1" = "-a"] 这样的结构造成的错误, 因为[这个命令对它的参数有所期望,
它期望最后一个参数是 ], 而你用"-a"] 这种连写的形式, 它得到的就只有3个参数: $1, = 和 -a].
这也解释了这样的错误:
["$1" = "-a" ]
bash解释器得到了这样的一个命令行:
[-a = "-a" ]
当然, 它认为 [-a 是命令名部分, 而你的系统中没有这个命令, 所以会报告说:
[-a: command not found
3. 其次, bash中有一个builtin的 [命令, 通常你使用[执行的都是这个内置的命令, 目的是效率. 启动一个进程的代价太高.
试试
type [
命令
转 关于shell中if 语法结构的广泛误解的更多相关文章
- Java初认识--Java中的语法结构
Java中的语法结构(程序流程控制) Java的语法结构有四种: 1.顺序结构. 顺序结构很简单,就是按顺序执行,输出就可以了. 2.判断结构. 判断结构的一个代表性的语句是if:if语句有三种格式体 ...
- shell中的控制流结构
shell中的控制流结构 1.if...then..else..fi语句 2.case语句 3.for循环 4.until 语句 5.while循环 6.break控制 7.continue 控制 1 ...
- (八)shell中的循环结构
1.for循环(1)要求:能看懂.能改即可.不要求能够完全不参考写出来.因为毕竟嵌入式并不需要完全重新手写shell,系统管理员(服务器运维人员,应用层系统级管理开发的才需要完全掌握shell) 这里 ...
- shell中的语法(1)
反引号 命令替换.将命令的输出放在命令行的任意位置. eg. [root@gam ~]# echo The Data is `date` The Data is Fri Nov 18 10:13:56 ...
- shell中switch语法
转载: https://blog.csdn.net/love__coder/article/details/7262160
- ANTLR4权威指南 - 第6章 尝试一些实际中的语法
第6章 尝试一些实际中的语法 在前一章,我们学习了通用词法结构和语法结构,并学习了如何用ANTLR的语法来表述这些结构.现在,是时候把我们学到的这些用来构建一些现实世界中的语法了.我们的主要目标是,怎 ...
- shell中select、case的使用
case和select结构在技术上说并不是循环, 因为它们并不对可执行代码块进行迭代. 但是和循环相似的是, 它们也依靠在代码块顶部或底部的条件判断来决定程序的分支. select select结 ...
- shell中的(),{}几种语法用法
转自:https://www.cnblogs.com/HKUI/p/6423918.html 查看脚本语法是否有错误:bash -n modify_suffix.sh跟踪执行sh -x modify_ ...
- centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件、目录属性 shell数组简单用法 $( ) 和${ } 和$(( )) 与 sh -n sh -x sh -v 第三十五节课
centos shell脚本编程1 正则 shell脚本结构 read命令 date命令的用法 shell中的逻辑判断 if 判断文件.目录属性 shell数组简单用法 $( ) 和$ ...
随机推荐
- oracle 非sys用户创建新用户 授权后 plsql看不到视图
问题: oracle 非sys用户创建新用户 授权后 plsql看不到视图 答案: 新用户查询视图时,视图名称前需要添加 视图所属用户. 如user用户新建newUser用户,newUser用户查 ...
- [LeetCode题解]: Sort Colors
前言 [LeetCode 题解]系列传送门: http://www.cnblogs.com/double-win/category/573499.html 1.题目描述 Given an a ...
- [CSS]利用伪元素实现一些特殊图形 from baidu校招
最近在博客园看到某人发的baidu校招题目,说是要用一行html代码实现下面的这个图形: 给定的html代码是: <div class='square'></div> ---- ...
- ASP.NET MVC 控制器通过继承控制器来达到 过滤 并且多了一个IAuthenticationFilter
暂时没有用到过这个IAuthenticationFilter接口,毕竟已经有三个具体实现类了,所以这个还不知道用在哪,以后看看 20190324 需要注意!!!控制器重写方法都是被protected修 ...
- MVC断点续传
using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mv ...
- MYSQL ZIP 压缩包 安装
基win10安装 1.管理员身份打开cmd 2.进入mysql 的 bin文件下 D: 回车 3.mysql服务名字 -install 回车 4.net start mysql服务名字 ...
- Python短路原则
1.括号内逻辑先执行 2.and优先级大于or 3.and一假为假 4.or一真为真 and:如果左边为假,返回左边值.如果左边不为假,返回右边值. or:如果左边为真,返回左边值.如果左边不为真,返 ...
- XSSFWorkbook实现导出excel
1.pom.xml中加入poi依赖: <!-- poi --> <dependency> <groupId>org.apache ...
- scroll滚动到一定距离触发事件/返回顶部animate
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8&quo ...
- Tomcat企业级应用
简介 Tomcat是Apache 软件基金会(Apache Software Foundation)的Jakarta 项目中的一个核心项目,由Apache.Sun 和其他一些公司及个人共同开发而成.由 ...