zoukankan      html  css  js  c++  java
  • WindowsBatch与LinuxShell比较[batch常见错误]

    一 变量延迟
    为了更好的说明问题,我们先引入一个例子。
    例1:
        @echo off
        set a=4
        set a=5&echo %a%
        pause
    结果:4
    解说:为什么是4而不是5呢?在echo之前明明已经把变量a的值改成5了?

    让我们先了解一下批处理运行命令的机制:
    批处理读取命令时是按行读取的,在处理之前要完成必要的预处理工作,这其中就包括对该行命令中的变量赋值。我们现在分析一下例1,批处理在运行到这句“set a=5&echo %a%”之前,先把这一句整句读取并做了预处理——对变量a赋了值,那么%a%当然就是4了!(没有为什么,批处理就是这样做的。)

    而为了能够感知环境变量的动态变化,批处理设计了变量延迟。简单来说,在读取了一条完整的语句之后,不立即对该行的变量赋值,而会在某个单条语句执行之前再进行赋值,也就是说“延迟”了对变量的赋值。

    那么如何开启变量延迟呢?变量延迟又需要注意什么呢?举个例子说明一下:
    例2:
        @echo off
        setlocal enabledelayedexpansion
        set a=4
        set a=5&echo !a!
        pause    
    结果:5
    解说:由于启动了变量延迟,得到了正确答案。变量延迟的启动语句是“setlocal enabledelayedexpansion”,并且变量要用一对叹号“!!”括起来(注意要用英文的叹号),否则就没有变量延迟的效果。

    分析一下例2,首先“setlocal enabledelayedexpansion”开启变量延迟,然后“set a=4”先给变量a赋值为4,“set a=5&echo !a!”这句是给变量a赋值为5并输出(由于启动了变量延迟,所以批处理能够感知到动态变化,即不是先给该行变量赋值,而是在运行过程中给变量赋值,因此此时a的值就是5了)。

    再举一个例子巩固一下。
    例3:
        @echo off
        setlocal enabledelayedexpansion
        for /l %%i in (1,1,5) do (
        set a=%%i
        echo !a!
        )
        pause

    结果:
    1
    2
    3
    4
    5

    二 if中的判断
    不多说了,直接看这两段代码。
    1、
        @echo off
        set a=5
        set b=40
        if %a% gtr %b% echo 5比40大!
        pause
        rem 运行结果是“按任意键继续…”
    2、
        @echo off
        set a=5
        set b=40
        if "%a%" gtr "%b%" echo 5比40大!
        pause
        rem 运行结果是“5比40大!”


    比较一下这两段代码,其差别就在引号“""”上。即当变量没被引号括起来的时候进行的是数字的比较;而被引号括起来就是进行字符串的比较(比较字符串时当然5比40大)。

    三 if中注意空变量
    @echo off
    set hero=
    if %hero% equ 1 (echo 正确!) else (echo 错误!)
    pause

    错了吗?

    答:错了。此时变量hero的值为空,即if语句相当于“if equ 1 (echo 正确!) else (echo 错误!)”,equ前面没有东西,当然不对。

    解决方法:加上引号,即“if "%hero%" equ "1" (echo 正确!) else (echo 错误!)”

    四 errorlevel使用的错误。

    @echo off
    find "hero" 1.txt
    if errorlevel 0 echo 找到了!&goto next
    if errorlevel 1 echo 没找到!&goto next
    :next
    pause

    错了吗?

    答:错了!这样写无论1.txt中有没有字符串“hero”都会显示“找到了!”。
    原因是“if errorlevel 0 echo 找到了!&goto next”这句相当于“if %errorlevel% gtr 0 echo 找到了!&goto next”。因此错误码大的一定要写在前面。

    五重定向的问题
    如果你要向一个文件中写入数字1,也许你会这样写:

        @echo off
        echo 1>hero.txt
        pause

    但这样写是错误的,因为这里的数字1有其它用途--代表了
    标准输出流。

    一般情况下不要用个位数直接接重定向符号。

    那么如何解决这个问题呢?我们可以换另外一种格式:

        @echo off
        >hero.txt echo 1

        pause

    六 罪恶的双引号
    双引号在单个使用的时候非常容易犯错误。“"”后面的字符串在第二个“"”出现之前都会被当成一般字符!

    @echo off
    if hero==hero (echo hero is me")
    pause

    这段代码运行不成功,原因是引号后面的括号“)”被当作是一般字符了。


    @echo off
    echo hero is me"&pause
    pause

    这段代码也出乎了我们的意料,原因是引号后面的&被当作是一般字符了。

    批处理中双引号的优先级比较高,但低于百分号,也就是说双引号中的百分号不会被识别为普通字符。

    七 罪恶的空格,空格不能随便乱用,定义变量的时候不要再等号前后加空格,还有很多的情况都需注意。

    八 续行符
    想必大家都知道符号“^”是作为去掉后续符号特殊意义的前导符。“^”还可以作为续行符,就是指出下一行是所在行的延续。

    举个简单的例子:
    @echo off
    echo 英雄^
    是^
    好^
    男人
    pause

    九 再看重定向
    我们知道一个创建快捷方式的方法:
    echo [InternetShortcut] >>a.url
    echo URL=c:\windows\system32\notepad.exe >>a.url
    echo IconIndex=20 >>a.url
    echo IconFile=C:\windows\system32\shell32.dll >>a.url
    是不是觉得代码中每一句都要加上“>>a.url”很繁琐。其实有一个简单的方法:
    (
    echo [InternetShortcut]
    echo URL=c:\windows\system32\notepad.exe
    echo IconIndex=20
    echo IconFile=C:\windows\system32\shell32.dll
    )>a.url

    完!


    作者:iTech
    微信公众号: cicdops
    出处:http://itech.cnblogs.com/
    github:https://github.com/cicdops/cicdops

  • 相关阅读:
    第五周
    第三章 程序的机器级表示
    第二章 信息的表示和处理
    嵌入式Linux应用开发——Linux下的C编程基础
    Linux基础入门(20135207 王国伊)
    Java实验报告(实验四)
    linux系统之pam模块
    linux 从入门到跑路-时间,日期问题
    linux 从入门到跑路-Shell和部分命令
    linux 从入门到跑路-挂载,命令的执行顺序
  • 原文地址:https://www.cnblogs.com/itech/p/1590756.html
Copyright © 2011-2022 走看看