Dockerのコンテナを起動するとき、ID指定にpowershellの配列をそのまま渡せるとは、今更ながら。

Windows10 HOMEのpowershellにて、
名前がtest-1,test-2,test-3という3つのコンテナを作成し、停止した状態から起動させてみた。
コンテナの名前で絞り込んで(filter,-f)、quietオプション(-q)を付けてlsでIDを配列に取り込む。
※dockerコマンドのsyntaxは古いかもしれませんのでご注意・・・

PS >docker container ls -a -f name=test-.*
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS                     PORTS     NAMES
9bbd5b2256b6   nginx:1.17.6-alpine   "nginx -g 'daemon of… "   3 minutes ago   Exited (0) 2 minutes ago             test-3
34410af55b73   nginx:1.17.6-alpine   "nginx -g 'daemon of… "   3 minutes ago   Exited (0) 2 minutes ago             test-2
d892fccc011b   nginx:1.17.6-alpine   "nginx -g 'daemon of… "   3 minutes ago   Exited (0) 3 minutes ago             test-1
PS >$c = docker container ls -a --quiet -f name=test-.*
PS >$c
9bbd5b2256b6
34410af55b73
d892fccc011b
PS >docker container start $c
9bbd5b2256b6
34410af55b73
d892fccc011b
PS >docker container ls
CONTAINER ID   IMAGE                 COMMAND                  CREATED         STATUS         PORTS                  NAMES
9bbd5b2256b6   nginx:1.17.6-alpine   "nginx -g 'daemon of… "   5 minutes ago   Up 9 seconds   0.0.0.0:8093->80/tcp   test-3
34410af55b73   nginx:1.17.6-alpine   "nginx -g 'daemon of… "   5 minutes ago   Up 8 seconds   0.0.0.0:8092->80/tcp   test-2
d892fccc011b   nginx:1.17.6-alpine   "nginx -g 'daemon of… "   5 minutes ago   Up 8 seconds   0.0.0.0:8091->80/tcp   test-1
PS >docker container stop $c
9bbd5b2256b6
34410af55b73
d892fccc011b
PS >stop-transcript

コンテナを作成したときのスクリプト

$port = 8090
foreach ( $i in 1..3 ){
    $port ++
    $name = 'test-' + $i
    $cmd = "docker run -d -it --name $name -p ${port}:80 nginx:1.17.6-alpine"
    invoke-expression $cmd
}

enter-pssesssionで他のPCに入りコンテナを起動して、exec -it でコンテナの中に入ろうとしたが、PSRemotingではコンテナの中には入れなかった。
コンテナの中に入れないのでは、面倒だが外からコマンドを発行するしかない。

docker container start ubun2
$c = docker container ls -q
$d = get-date -format 'yyyyMMdd'
$f = $d + '.log'
docker container exec -d $c bash -c "/home/guest/app2/server.py > /tmp/${f} 2>&1"

dettachの'-d'をつけ忘れたらpowershellの端末を奪われてしまった。
未だに見まねで使っているレベル、要注意。

【つぶやき】Windowsのftp.exeはpassive modeをサポートしていないのだろうか?

Windowsftp.exeはpassive modeをサポートしていないのだろうか?
Bingで'ftp.exe passive mode'を検索すると、ftp.exeはサポートされていないという情報が結構あるのだが、
localhostIISFTPサイトを作って試してみると、サポートされているように見えてしまう。

なおFTPサイトの作成は以下の記事を参照した。
www.chuken-engineer.com

PS >ftp
ftp> open localhost
XXXXXX に 接 続 し ま し た 。 
220 Microsoft FTP Service
200 OPTS UTF8 command successful - UTF8 encoding now ON.
ユ ー ザ ー  (XXXXXX:(none)): ftpuser
331 Password required
パ ス ワ ー ド :
230 User logged in.
ftp> put aaa.txt
200 EPRT command successful.
125 Data connection already open; Transfer starting.
226 Transfer complete.
ftp: 1928 バ イ ト が 送 信 さ れ ま し た  0.001928000.00KB/秒 。 
ftp> quote epsv
229 Entering Extended Passive Mode (|||60003|)
ftp> put aaa.txt
200 EPRT command successful.
150 Opening ASCII mode data connection.
425 Cannot open data connection.
ftp> bye
221 Goodbye.
PS >stop-transcript

