ゼロ幅スペースの謎を解く

ゼロ幅スペース(Zero Width Space, ZWSP)とは?

ゼロ幅スペース - Wikipedia

によれば、

  • コンピュータの組版に用いられる非表示文字で、文書処理システムに対して語の切れ目を示すのに用いる。
  • HTMLでは要素の代替として、長い単語の途中で改行可能な場所を示すのに使われる。

例として、以下の文字列では、キャメルケースの単語間には、ZWSPがそれぞれ入っている(非表示のため目には見えない)

Lorem​Ipsum​Dolor​Sit​Amet​Consectetur​Adipiscing​Elit​Sed​Do​Eiusmod​Tempor​Incididunt​Ut​Labore​Et​Dolore

Vimで開くと以下のように見える

Lorem<200b>Ipsum<200b>Dolor<200b>Sit<200b>Amet<200b>Consectetur<200b>Adipiscing<200b>Elit<200b>Sed<    200b>Do<200b>Eiusmod<200b>Tempor<200b>Incididunt<200b>Ut<200b>Labore<200b>Et<200b>Dolore

このなぞの「<200b>」がZWSPである。

<200b>は何のコードか

<200b>は「ゼロ幅スペース」のUnicodeである。

Unicode Character Table

をみると、<200b>のUTF-8での16進数は「E2 80 8B」である。

バイナリエディタでみてみる

それでは、文字列

Lorem​Ipsum​Dolor​Sit​Amet​Consectetur​Adipiscing​Elit​Sed​Do​Eiusmod​Tempor​Incididunt​Ut​Labore​Et​Dolore

バイナリエディタで16進数をdumpしてみる

$ echo "Lorem​Ipsum​Dolor​Sit​Amet​Consectetur​Adipiscing​Elit​Sed​Do​Eiusmod​Tempor​Incididunt​Ut​Labore​Et​Dolore" | od -t x1

0000000 4c 6f 72 65 6d e2 80 8b 49 70 73 75 6d e2 80 8b
0000020 44 6f 6c 6f 72 e2 80 8b 53 69 74 e2 80 8b 41 6d
0000040 65 74 e2 80 8b 43 6f 6e 73 65 63 74 65 74 75 72
(省略)

テキストファイルから<200b>文字を削除する

ファイルをvimで開いて、

:%s/\%u200b//g

これで、ファイル内すべての<200b>を削除できる。

vim以外の方法で、sedなどいろいろ試してみたが、うまく行かず諦めた。。

<200b>のコピペ

コピーについては、以下の資料を参考にうまく行けた。

unicodeでU+200B;幅なしスペース(幅が0)という文字があるん... - Yahoo!知恵袋

まず、文字幅0のスペースの左側に文字カーソルを置きます。 次に、Shift+→ で文字幅0のスペースを選択します。 (ただし、反転表示されないので、選択されたかどうか解り難いです)
Ctrl+C でコピー
Ctrl+V で貼り付け

<200b>の入力

あくまでもMacしか試していないので、Windowsの方はもっといろいろな方法があるかもしれない。

ChromeのConsoleから

Consoleを開いて、copy("\u200B")を打てば文字がクリップボードに入ったため、後はペストすればいい。 個人的にこの方法が好き。

Unicode Character Table から

Unicode Character Table から「Copy」ボタンを押せばコピーされ、後はペストすればいい。

coolsymbol.comから

Symbols に色々なシンボルがあり、画面下部に「Zero-Width Space (ZWSP) Character」あるので、コピーして後はペストすればいい。

普段仕事上めったに<200b>にあうことはないが、自分は今日仕事上遭ったため、調べてブログにした。 インターネット上で調べている方のいい参考になれればと思います。

参考資料

screwdriver.cdを使ってローカルでビルド

環境

macOS Catalina

前提

  • Docker Desktop がインストールされている
  • git コマンドが使える

手順

