我就是饿死,死外面,从外面跳下去,也不会用 M$ 的垃圾 PowerShell!

……

我草,真香!

事情的起因是这样的,作为一般通过Windows用户,突然间我遇到了一个需求:每天ssh登录服务器下载一个备份文件。由于每个备份文件都很大(> 500MB) 我希望我能只在本地保留5份文件。同时,由于网络环境不够可靠,我希望它能自动检测错误并提醒我重试。而我手上只有一个孱弱的 CMD

估算了一下我需要的工作量后,我颤颤巍巍地决定尝试一下我从来没用过的 PowerShell。毕竟作为一个后来的产物,比起瞬间启动的bash,启动时间高达 3 秒的它,总不能比 CMD 还差吧?

但我还是不太抱希望,因为我脑子里的Bash,一般是语法一般长这样的恐怖东西:

(感谢 husky 的友情支持)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#!/usr/bin/env sh
if [ -z "$husky_skip_init" ]; then
debug () {
if [ "$HUSKY_DEBUG" = "1" ]; then
echo "husky (debug) - $1"
fi
}

readonly hook_name="$(basename -- "$0")"
debug "starting $hook_name..."

if [ "$HUSKY" = "0" ]; then
debug "HUSKY env variable is set to 0, skipping hook"
exit 0
fi

if [ -f ~/.huskyrc ]; then
debug "sourcing ~/.huskyrc"
. ~/.huskyrc
fi

readonly husky_skip_init=1
export husky_skip_init
sh -e "$0" "$@"
exitCode="$?"

if [ $exitCode != 0 ]; then
echo "husky - $hook_name hook exited with code $exitCode (error)"
fi

if [ $exitCode = 127 ]; then
echo "husky - command not found in PATH=$PATH"
fi

exit $exitCode
fi

充满了复杂的变量,充满了对系统的知识,充满了在高级语言看来莫名其妙的语法。语法诡异,需要拓展,这是我对 bash 的刻板印象。本以为, PowerShell 作为写脚本的,也会不免如此,但是我错了。

在Powershell里,我该怎么获取时间?怎么检测错误?怎么做判断?对此一窍不通的我,抱着要啃1MB的文档的心态去打开Powershell的教程,结果却看到:

1
$file.CreationTime -le (Get-Date).AddDays(-5)

啊?我想象中的管道呢?

$file 是一个对象?对象可以直接调用成员函数?啊?Get-Date的返回值也是对象?啊?我不用管道了?

在 PowerShell 中,想要删除超过五天前的备份是如此的符合直觉,就像在高级语言中所需要做的那样:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
$count = 0
$backupfiles = Get-ChildItem -Path D:\Linca\Backups

foreach ($file in $backupfiles) {
if ($file.CreationTime -le (Get-Date).AddDays(-5)) {
try {
Write-Output "删除旧备份文件 $file 中……"
Write-Output ''
$file.Delete()
$count = $count + 1
} catch {
Write-Output "删除旧备份文件 $file 时发生了错误 >_<"
Write-Output '-------------------'
Write-Output $_
Write-Output '-------------------'
}
}
}

简简单单,获得了一个文件的Array,非常符合直觉的,遍历这个Array。非常面向对象的,调用 Delete() 函数而不是去新建一个进程来 rm。甚至出现异常的情况都可以直接 try-catch,简直不像脚本语言啊!

真是 太香啦!

附上 PowerShell Documention