Powershell指定函数的返回值 – PowerShell 中文博客
docker-containerd 占用大量内存
docker-containerd 占用约1GB内存,正常情况下不到100MB
powershell 之 foreach
原材料:
1 2 3 4 5 |
> $a=@("a", "b", "c") > $a a b c |
foreach有三种形态:
cmdlet形态,如下:
1 2 3 4 |
> $a|foreach {$_} a b c |
foreach 语句形态,如下:
1 2 3 4 |
PS /home/phpor> foreach($i in $a) {$i} a b c |
foreach方法形态,如下:
1 2 3 4 |
PS /home/phpor> $a.ForEach({$_}) a b c |
参考:
https://ss64.com/ps/foreach.html
https://ss64.com/ps/foreach-method.html
注意: foreach一般是看不到key的,如何才能看到key呢?
powershell之for循环
1 2 3 4 5 6 7 8 |
$alphabet = @() for ([byte]$c = [char]'A'; $c -le [char]'Z'; $c++) { $alphabet += [char]$c } [String]::Join(", ", $alphabet) |
1 2 3 4 5 |
> for($i=0;$i -lt 4;$i++) {$i;} 0 1 2 3 |
注意: 大小比较不能直接使用大于号、小于号
powershell 之 a-z
字符之 0~9:
1 2 3 4 5 6 7 8 9 10 11 |
0x30..0x39|foreach {[char]$_} 0 1 2 3 4 5 6 7 8 9 |
数字之0~9:
1 2 3 4 5 6 7 8 9 10 11 |
PS /home/phpor> 0..9 0 1 2 3 4 5 6 7 8 9 |
a~z :
1 2 3 |
$alph=@() 65..90|foreach-object{$alph+=[char]$_} $alph |
1 |
[char]'A'..[char]'D'|foreach {[char]$_} |
两个圆点的扩展需要是能计算出大小的字符(int或等价于int的char),毕竟shell中的单引号和双引号都是字符串,而不是字符,所以,单个字符需要显式转换为char,如下:
因为字符串可以取下标,取下标之后就是字符了,那么,可以如下写法:
1 2 3 4 5 |
'A'[0]..'D'[0] 65 66 67 68 |
如何再添加一个char的强制类型转换就可以输出字符了,如下:
1 2 3 4 5 |
[char[]]('A'[0]..'D'[0]) A B C D |
注意: 这个转换为的是字符数组(char[])而不是字符(char)哦
使用常规的for循环输出A~C:
1 2 3 4 |
> for($i=[int]'A'[0];$i -lt [int]'D'[0];$i++) {[char]$i;} A B C |
注意: ++ 运算只能用于number,不能用于char,所以,这里先转成int
Powershell 之split
如下脚本,通过where cmdlet过滤出来netstat中已连接状态的连接:
可以发现, 使用字符串的split选项可以凑效,但是,使用字符串的split方法不能凑效; 因为split选项支持正则分隔符,split方法不支持正则分隔符,其实第二种写法是不对的。split方法只能按照单个字符分隔
参考: https://msdn.microsoft.com/en-us/library/System.String.Split(v=vs.110).aspx
统计每种tcp状态的数量:
1 2 3 4 5 6 |
netstat -ant|select -Skip 2|foreach -Begin {$arr=@{}} {$state=($_ -split "[\s]+")[5] ; $arr[$state]++; } -End {$arr} Name Value ---- ----- LISTEN 2 ESTABLISHED 2 |
其中,begin、end都很类似awk的用法
改进: 如何按照名字的升序进行输出呢:
1 2 3 4 5 6 |
netstat -ant|select -Skip 2|foreach -Begin {$arr=@{}} {$state=($_ -split "[\s]+")[5] ; $arr[$state]++; } -End {$arr.GetEnumerator()|Sort-Object -Property name } Name Value ---- ----- ESTABLISHED 2 LISTEN 2 |
注意这里sort的使用,需要使用 GetEnumerator(), 因为$arr 本身是一个大对象,本没有迭代为多个对象输出,是不会被sort的,所以需要$arr.GetEnumerator() ,然后输出给sort
tips: sort的 -Property 可以不写,直接 sort name (或)sort value
格式化输出:
1 2 3 |
netstat -ant|select -Skip 2|foreach -Begin {$arr=@{}} {$state=($_ -split "[\s]+")[5] ; $arr[$state]++; } -End {$arr.GetEnumerator()|foreach {$_.name +":"+ $_.value} } LISTEN:2 ESTABLISHED:2 |
SysVinit vs Systemd
sysvinit 管理服务使用的是service命令,执行的是 /etc/init.d/{$script} 的逻辑;而systemd 使用的是systemctl来管理服务的。
我们如果在systemd系统上使用service命令(甚至直接执行 /etc/init.d/ 下的脚本)时,会提示自动重定向到systemctl来处理,其逻辑为:
service 为 initscripts 包中的命令,该包还包含了 /etc/rc.d/init.d/functions ,该functions提供了一些基础的函数,经常会被init.d 下的脚本包含; 在centos7上,initscripts 被做了手脚,service命令和functions里面都拦截命令的执行而重定向到systemctl,不过也可以通过环境变量SYSTEMCTL_SKIP_REDIRECT 来禁止重定向,脚本逻辑并不复杂;有时候,我们习惯使用 service 命令,还有时候,我们在docker容器里面使用systemctl总是没有权限,于是,借助环境变量SYSTEMCTL_SKIP_REDIRECT,依然执行 /etc/init.d 下的脚本而不去执行systemctl还是不错的