screwdriverクラスタをローカルに起動させる

$ python <(curl -L https://git.io/sd-in-a-box)
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
  0     0    0     0    0     0      0      0 --:--:-- --:--:-- --:--:--     0
100  9392  100  9392    0     0   7120      0  0:00:01  0:00:01 --:--:--  7120
🎁   Boxing up Screwdriver
👀   Checking prerequisites
🔐   Generating signing secrets
📤   Which SCM provider would you like to use? (github/gitlab/bitbucket) github
📦   Generating OAuth credentials

    Please create a new OAuth application on GitHub.com
    Go to https://github.com/settings/applications/new to start the process
    For 'Homepage URL' put http://192.168.0.2:9000
    For 'Authorization callback URL' put http://192.168.0.2:9001/v4/auth/login

    When done, please provide the following values:

    Client ID: 9baf4ee73bcbd1110a04
    Client Secret:

💾   Writing Docker Compose file
🚀   Screwdriver is ready to launch!

    Just run the following commands to get started!
      $ docker-compose pull
      $ docker-compose -p screwdriver up -d
      $ open http://192.168.0.2:9000

    Would you like to run them now? (y/n) y
Pulling api   ... done
Pulling ui    ... done
Pulling store ... done
Creating network "screwdriver_default" with the default driver
Creating screwdriver_store_1 ... done
Creating screwdriver_api_1   ... done
Creating screwdriver_ui_1    ... done

👍   Launched!

    A few more things to note:
      - To stop/reset Screwdriver
        $ docker-compose -p screwdriver down
      - If your internal IP changes, update the docker-compose.yml and your SCM OAuth application
      - In-a-box does not support Webhooks including PullRequests for triggering builds
      - To create your own cluster, see https://docs.screwdriver.cd/cluster-management/kubernetes
      - For help with this and more, find us on Slack at https://slack.screwdriver.cd

❤️   Screwdriver Crew

ui が立ち上がった。

screwdriver

Sign in with SCM Provider」リンクをクリックすると、以下のように権限認可画面が出る Authorize

状況確認

コンテナ
$ docker ps -a
CONTAINER ID        IMAGE                              COMMAND                  CREATED              STATUS                           PORTS                            NAMES
b42f1bb49d9f        screwdrivercd/ui:stable            "nginx -g 'daemon of…"   About a minute ago   Up About a minute                0.0.0.0:9000->80/tcp             screwdriver_ui_1
e18174d2bac6        screwdrivercd/screwdriver:stable   "docker-entrypoint.s…"   About a minute ago   Up About a minute                8080/tcp, 0.0.0.0:9001->80/tcp   screwdriver_api_1
eb1b350f4355        screwdrivercd/store:stable         "docker-entrypoint.s…"   About a minute ago   Up About a minute                0.0.0.0:9002->80/tcp             screwdriver_store_1
af6b538f8bee        centos:centos8                     "/sbin/init"             7 days ago           Exited (137) About an hour ago
イメージ
$ docker images
REPOSITORY                  TAG                 IMAGE ID            CREATED             SIZE
centos                      centos8             0d120b6ccaa8        2 months ago        215MB
screwdrivercd/screwdriver   stable              bfc1a62afe5a        5 months ago        1.05GB
screwdrivercd/ui            stable              321c51c4e647        5 months ago        25.8MB
screwdrivercd/store         stable              692bb501be06        8 months ago        1.02GB

screwdrivercdだけで合計2GB以上もある。。

コンテナを停止

$ docker-compose -p screwdriver down
Stopping screwdriver_ui_1    ... done
Stopping screwdriver_api_1   ... done
Stopping screwdriver_store_1 ... done
Removing screwdriver_ui_1    ... done
Removing screwdriver_api_1   ... done
Removing screwdriver_store_1 ... done
Removing network screwdriver_default

コンテナ再確認

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND             CREATED             STATUS                      PORTS               NAMES
af6b538f8bee        centos:centos8      "/sbin/init"        29 hours ago        Exited (137) 25 hours ago                       centos8

メモ:コンテナ起動

$ docker-compose -p screwdriver up

Get Started

Getting Started with Screwdriver を参考し

$ git clone git@github.com:<YOUR_USERNAME_HERE>/quickstart-generic.git
$ cd quickstart-generic/
screwdriver.yaml

サンプルのscrewdriver.yamlにはコメント行が沢山あり、見づらいため、

$ sed -e '/^[\t ]*#/d' screwdriver.yaml 
---
shared:
  image: buildpack-deps

jobs:
  main:
    requires: [~pr, ~commit]
    steps:
      - export: export GREETING="Hello, world!"
      - hello: echo $GREETING
      - set-metadata: meta set example.coverage 99.95
  second_job:
    requires: main
    steps:
      - make_target: make greetings
      - get-metadata: meta get example
      - run_arbitrary_script: ./my_script.sh

でコメント行を除外して表示した。

Create a New Pipeline

screwdriver.cdのuiから、SCM(githubを選択していた)にログインして(OAuth認証)、Create Pipelineする。
下図にある[my_github_accoutn]部分は、実際に自分のアカウントが入る。 pipeline

Startボタンを押してビルド開始。 Start to build

以下のエラーが出てしまった

 (HTTP code 404) no such container - No such image: screwdrivercd/launcher:stable

参考資料

Install CentOS8 through Docker on macOS

概要

macOS Catalina上で、Dockerで以下の仮想環境を構築する:

手順

準備

Docker Desktop Community 2.4.0.0をインストール

$ docker version
Client: Docker Engine - Community
 Cloud integration  0.1.18
 Version:           19.03.13
 API version:       1.40
 Go version:        go1.13.15
 Git commit:        4484c46d9d
 Built:             Wed Sep 16 16:58:31 2020
 OS/Arch:           darwin/amd64
 Experimental:      false

Server: Docker Engine - Community
 Engine:
  Version:          19.03.13
  API version:      1.40 (minimum version 1.12)
  Go version:       go1.13.15
  Git commit:       4484c46d9d
  Built:            Wed Sep 16 17:07:04 2020
  OS/Arch:          linux/amd64
  Experimental:     false
 containerd:
  Version:          v1.3.7
  GitCommit:        8fba4e9a7d01810a393d5d25a3621dc101981175
 runc:
  Version:          1.0.0-rc10
  GitCommit:        dc9208a3303feef5b3839f4323d9beb36df0a9dd
 docker-init:
  Version:          0.18.0
  GitCommit:        fec3683

どのようなDockerイメージがあるかを調べるには、docker hub から探せばいい。

CentOS8のイメージをDocker Hubから取得

$ docker pull centos:centos8
centos8: Pulling from library/centos
3c72a8ed6814: Pull complete
Digest: sha256:76d24f3ba3317fa945743bb3746fbaf3a0b752f10b10376960de01da70685fbd
Status: Downloaded newer image for centos:centos8
docker.io/library/centos:centos8

コンテナを作成して起動

コンテナの名前を「centos8」を指定し、コンテナのポート8080をホストの80ポートにバウンドさせて、バックグランドで起動する。

$ docker run --detach --name centos8 --privileged --publish=80:8080 centos:centos8 /sbin/init
af6b538f8beed2885d695f72ba0c29c0c00332f1dcb4787989f71105f622d3dc

Docker-docs-ja に各オプションの説明があります。

すべてのコンテナを表示してみる

$ docker ps -a
CONTAINER ID        IMAGE               COMMAND                  CREATED             STATUS                     PORTS               NAMES
af6b538f8bee        centos:centos8      "/sbin/init"              2 minutes ago       Up About a minute                      centos8
2fc5923004a3        hello-world         "/hello"                 22 hours ago        Exited (0) 22 hours ago                        gracious_euclid
5458576feea9        alpine/git          "git clone https://g…"   25 hours ago        Exited (0) 25 hours ago                        repo

昨日にDocker Desktopを入れた時にお試しに作ったコンテナが存在しているので、削除してみる。

コンテナを削除する

コンテナ削除のコマンド:docker rm [コンテナID](コンテナIDはspace区切りで複数指定してもOK)

やってみる

$ docker rm 2fc5923004a3 5458576feea9
2fc5923004a3
5458576feea9

削除後、$ docker ps -aで確認すると、centos:centos8だけ残っていることが確認できた。

イメージを削除する

まずはイメージの一覧をみる

$ docker images
REPOSITORY          TAG                 IMAGE ID            CREATED             SIZE
alpine/git          latest              94f8849864da        3 weeks ago         28.4MB
centos              centos8             0d120b6ccaa8        2 months ago        215MB
hello-world         latest              bf756fb1ae65        9 months ago        13.3kB

イメージを削除するコマンド:docker rmi [イメージID](イメージIDもspace区切りで複数指定してOK)

$ docker rmi 94f8849864da bf756fb1ae65
Untagged: alpine/git:latest
Untagged: alpine/git@sha256:9e2309b689ac74257941b0f7b72d8d34c9e94216806eed047338eb39e3b90c58
Deleted: sha256:94f8849864daf55267c12512ff521931842cd707adfde019d86e2d41179ae9e2
Deleted: sha256:c044252e47e67929e158bee2fbf759460445f256ee3376474abac9efd3af5f35
Deleted: sha256:d59fd62de84f6d6ca50712ef1e18ebd451ec306711c0270ba9efba28e6fe462e
Deleted: sha256:50644c29ef5a27c9a40c393a73ece2479de78325cae7d762ef3cdc19bf42dd0a
Untagged: hello-world:latest
Untagged: hello-world@sha256:8c5aeeb6a5f3ba4883347d3747a7249f491766ca1caa47e5da5dfcf6b9b717c0
Deleted: sha256:bf756fb1ae65adf866bd8c456593cd24beb6a0a061dedf42b26a993176745f6b
Deleted: sha256:9c27e219663c25e0f28493790cc0b88bc973ba3b1686355f221c38a36978ac63

コンテナを起動する

$  docker start centos8
centos8

コンテナに接続して確認

docker exec コマンドを使用して、起動したコンテナ内にて bash シェルを実行する。

$ docker exec -it centos8 bash
[root@af6b538f8bee /]#  ← 接続できた!
root@af6b538f8bee /]# cat /etc/redhat-release
CentOS Linux release 8.2.2004 (Core)  ← CentOS8 がインストールされている
[root@af6b538f8bee /]# cat /etc/os-release
NAME="CentOS Linux"
VERSION="8 (Core)"
ID="centos"
ID_LIKE="rhel fedora"
VERSION_ID="8"
PLATFORM_ID="platform:el8"
PRETTY_NAME="CentOS Linux 8 (Core)"
ANSI_COLOR="0;31"
CPE_NAME="cpe:/o:centos:centos:8"
HOME_URL="https://www.centos.org/"
BUG_REPORT_URL="https://bugs.centos.org/"

