Skip to content

Commit

Permalink
main
Browse files Browse the repository at this point in the history
  • Loading branch information
sharpchen committed Jan 20, 2025
1 parent 6259b13 commit c0e7fdd
Show file tree
Hide file tree
Showing 11 changed files with 271 additions and 30 deletions.
9 changes: 0 additions & 9 deletions docs/document/PowerShell/docs/File System/1.Overview.md

This file was deleted.

19 changes: 0 additions & 19 deletions docs/document/PowerShell/docs/File System/3.Special Folders.md

This file was deleted.

101 changes: 101 additions & 0 deletions docs/document/PowerShell/docs/Item Manipulation/Path.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
# Path

## Resolve Path

- `-Path(0, pv)`: expand path containing special characters like `~` or UNC(Universal Naming Convention) path and some other special paths
```ps1
Resolve-Path '~/*' # returns all PathInfo of children under `~`
Resolve-Path ~ # returns expanded path as PathInfo of `~`
```
- `-Relative(switch)`: get all relative paths from current path or specified location of items to be listed
```ps1
Resolve-Path '~/*' -Relative # list all relative string of children under ~ relative to current location
```
- `-RelativeBasePath`: get all relative paths from specified location of items to be listed
```ps1
Resolve-Path '~/*' -RelativeBasePath ~ -Relative # list all children of ~ relative to ~ itself
```
## Part of Path
- `-Path(0, pv)`: get parent path as `PathInfo`
```ps1
Split-Path ([System.IO.Path]::GetTempFileName()) # C:\Users\username\AppData\Local\Temp
```
- `-Parent(!, switch)`: optional, the default flag for `Split-Path`, returns the parent container of `-Path`
- `-Leaf(switch)`: get base name of a path
```ps1
Split-Path ([System.IO.Path]::GetTempFileName()) -Leaf # tmpfigvir.tmp
```
- `-LeafBase(switch)`: get base name without extension
```ps1
Split-Path ([System.IO.Path]::GetTempFileName()) -LeafBase # tmpfigvir
```
- `-Extension(switch)`: get extension
```ps1
Split-Path ([System.IO.Path]::GetTempFileName()) -Extension # .tmp
```
- `-Qualifier(switch)`: get drive prefix of the path, not available on non-Windows platform
```ps1
Split-Path ([System.IO.Path]::GetTempFileName()) -Qualifier # C:
```
- `-NoQualifier(switch)`: exclude the drive prefix of the path, not available on non-Windows platform
```ps1
Split-Path ([System.IO.Path]::GetTempFileName()) -NoQualifier # \Users\username\AppData\Local\Temp\tmpoo33lr.tmp
```
- `-IsAbsolute(switch)`: telling whether the path is absolute
- `-Resolve(switch)`: handles relative or wildcard path for `-Path`
```ps1
Split-Path ~/* -Resolve # all parents of children under ~, which are all the same as `Resolve-Path ~`
```
## Path Validation
- `-Path(0, pv)`: telling whether the path exists, can be relative
```ps1
Test-Path '~/.vimrc'
Test-Path '../.gitignore'
```
- `-Filter`: common filter
```ps1
Test-Path '~/*rc'
```
- `-IsValid(switch)`: telling whether the provided path has correct syntax
```ps1
Test-Path 'foo/bar' # False
Test-Path 'foo/bar' -IsValid # True
```
- `-Exclude` & `-Include`: telling whether any/no path matches the specified pattern
```ps1
Test-Path '~/*' -Exclude *rc # is there any file exists besides rc files?
```
- `-PathType`: telling whether the path is a leaf or a container(leaf is the child of a container)
```ps1
Test-Path '~/.vimrc' -PathType Leaf # True, it is a file indeed
```
> [!NOTE]
> The meaning of `Leaf` is not the same as `Leaf` in `Split-Path`, `Leaf` can be any kind of child of a container in `Split-Path`.
- `-NewerThan` & `-OlderThan`: telling whether the path was created before/after a date(can be date string)
```ps1
Test-Path ~/.vimrc -NewerThan "2012.6.12"
```
## Join Path
- `-Path(0)` & `-ChildPath(1)`: join one or more parents with single child
```ps1
Join-Path C:, D: foo
# C:\foo
# D:\foo
```
- `-AdditionalChildPath(remain)`: accepts unlimited count of child paths
```ps1
Join-Path -Path foo -ChildPath foo -AdditionalChildPath foo, foo, foo # this is how it work formally
Join-Path foo foo foo foo foo # this is how you could use it in daily life
```
- `-Resolve(switch)`: resolve( and validate) the path and join them, supports wildcard to join multiple matches at one time
```ps1
Join-Path ~/Projects nix-config -Resolve # C:\Users\username\Projects\nix-config
Join-Path ~/Projects .git -Resolve # C:\Users\username\Projects\.git does not exist # [!code error]
Join-Path ~/Projects * -Resolve # equvalent to `Resolve-Path ~/Projects/* | % Path` # [!code highlight]
```
120 changes: 118 additions & 2 deletions docs/document/PowerShell/docs/Language/Control Flow.md
Original file line number Diff line number Diff line change
Expand Up @@ -105,12 +105,128 @@ It has a few different patterns available:
- Regex: matching by regex string, specifically for `string`.
- Wildcard: matching by wildcard string, specifically for `string`.

### Synopsis

`switch` in PowerShell differs from c-like languages in:
- condition can be a procedure(scriptblock) so you can perform more nested and complex determine
```ps1
switch (1) {
{ $_ -is [int] } { "Int32" }
}
```
- can have implicit return, each time the case matches yields the result into the final array, or just the singular result when only one case matches
```ps1
$foo = switch ($bar) { <# ... #> }
$foo -is [System.Object[]] # True
```
- `default` block is not required(`$null` will be returned when no case is matched)
- can match for not only a singular object but an collection
```ps1
$foo = switch (1, 2, 3) { }
```
- use `continue` to skip current enumeration
```ps1
switch (1, 2) {
1 { continue } # I don't want to preceed with this value 1, next!
2 { "aha" }
} # aha
```
There's three options available `switch`(specifically for `string` macthing):
- `-Exact`: the default option that matches the string by literal, can be elided
- `-Regex`: match by regex condition
- `-Wildcard`: match by wildcard condition
- `-CaseSensetive`: case-sensitive matching, can be combined with any of other three options
### Constant Pattern
Constant pattern is specifically for numbers and strings.
While `switch` has dedicated options for strings but those does not apply on other literals.
However, when a non-string type is tried to match the string case by no matter which option you specified, it will be evaluated to string.
```ps1
$foo = 1
$bar = switch -Exact ($foo) {
1 { "one" }
2 { "two" }
3 { "three" }
1 { "one" } # reachable # [!code warning]
'1' { "stringified one" } # matched too! # [!code highlight]
}
$bar = switch ($foo) { # -Exact can be elided # [!code highlight]
1 { "one"; break }
2 { "two" }
3 { "three" }
1 { "one" } # not reachable # [!code highlight]
default { "ok I am the last resort" }
}
```

### Type Pattern

### Regex Pattern
Nothing else

```ps1
switch ("foo") {
{ $_ -is [string] -and $_.Length -gt 0 } { 'all right' }
}
```

### Regex & Wildcard Pattern

I don't have much to say

```ps1
switch -Regex -CaseSensetive ("hello") {
"h\d+" { "..." }
"H\w+" { "..." }
}
```

## Trap

### Wildcard Pattern
`trap` is been called as a statement in PowerShell worlatchedd, but this is more like a `trap` block, for it:
- serve as a isolated process for handling any error raised in the script or function
- can be defined anywhere inside the script or function

But what makes it different from *block* is, you can specify multiple `trap` for different error types.
**And PowerShell only run the most specific `trap` statement for the error**

> [!NOTE]
> Use `$_` to access the captured error object inside `trap`
> [!WARNING]
> Do not defined more than one `trap` for a same error type, only the first would be executed
```ps1
param()
trap {
"Any error was triggered"
}
trap [System.StackOverflowException] {
"A dedicated exception happened"
}
```

`trap` does not break the process, but only executes when particular error happens unless, you use `break`.

```ps1
param()
trap {
"Stop here"
break
}
ErrorHere
Write-Host "Not reachable here" # [!code warning]
```

> [!NOTE]
> `continue` is also available in `trap`, the only difference is it does not write the error to error stream
42 changes: 42 additions & 0 deletions docs/document/PowerShell/docs/Standard IO/Stream Redirection.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
# Stream Redirection

The streams are implicitly working everyday we use redirection operator `>`, `>>` in PowerShell.
Streams are `Success`, `Error`, `Warning` ... that's exactly the counterpart of `Write-Output`, `Write-Error` ...

> [!NOTE]
> See: [Output Streams](https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_redirection?view=powershell-7.4#redirectable-output-streams)
> [!NOTE]
> Append redirection `>>` is only available for files
## Redirect to File

When you write to a file using `>` to redirect content, it's actually redirecting the `Success` stream to the file.

```ps1
gci > foo.txt
# equivalent to
gci 1> foo.txt # 1 represents the Success stream
```

## Redirect to Another Stream

```ps1
gci 1>&2 # redirect Success stream to Error stream
```

## Redirect at One Go

You can apply multiple redirection for a same source.

```ps1
& { Write-Warning "hello"; Write-Error "hello"; Write-Output "hi" } 3>&1 2>&1 > C:\Temp\redirection.log
```

## Suppress Message from Streams

If you only care specific message from streams or exculde particular stream, redirect it to `$null`

```ps1
ffmpeg -h *> $null # swollow all streams output from ffmpeg
```
10 changes: 10 additions & 0 deletions docs/document/PowerShell/docs/Terminology.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,13 @@ By this approach, you can expose minimal privileges and custom utilities to user
Each Runspace creates isolated session state just like a normal powershell instance.

A normal powershell can be referred as a Runspace too.

## Execution Policy

Execution Policy is dedicated for Windows platform, it restricts the authority to execute a valid PowerShell script or command.

- `AllSigned`: requires scripts to be signed by trusted-publisher
- `Bypass`: does not block anything
- `Default`: `Restricted` for Windows personal and `RemoteSigned` for Windows Server
- `Unrestricted`: default and unchangeable for non-windows platform
- `Restricted`: no script allowed; command execution allowed

0 comments on commit c0e7fdd

Please sign in to comment.