'quote epsv'のあと'229 Entering Extended Passive Mode'と表示されているので変更されているように見えるのだが、どうなのだろう。
ポート番号60003は開けていないので失敗しているが、
セキュリティソフトNortonでのport開け方が良く分からなかったので、危険を冒すのはやめておいた。
気のせいなのだろうか?Windows標準のftpだよなあ?違うのかな?

PS >get-command ftp

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Application     ftp.exe                                            10.0.19... C:\WINDOWS\system32\ftp.exe


PS >

OSはWindows10 HOME (21H2 Version: 10.0.19044)
もうすぐ、22H2だなあ。

【完全に備忘録】scコマンドでwinrmサービスの状況を調べる

winrmサービスが開始されているのかや起動設定がどうなっているのかを確認したいことがときどきあるが、すぐ忘れてしまうのでメモ。
learn.microsoft.com

普段、powershellを使用しているが,powershellではscはset-contentのエイリアスなのでうまく動作しないということをネットで知り、cmdを打ってから作業。

PS >cmd
Microsoft Windows [Version 10.0.19044.2006]
(c) Microsoft Corporation. All rights reserved.

D:\tmp>sc query  winrm

SERVICE_NAME: winrm
        TYPE               : 30  WIN32
        STATE              : 4  RUNNING
                                (STOPPABLE, NOT_PAUSABLE, ACCEPTS_SHUTDOWN)
        WIN32_EXIT_CODE    : 0  (0x0)
        SERVICE_EXIT_CODE  : 0  (0x0)
        CHECKPOINT         : 0x0
        WAIT_HINT          : 0x0

D:\tmp>sc qc winrm
[SC] QueryServiceConfig SUCCESS

SERVICE_NAME: winrm
        TYPE               : 20  WIN32_SHARE_PROCESS
        START_TYPE         : 2   AUTO_START  (DELAYED)
        ERROR_CONTROL      : 1   NORMAL
        BINARY_PATH_NAME   : C:\WINDOWS\System32\svchost.exe -k NetworkService -p
        LOAD_ORDER_GROUP   :
        TAG                : 0
        DISPLAY_NAME       : Windows Remote Management (WS-Management)
        DEPENDENCIES       : RPCSS
                           : HTTP
        SERVICE_START_NAME : NT AUTHORITY\NetworkService

D:\tmp>exit
PS >stop-transcript

netコマンドを使うと以下のような感じか。

PS >net start | sls ws-management

   Windows Remote Management (WS-Management)

scコマンドとnetコマンドの違いについては以下を参照方。
(私には理解するための知識が欠けていますが・・・)
ryoichi0102.hatenablog.com

2022-10-08 p.s.

稼働確認ならget-serviceコマンドレットでも行えるようだ。こちらの方が標準的なのかな。
PSRemotingを使用していないのでPSRemotingの設定をしていないremote computerに対しても調べることができるようだ。
PS >get-service "win*"