CENTOS_MANTISBT_PROJECT="CentOS-8"
CENTOS_MANTISBT_PROJECT_VERSION="8"
REDHAT_SUPPORT_PRODUCT="centos"
REDHAT_SUPPORT_PRODUCT_VERSION="8"

シェアから抜く

[root@af6b538f8bee /]# exit
exit

コンテナを停止する

$  docker stop centos8
centos8

停止まで十数秒かかった気がする。

コンテナに入れたいものを入れる

CentOS8になってから、システムが利用する python のバージョンも python3 系に上がっているため、phthon2 で書かれている yum が廃止せざるを得なくなった。 また、もともと yum にはいろいろ欠陥があり、dnf はそれを改善されるようになったこともあるらしい。

vim

# dnf install vim
~~(省略)~~
# # vim --version
VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Nov 11 2019 19:08:24)

nginx

# dnf install nginx
~~(省略)~~
Complete!

デフォルトでは80/tcpで開放されているため、コンテナ起動時にバウンドさせていた8080/tcpに変更する。

# ls -l  /etc/nginx/conf.d/default.conf ← ファイルが存在しないことを確認した
# cat << EOF > /etc/nginx/conf.d/default.conf
server {
    listen       8080;
    server_name  localhost;
}
EOF

nginxをコンテナ接続時に起動ようにする

