Home > database >  PowerShell, how to output contents of a function
PowerShell, how to output contents of a function

Time:11-12

I know that this works to view the contents of a function:

cat function:\mkdir

That's fine, so I thought I'd use the bat to syntax highlight that output

PS C:\> bat function:\mkdir
function:\mkdir: No such file or directory

I thought this might work:

PS C:\> bat $(function:\mkdir)
function:\mkdir : The term 'function:\mkdir' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try
again.
At line:1 char:7
  bat $(function:\mkdir)
         ~~~~~~~~~~~~~~~
      CategoryInfo          : ObjectNotFound: (function:\mkdir:String) [], CommandNotFoundException
      FullyQualifiedErrorId : CommandNotFoundException

This also fails:

cat function:\mkdir | bat

What am I doing wrong; how can I output the function contents with a parser of my choice?

For some context, this is for my function that tells me as much information as possible about any cmdlet, function, alias, module, external script, application, or variable, just point what at any object and it will tell you about that object (e.g. what mkdir or what what etc). If bat is on the path, it will use that and colourise the output as PowerShell, and if not, it will use Get-Content. https://gist.github.com/roysubs/20c1bc888383d56df67008f4ba4179cb

CodePudding user response:

Use namespace variable notation:

# As argument.
bat $function:mkdir

# Via the pipeline
$function:mkdir | bat

Note:

  • If the function name contains special characters, such as -, enclose the entire identifier in {...}, such as ${function:Get-Foo}.

  • As an aside:

    • As noted, in PowerShell on Windows, cat is a built-in alias for Get-Content. By contrast, in PowerShell on Unix-like platforms, cat refers to the standard Unix utility (/bin/cat).

In short:

  • $function:mkdir is the equivalent of Get-Content function:mkdir

  • The result is a [scriptblock] instance, which is implicitly stringified when you pass it to an external program, such as bat in your case.

    • A script block conveniently stringifies to its verbatim content, i.e. to its source code. (In the case of a script-block literal - { ... } - the { and } are not included).
  • Namespace variable notation only works with literal function names; use the Get-Content equivalent if the function must be supplied via a variable or expression:

    $cmd = 'mkdir'
    
    # As argument.
    bat (Get-Content function:$cmd)
    
    # Via the pipeline
    (Get-Content function:$cmd) | bat
    
  • Related