Status   Name               DisplayName
------   ----               -----------
Stopped  WinDefend          Microsoft Defender Antivirus Service
Running  WinHttpAutoProx... WinHTTP Web Proxy Auto-Discovery Se...
Running  Winmgmt            Windows Management Instrumentation
Running  WinRM              Windows Remote Management (WS-Manag...

IISとは「World Wide Web 発行サービス」であるようだが、netコマンドとpowershellのwebsiteコマンドレットとではちょっと挙動が違ってた、クソどうでもいいことだが。

Microsoft Internet Information Services

net startで表示されるサービス名の中でIISのサービス名なのか見当がつかなかったので、
World Wide Web 発行サービス」を起動、停止を試してみた。
いつもはIISマネージャーかpowershellのget-website, start-website, stop-websiteコマンドレットを使っているが、
停止しているときはstateは通常'Stopped'となるが、netコマンドで停止させるとstateが空白となった。

PS >net stop 'World Wide Web 発行サービス'
World Wide Web 発行サービス サービスを停止中です.
World Wide Web 発行サービス サービスは正常に停止されました。

PS >get-website 'default web site'

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Default Web Site 1               %SystemDrive%\inetpub\wwwroot  http *:80:
                                                                https *:443: sslFlags=0


PS >net start 'World Wide Web 発行サービス'
World Wide Web 発行サービス サービスを開始します.
World Wide Web 発行サービス サービスは正常に開始されました。

PS >get-website 'default web site'

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Default Web Site 1    Started    %SystemDrive%\inetpub\wwwroot  http *:80:
                                                                https *:443: sslFlags=0


PS >stop-website 'default web site'
PS >get-website 'default web site'

Name             ID   State      Physical Path                  Bindings
----             --   -----      -------------                  --------
Default Web Site 1    Stopped    %SystemDrive%\inetpub\wwwroot  http *:80:
                                                                https *:443: sslFlags=0

まあ、「クソどうでもいい」ことだが。

Let's try Qiita API v2 via curl of powershell

powershellcurlでQiita APIを使ってみました。
何かしら参考になればと思い投稿します。
(Qiita側からすると規約違反になるのだろうか?markdown記法の知識がないのでQiitaには内容不明な投稿になってしまいました。)

PS >$url = 'https://qiita.com/api/v2/items?page=1&per_page=10'
PS >$r = curl -URI $url
PS >$r | get-member

   TypeName: Microsoft.PowerShell.Commands.HtmlWebResponseObject

Name              MemberType Definition
----              ---------- ----------
Dispose           Method     void Dispose(), void IDisposable.Dispose()
Equals            Method     bool Equals(System.Object obj)
GetHashCode       Method     int GetHashCode()
GetType           Method     type GetType()
ToString          Method     string ToString()
AllElements       Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection AllElements {get;}
BaseResponse      Property   System.Net.WebResponse BaseResponse {get;set;}
Content           Property   string Content {get;}
Forms             Property   Microsoft.PowerShell.Commands.FormObjectCollection Forms {get;}
Headers           Property   System.Collections.Generic.Dictionary[string,string] Headers {get;}
Images            Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Images {get;}
InputFields       Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection InputFields {get;}
Links             Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Links {get;}
ParsedHtml        Property   mshtml.IHTMLDocument2 ParsedHtml {get;}
RawContent        Property   string RawContent {get;set;}
RawContentLength  Property   long RawContentLength {get;}
RawContentStream  Property   System.IO.MemoryStream RawContentStream {get;}
Scripts           Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Scripts {get;}
StatusCode        Property   int StatusCode {get;}
StatusDescription Property   string StatusDescription {get;}

PS >$r
StatusCode        : 200
StatusDescription : OK
Content           : [{"rendered_body":"\u003cp data-sourcepos=\"1:1-5:19\"\u003e始めての投稿\u003cbr\u003e\n「良い記事を書くには」道のりが長そうだ。markdown
                    って何?\u003cbr\u003e\nPS \u0026gt;$url = '\u003ca href=\"https://qiita.com/api/v2/items?page...
RawContent        : HTTP/1.1 200 OK
                    Transfer-Encoding: chunked
                    Connection: keep-alive
                    X-Frame-Options: SAMEORIGIN
                    X-XSS-Protection: 1; mode=block
                    X-Content-Type-Options: nosniff
                    X-Download-Options: noopen
                    X-Permit...
Forms             : {}
Headers           : {[Transfer-Encoding, chunked], [Connection, keep-alive], [X-Frame-Options, SAMEORIGIN], [X-XSS-Protection, 1; mode=block]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 3008491

PS >$c = ($r.content | convertfrom-json )
PS >$i = 0
PS >foreach ( $a in $c ){ Write-Host "[${i}]"  ${a}.title; $i ++ }
[0] Let's try Qiita api v2 via curl of powershell
...

仕様に関しては以下のリンクを参照方。
APIを活用しようとするにせよ学習のコストが求められるのは仕方ないのだろうか?
qiita.com
タイトルを表示するスクリプトだと以下のようなものになるのだろうか。

$url = 'https://qiita.com/api/v2/items?page=1&per_page=10'
$r = curl -URI $url
$c = ($r.content | convertfrom-json )
$i = 0
foreach ( $a in $c ){
    Write-Host "[${i}]"  ${a}.title
    $i ++
}

近年話題のAIを活用する以前にAPIを活用できない自分にもどかしい。
要するにITを活用できないだけなのだが・・・でもITを活用するなんて結構難しいでぇ。
しかし活用するにしても何がしたいのだろうか?(独語)

PowerShellにcurlがあることを知らなかった

powershellにもcurlがあることを知り試してみた。
curlInvoke-WebRequestのAliasで以下のページを参考にした。
といってもURIオプションしか参考にしていないが・・・
docs.microsoft.com
以下のようなJSONデータを返す自前で用意したPHPのページへリクエストを出してみた。

[
{
"id":1,
"code":"001",
"title":"一流の言いかえ−「ふつうの人」を「品のいい人」に変える−",
"publisher":"光文社",
"year":"2022"
},
{
"id":2,
"code":"001",
"title":"老いの品格−品よく、賢く、おもしろく−(PHP新書 1310)",
"publisher":"PHP研究所",
"year":"2022"
},
{
"id":3,
"code":"001",
"title":"「させていただく」の使い方−日本語と敬語のゆくえ−(角川新書 K−381)",
"publisher":"KADOKAWA",
"year":"2022"
}
]
powershellcurlでリクエストしたときのtranscript
PS >get-command curl

CommandType     Name                                               Version    Source
-----------     ----                                               -------    ------
Alias           curl -> Invoke-WebRequest


PS >$r = curl -URI http://localhost/php/sqlite3json_newbook.php

PS >$r.gettype()

IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     False    HtmlWebResponseObject                    Microsoft.PowerShell.Commands.WebResponseObject


PS >$r | get-member


   TypeName: Microsoft.PowerShell.Commands.HtmlWebResponseObject

Name              MemberType Definition
----              ---------- ----------
Dispose           Method     void Dispose(), void IDisposable.Dispose()
Equals            Method     bool Equals(System.Object obj)
GetHashCode       Method     int GetHashCode()
GetType           Method     type GetType()
ToString          Method     string ToString()
AllElements       Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection AllElements {get;}
BaseResponse      Property   System.Net.WebResponse BaseResponse {get;set;}
Content           Property   string Content {get;}
Forms             Property   Microsoft.PowerShell.Commands.FormObjectCollection Forms {get;}
Headers           Property   System.Collections.Generic.Dictionary[string,string] Headers {get;}
Images            Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Images {get;}
InputFields       Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection InputFields {get;}
Links             Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Links {get;}
ParsedHtml        Property   mshtml.IHTMLDocument2 ParsedHtml {get;}
RawContent        Property   string RawContent {get;set;}
RawContentLength  Property   long RawContentLength {get;}
RawContentStream  Property   System.IO.MemoryStream RawContentStream {get;}
Scripts           Property   Microsoft.PowerShell.Commands.WebCmdletElementCollection Scripts {get;}
StatusCode        Property   int StatusCode {get;}
StatusDescription Property   string StatusDescription {get;}


PS >$r


StatusCode        : 200
StatusDescription : OK
Content           : [{"id":1,"code":"001","title":"一流の言いかえ−「ふつうの人」を「品のいい人」に変える−","publisher":"光文社","year":"2022"},{"id":2,"code":"001","title"
                    :"老いの品格−品よく、賢く、おもしろく−(PHP新書 1310)","publisher":"PHP研究所","year":"2022"},{"id":3...
RawContent        : HTTP/1.1 200 OK
                    Content-Length: 522
                    Content-Type: application/json; charset=utf-8
                    Date: Mon, 12 Sep 2022 06:18:51 GMT
                    Server: Microsoft-IIS/10.0
                    X-Powered-By: PHP/8.0.11

                    [{"id":1,"code":"001",...
Forms             : {}
Headers           : {[Content-Length, 522], [Content-Type, application/json; charset=utf-8], [Date, Mon, 12 Sep 2022 06:18:51 GMT], [Server, Microsoft-IIS/10.0]...}
Images            : {}
InputFields       : {}
Links             : {}
ParsedHtml        : mshtml.HTMLDocumentClass
RawContentLength  : 522



PS >$c = ( $r.content | convertfrom-json )

PS >$c


id        : 1
code      : 001
title     : 一流の言いかえ−「ふつうの人」を「品のいい人」に変える−
publisher : 光文社
year      : 2022

id        : 2
code      : 001
title     : 老いの品格−品よく、賢く、おもしろく−(PHP新書 1310)
publisher : PHP研究所
year      : 2022

id        : 3
code      : 001
title     : 「させていただく」の使い方−日本語と敬語のゆくえ−(角川新書 K−381)
publisher : KADOKAWA
year      : 2022



PS >$psversiontable

Name                           Value
----                           -----
PSVersion                      5.1.19041.1682
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.1682
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


PS >stop-transcript
PHPのページのコード
<?php
header("Content-Type: application/json; charset=utf-8");
$file = 'db/newbook.sqlite';
$db = new SQLite3($file);
$sql = "SELECT * FROM book order by id limit 3";
$result = $db->query($sql);

while($res = $result->fetchArray(SQLITE3_ASSOC)){
    $h[] = array('id'=>$res['id'],'code'=>$res['code'],'title'=>$res['title'],'publisher'=>$res['publisher'],'year'=>$res['year']);
}
$db = null;
$js =json_encode($h, JSON_UNESCAPED_UNICODE);
print_r($js);

『安いニッポン「価格」が示す停滞』中藤玲 (c)2021

港区の年平均所得1200万円はサンフランシスコでは「低所得」

港区の年平均所得1200万円はサンフランシスコでは「低所得」に分類されるらしい?
「低所得」に分類されたことも驚きだが港区の年平均所得1200万円ということの方が私にとっては驚きであった。
「じゃー、港区に引っ越ししようか!」と引っ越したところで所得が上がることはないのでやめておこう。
まあ、サンフランシスコも別世界だが港区も縁のない世界なので、そのような世界のことは気にしないでおこう!

賃金の停滞

「日本の賃金はこの30年間全く成長していない」(矢代尚宏)、日本だけが低賃金なのはなぜなのだろう?

ということが挙げられていた。

労働生産性ということに関して野村證券金融経済研究所の許斐潤(このみじゅん)所長がドイツに赴任したときの印象が面白い。実際にドイツに行ってみたところ、「ドイツ人は全然働かないように見えた」という。これではとても「生産性大国」とは思えないが、モノが日本より高いので金額ベースではドイツの方が生産性が高いということになるみたいだ。

許斐所長は「ヨーロッパで5倍の時間をかけて作った車も10倍の価格で売れば、金額の生産性は2倍になる。それこそがドイツの生産性の高さだった」と分析する。

物価が高いから生産性が高く賃金が高いのね?うーん、鶏と卵みたいな話で訳が分からなくなってしまう。
ただ、これは許斐氏がドイツに赴任した30年前の印象や分析である。今でも本質的には正しい指摘ではあると思うが「途上国化」しつつある国の視点から見てみよう。
高級車の組み立て工場における生産性は日本が約17時間でヨーロッパは37時間から111時間というので「組み立て」の工程では日本の方が生産性が高いと言えよう。
ただ、車は走る半導体と言われるほどなので擦り合わせ技術中心の生産からモジュール型生産へ移行してからは、電気自動車ではなおさら半導体やソフトウェアの生産性がカギを握るようになってきたので「組み立て」以外の工程での生産性に注意する必要があるのではないだろうか。
なので本当はテスラなどをベンチマークの対象にした方が分かりやすいのかもしれないが、本書では触れられていなかった。が、さすがにこの領域に踏み込む分析を期待するのは虫が良すぎる。

外国の高度人材の獲得でも苦戦

賃金の停滞する日本では企業も外国の高度人材の獲得でも苦戦しているようだ。

ある日本の著名スタートアップ幹部は、IIT(インド工科大学)人材を渇望する。
以前同社のインターンに参加したIIT出身者が、自社アプリの使い勝手を良くするプログラミングで抜群の実績を残したのだ。
「こんなにも違うものかと驚いた」
だが彼は年収1700万円を出したアマゾンに入社してしまった。

インド人技術者を大量採用できた企業も、単純な作業しか任せなかったため退職が相次ぐことになるなど定着させるのに問題を抱えているようだ。
メンバーシップ型雇用は外国人には異様に映るというから、ジョブ型に転換しないと定着は難しいのだろう。
ただ、形だけジョブ型にしても不透明な評価基準が残るとグローバルな転職市場では通用しないとの忠告もあるくらいだから、道のりはかなり険しそうだ。

『途上国化する日本』もそうだったが、本書を読み終えると暗い思いになってしまう。
まあ、個人としては置かれた状況の中で努力するしかないのかな。

www.itmedia.co.jp