# systemctl enable nginx
Created symlink /etc/systemd/system/multi-user.target.wants/nginx.service → /usr/lib/systemd/system/nginx.service.

nginxを起動させる

# systemctl start nginx
# ps auxww | grep nginx
root         226  0.0  0.1 103328  2184 ?        Ss   12:31   0:00 nginx: master process /usr/sbin/nginx
nginx        227  0.0  0.3 122628  8004 ?        S    12:31   0:00 nginx: worker process
nginx        228  0.0  0.3 122628  8004 ?        S    12:31   0:00 nginx: worker process
root         230  0.0  0.0   9180   992 pts/0    S+   12:31   0:00 grep --color=auto nginx

コンテナ内でnginxサーバにアクセスしてみる

# curl -D - -s  -o /dev/null http://localhost
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Sun, 18 Oct 2020 12:49:29 GMT
Content-Type: text/html
Content-Length: 4057
Last-Modified: Mon, 07 Oct 2019 21:16:24 GMT
Connection: keep-alive
ETag: "5d9bab28-fd9"
Accept-Ranges: bytes

ホストOS(macOS)にてブラウザからコンテナのngnixサーバにアクセスしてみる http://localhost

画像

ついでに、index.html をいじってみる

# cd /usr/share/nginx/html
# mv index.html index.html.org
# cat << EOF > index.html
<html>
<body>
Hello, World!
</body>
</html>
EOF
# curl -i http://localhost:8080
HTTP/1.1 200 OK
Server: nginx/1.14.1
Date: Sun, 18 Oct 2020 15:11:37 GMT
Content-Type: text/html
Content-Length: 44
Last-Modified: Sun, 18 Oct 2020 15:11:06 GMT
Connection: keep-alive
ETag: "5f8c5b0a-2c"
Accept-Ranges: bytes

