ITPub博客

首页 > 自动化运维 > 大规模网络运维 > [20240416]批处理 for tokens内部赋值问题.txt

[20240416]批处理 for tokens内部赋值问题.txt

原创 大规模网络运维 作者:lfree 时间:2024-04-22 20:44:32 0 删除 编辑

[20240416]批处理 for tokens内部赋值问题.txt

---//调试windows批处理遇到的问题,通过例子说明:

D:\>cat aa.bat
@echo off

for /f "tokens=1,2" %%a in (aa1.txt) do (
    set tablespace_name=%%a
    set usage_percent=%%b

    echo %%a -- %%b
    echo -------------
    echo %tablespace_name%:%usage_percent%
    echo +++++++++++++
rem    if %usage_percent% GEQ 80 (
rem        echo %tablespace_name%
rem    )
)

@ echo on

--// 简单介绍,就是从aa1.txt文本取第1,2字段,各种组合输出.

d:\>cat aa1.txt
aaaa 81
user 60

--//第1次执行:
D:\>aa
aaaa -- 81
-------------
:
+++++++++++++
user -- 60
-------------
:
+++++++++++++
--//注意看echo %tablespace_name%:%usage_percent% 那行仅仅输出:,感觉就想赋值失效一样.

D:\>echo %tablespace_name%:%usage_percent%
user:60

--//而在命令行上单独执行有输出,并且是aa1.txt文本对应的最后1行.

--//第2次执行:
D:\>aa
aaaa -- 81
-------------
user:60     --//按照一般理解这里应该输出 aaaa:81
+++++++++++++
user -- 60
-------------
user:60
+++++++++++++

D:\>echo %tablespace_name%:%usage_percent%
user:60

--//可以看出windows批处理的设计非常的垃圾,很容易搞错,实际上tablespace_name的赋值仅仅在括号外有效(for循环体的外面).
--//第1次执行给tablespace_name,usage_percent赋值,但是在循环体内并不显示.
--//第2次执行显示的是前面第1次执行获取的赋值.
--//修改aa1.txt文件,两行对调.
D:\>cat aa1.txt
user 60
aaaa 81

--//第3次执行:
D:\>aa
user -- 60
-------------
user:60
+++++++++++++
aaaa -- 81
-------------
user:60
+++++++++++++

D:\>echo %tablespace_name%:%usage_percent%
aaaa:81
--//变成了aaaa:81

--//第4次执行:
D:\>aa
user -- 60
-------------
aaaa:81
+++++++++++++
aaaa -- 81
-------------
aaaa:81
+++++++++++++

--//我的理解尽量避开这样的赋值,直接使用%%a,%%b的值.

--//修改如下,里面不能存在变量赋值语句.
$ cat bb.bat
@echo off

for /f "tokens=1,2" %%a in (aa1.txt) do (

    echo %%a -- %%b
    echo -------------
    if %%b% GEQ 80 (
        echo tablespacename=%%a
    )
)

@ echo on

D:\>bb
user -- 60
-------------
aaaa -- 81
-------------
tablespacename=aaaa

--//看了一些文档,似乎这个叫延迟环境变量.
--//help set可以查询到如下例子:
终于添加了延迟环境变量扩充的支持。该支持总是按默认值被
停用,但也可以通过 CMD.EXE 的 /V 命令行开关而被启用/停用。
请参阅 CMD /?

考虑到读取一行文本时所遇到的目前扩充的限制时,延迟环境
变量扩充是很有用的,而不是执行的时候。以下例子说明直接
变量扩充的问题:

set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "%VAR%" == "after" @echo If you see this, it worked
)

--//以上代码执行不会看到If you see this, it worked的输出.
--//如果修改如下:
D:]> cat cc.bat
set VAR=before
if "%VAR%" == "before" (
    set VAR=after
    if "!VAR!" == "after" @echo If you see this, it worked
)

D:\>cc
D:\>set VAR=before

D:\>if "before" == "before" (
set VAR=after
 if "!VAR!" == "after"
)

--//没有输出,缺省不支持延迟环境变量扩充的支持.启动新的cmd,加入/v参数.

D:\>cmd /v
Microsoft Windows XP [版本 5.1.2600]
(C) 版权所有 1985-2001 Microsoft Corp.

D:\>cc

D:\>set VAR=before

D:\>if "before" == "before" (
set VAR=after
 if "!VAR!" == "after"
)
If you see this, it worked

--//可以发现有输出.
--//如果像前面的例子,修改如下:

D:\>cat aa.bat
@echo off

for /f "tokens=1,2" %%a in (aa1.txt) do (
    set tablespace_name=%%a
    set usage_percent=%%b

    echo %%a -- %%b
    echo -------------
    echo !tablespace_name!:!usage_percent!
    echo +++++++++++++
rem    if %usage_percent% GEQ 80 (
rem        echo %tablespace_name%
rem    )
)

D:\>cmd /v /c aa
user -- 60
-------------
user:60
+++++++++++++
aaaa -- 81
-------------
aaaa:81
+++++++++++++

--//这样就正确了,符合一般对于编程的理解.如果不打开/v 看到的结果如下:

D:\>cmd /c aa
user -- 60
-------------
!tablespace_name!:!usage_percent!
+++++++++++++
aaaa -- 81
-------------
!tablespace_name!:!usage_percent!
+++++++++++++


来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/267265/viewspace-3013375/ ,如需转载,请注明出处,否则将追究法律责任。

请登录后发表评论 登录
全部评论
熟悉oracle相关技术,擅长sql优化,rman备份与恢复,熟悉linux shell编程。

注册时间:2008-01-03

  • 博文量
    4006
  • 访问量
    7969412