zoukankan      html  css  js  c++  java
  • powershell初探(五)

      这一章谈谈ps的管道通信,函数和过滤器。这仨哥们之间有着千丝万缕的联系。当然,跟我比较懒,不想写三篇来介绍也有关。

      什么是管道?简单来说,管道就是一种函数的组合,类似于B(A(X)),就是把一个函数的输入作为一个函数的输出,他有一定的局限性,你最多只能..D(C(B(A(X)))),而不能D(C

    (X),B(X),A(X))。这个关于管道的解释我觉得比较通俗易懂,我是从另一个博主的博文中摘取的,原文在王垠:Unix的缺陷。这是一篇介绍Unix的哲学缺陷的文章,其中说到的用文

    本流作为程序通用接口的缺陷我在ps中没有发现,应该是因为ps是建立在CTS(通用类型系统)上的原因,所以ps支持多种类型。

      什么是函数?有你的初中老师数学电话没?打过去问他。(计算机的中的函数概念可能和数学中的有区别,但我觉得数学中对函数的定义更加的严谨)

      什么是过滤器?过滤器在ps中可以算是一种特殊的函数。

      在ps中管道通信使用“|“这个操作符,一个函数组合D(C(B(A(X))))可以表达为A(X)|B(X)|C(X)|D(X)。

      假设如下情景,你需要获得每一个进程的详细信息并且将他们输出到一个txt文件,那么你要做两件事

      (1)获得所有的进程。get-process

      (2)输出他们到txt文件。set-conent process.txt

      用管道表达就是:get-process|set-conent process.txt

      打开process.txt你会发现其中的内容与输出到控制台的内容并不相同,那是因为get-process返回的是一个进程对象,输出到控制台的内容经过了处理。

    既然管道函数的组合,那get-process和set-content都是函数了,我们又可不可以使用自己定义的函数来接收管道输出呢?of course!

      将以下代码拷贝到记事本中并保存为function.ps1为拓展名的文件(.ps1是ps脚本文件的拓展名)

    function from-function
    {
        foreach($name in $input)
        {
            write-host "$name from function"
        }    
    }
    filter from-filter
    {
            foreach($name in $input)
            {
                    write-host "$name id from filter";
            }
    }

       然后打开ps转到你保存的脚本目录下,输入". ./function.ps1"(注意两个点之间的空格,这种使用脚本的方式称为点源引用,将不会执行脚本而是直接将脚本释放到当前的shell中)

      再输入如下命令"get-process|from-function",结果如下图: 

      你一定注意到了定义函数的同时我还定义了一个filter,在控制台中输入"get-process|from-filter",你将会得到跟上图一样的结果。

      那filter跟函数到底有什么不同?$input又是什么?

      filter和函数其实是一样的。唯一的不同之处在于filter中的管道对象是一输出即被使用,而函数的管道对象却可以选择在完全输出后才被使用。

      让我们在D盘根目录下输入"get-childrenitem -r|from-function"(其中get-childrenitem -r是以递归的方式获得D盘下的所有子项,即获得D盘下的所有文件和文件夹)。如果你D盘的文件数目够多的话你会看到console卡顿的现象,这是因为from-function函数在等待管道对象全部传递完毕储存在$input才开始执行。而输入"get-childrenitem -r|from-filter"你会看见直接执行了。这是因为from-filter这个过滤器在每次管道有对象传入的时候就会执行。

      而$input是一个枚举器。可以让函数和过滤器枚举管道对象。他和$_这个变量的作用应该是相同的,至少我还没有发现不同的地方。

      其实函数也可以立即输出管道对象而不必等待管道对象接收完毕。将from-function改为:

    function from-function
    {
        param([string]$hello,[string]world)
        process
        {
            write-host "$input  from function"
        }
    }

       然后再次". ./function.ps1"点源引用脚本以更新当期控制台的from-function函数,输入"get-process|from-function"

      你会发现输出的情况和过滤器一样了。注意下面这段话,来自powershell help

    “In the Process block of a function, $input contains the object currently in the pipeline… If the function does not have a Process block, the value of $input is 
    available to the End block, and it contains all of the input to the function.”

       原来在函数没有process块的时候,$input将会等待管道对象存储完毕才能使用。而包含process块的时候,$input将包含当前管道对象。而对于后一种情况,建议使用$_而不是$input。过滤器的情况由于与后一种情况相同,所以过滤器中建议使用$_。(我真不知道$input跟$_的区别,谁能告诉我T_T)

      最后要说的是,函数中还有Begin{},和End{},这两个脚本块来处理函数的初始化和最后的返回值。不过没有也不会影响函数的运行。你也可以定义函数的参数像下面这样

    function from-function
    {
        param([string]$hello,[string]$world)
        process
        {
            write-host "$hello $world from function"
        }
    }

      调用如下命令 get-childrenitem -r|from-function -hello "hello" -world "world",你就可以看见参数传递给函数了。如下图:

      函数还用作用域,默认参数等等问题,今天就先到这吧,这些以后有机会再写,dota去了\(^o^)/~

  • 相关阅读:
    关于我 — About Me
    《这样说就对了》读书笔记
    LOMA280保险原理读书笔记
    .NET单元测试的艺术-3.测试代码
    .NET单元测试的艺术-2.核心技术
    .NET单元测试的艺术-1.入门
    《人人都该买保险》读书笔记
    借助 Lucene.Net 构建站内搜索引擎(下)
    借助 Lucene.Net 构建站内搜索引擎(上)
    自己动手写一个简单的MVC框架(第二版)
  • 原文地址:https://www.cnblogs.com/iiaijimaai/p/2657629.html
Copyright © 2011-2022 走看看