<html>
<body>
Hello, World!
</body>
</html>

python3

python3系だけあればいいかな。

# dnf install  python3 python3-pip
CentOS-8 - AppStream                                    5.0 kB/s | 4.3 kB     00:00
~~(省略)~~
Installed:
  platform-python-pip-9.0.3-16.el8.noarch
  python3-pip-9.0.3-16.el8.noarch
  python3-setuptools-39.2.0-5.el8.noarch
  python36-3.6.8-2.module_el8.1.0+245+c39af44f.x86_64

Complete!
#
# python3 -V
Python 3.6.8

pip3でnumpy、matplotlib、scrapy、requestをインストールする。

# pip3 install numpy matplotlib scrapy requests
(省略)
# python3
Python 3.6.8 (default, Apr 16 2020, 01:36:27)
[GCC 8.3.1 20191121 (Red Hat 8.3.1-5)] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
>>> import matplotlib
>>> import scrapy
>>> import requests
>>> exit()

無事にインストールできたことが分かる。

mac -> ssh -> dockerできるようにする

docker側の設定

  • openssh-server をインストール
# dnf install openssh-server
...省略...
Installed:
  openssh-8.0p1-5.el8.x86_64                       openssh-server-8.0p1-5.el8.x86_64

Complete!
  • サービスを起動
# systemctl start sshd.service
  • sshd.serviceのステータスがアクティブ状態になっていることを確認
# systemctl status sshd.service
● sshd.service - OpenSSH server daemon
   Loaded: loaded (/usr/lib/systemd/system/sshd.service; enabled; vendor preset: enabled)
   Active: active (running) since Tue 2021-01-05 21:26:45 JST; 1min 49s ago
     Docs: man:sshd(8)
           man:sshd_config(5)
...省略...
 105 21:26:45 af6b538f8bee systemd[1]: Starting OpenSSH server daemon...
...省略...
 105 21:26:45 af6b538f8bee systemd[1]: Started OpenSSH server daemon.
  • sshクライアントをインストール
# dnf install openssh-clients
...省略...
Installed:
  libedit-3.1-23.20170329cvs.el8.x86_64                 openssh-clients-8.0p1-5.el8.x86_64

Complete!

To be continured.

参考資料

新しいMacにgitクライアントを入れるまで

先週、MacBook Pro 13インチ(A2289)が到着したので、以前のMacBook Air を使っていた時に何気なくインストールし使ってきたソフトウェアのインストール手順を、Proを使っていくのをきっかけにまとめてみようと思った。

今回は、まずgitクライアントを入れるまでにメモ書きしておく。

以下の資料を参考させてもらった

Git のインストール 〜Git をMacにインストールしよう〜 | バージョン管理システム入門(初心者向け)

$which git
/usr/bin/git
$ git --version

ポップアップが出て、コマンドラインデベロッパ・ツールが必要だ、インストールしてくださいと言われた。「インストール」ボタンを押して、後のポップアップに「同意する」を押してやったが、しばらくするとなんとまたポップアップが出て、インストールできないと言われた(原因不明)。2回繰り返しても同じなので、この方法を諦めた。

参考資料には、別の方法として、インストーラーでgitをインストールする方法も紹介されているが、自分はその次の「Homebrewを使ってGitをインストールする」を選んでインストールすることにした(なぜならば、このMacにはまだ Homebrew が入っていないので、今後いろいろパッケージを入れる必要があり、どうせ必要だと思ったから)

Homebrew を入れる

まずは念の為に確認すうr

$ brew list
-bash: brew: command not found
$ /usr/bin/ruby -e "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"
~~(省略)~~
==> Installation successful!

==> Homebrew has enabled anonymous aggregate formulae and cask analytics.
Read the analytics documentation (and how to opt-out) here:
  https://docs.brew.sh/Analytics
No analytics data has been sent yet (or will be during this `install` run).

==> Homebrew is run entirely by unpaid volunteers. Please consider donating:
  https://github.com/Homebrew/brew#donations

==> Next steps:
- Run `brew help` to get started
- Further documentation:
    https://docs.brew.sh

今後は git がちゃんと使えるようになった

$ git --version
git version 2.24.3 (Apple Git-128)

Hatenaブログに外部JavaScriptを入れてみた

初めてのHatenaブログです。 以前はLivedoorブログを書いていたが、HTMLエディタがあまりにも使いづらいため、引っ越しを考えてました。

Hatenaブログに3種類の編集モードがあり、特にwikiMarkdownの書き方ができるのはありがたい。 一層のこと、JavaScriptを入れてカスタマイズできないか、ちょっと調べて見たところ、なんと、LaTeXが書けるJSを入れる紹介がありました。

LaTeXが書ける紹介ブログ

haskell.hatenablog.com

あの奥村先生の紹介も

MathJaxによる数式表示

早速試してみた

書くのは超簡単だが、超有名なアインシュタインの E = m c ^ 2 をLaTeXで書いてみました

$$ E = m c ^ 2 $$

書き方はこれ $$ E = m c ^ 2 $$

$$ (x+y) ^ n = \sum_{k = 0} ^ n {n \choose k} x ^ {n - k} y ^ k $$

もう20年以上使っていないが、修論で書く時にめっちゃ使ってました、個人的には美しく書けるので好きでした。

初めてのHatenaブログでした。