けけずんセルフハッキング

エンジニアっぽい雰囲気を醸しだしているかのようなブログです!

/bin/stty で端末設定を設定 or 表示する

はじめに

よく分からんコマンド調べてみようシリーズ。 経緯はこちら。

kkznch.hatenablog.com

今回は /bin/stty について。

/bin/stty

確実に一回も実行したことないであろうコマンド。 stty だからコンソールに関連するコマンドかな。

こちら man stty したときの DESCRIPTION の内容。

The stty utility sets or reports on terminal characteristics for the device that is its standard input. If no options or operands are specified, it reports the settings of a subset of characteristics as well as additional ones if they differ from their default values. Otherwise it modifies the terminal state according to the specified arguments. Some combinations of arguments are mutually exclusive on some terminal types.

標準入力であるデバイスの端末特性を設定したり表示したりする、何を言っているのかよく分からない。

とりあえず実行して動きを見る。

/bin/stty 実行してみる

よし何が起きるのか分からんけど実行する。

$ /bin/stty
speed 38400 baud;
lflags: echoe echok echoke echoctl pendin
iflags: iutf8
oflags: -oxtabs
cflags: cs8 -parenb
erase
^H

実行したけど何が起きたのか分からなかった。 端末の転送速度とか特殊文字に関する設定が出力されてるだけかな。

linuxjm.osdn.jp

ここを見るに、文字を削除したときやプロセスをkillしたときの表示形式などが出力されてるっぽい。 ほぼ触ることがなさそうなコマンドだ...。

ちなみにコンソールの表示がおかしくなったときは stty の設定がおかしくなってる可能性があるので、以下のコマンドを実行して stty の設定を初期化してあげるとよいらしい。

$ stty sane

qiita.com

/bin/dd でデータをブロック単位でコピーする

はじめに

よく分からんコマンド調べてみようシリーズ。 経緯はこちら。

kkznch.hatenablog.com

今回は /bin/dd について。

/bin/dd

Linux の iso イメージを USB フラッシュメモリに書き込む際に使った記憶がある。 それ以外で使った記憶がない。

なんかディスクに書き込んでるんだろうな〜というぐらいの認識だった。 こちら man dd したときの DESCRIPTION の内容。

The dd utility copies the standard input to the standard output. Input data is read and written in 512-byte blocks. If input reads are short, input from multiple reads are aggregated to form the output block. When finished, dd displays the number of complete and partial input and output blocks and truncated input records to the standard error output.

標準入力を標準出力にブロック単位でコピーするらしい。 だいたい認識通りだった。

オプションで入力元や出力先、入出力のブロック単位を変更できる。

/bin/dd と /bin/cp の違いは?

他サイトからの引用。

dd コマンドは入力から出力へデータをコピーするコマンドである。cp コマンドはファイルからファイルにコピーするだけであるが、dd コマンドはファイルからデバイス、デバイスからファイル、デバイスからデバイスへのコピーも可能なため、ディスクのバックアップやダンプにも使用できる。

x68000.q-e-d.net

dd コマンドはファイルシステム上のファイルだけでなく、ブロックデバイスに直接アクセスできます。

teratail.com

/bin/dd はデバイスにごそっと出力、 /bin/cp はファイルのコピー、なるほど。

/bin/dd 実行してみる

基本的な構文はこれ。 細かいオプションはマニュアルを読もう。

$ /bin/dd if=入力元 of=出力先

if で入力元、 of で出力先を指定する。 どちらもデバイスまたはファイルを指定できる。 なお if を指定しない場合は標準入力が入力元、 of を指定しない場合は標準出力が出力先になる。

試しにファイルを対象に dd 実行してみる。

$ /bin/dd if=hoge.txt of=fuga.txt
0+1 records in
0+1 records out
15 bytes transferred in 0.000072 secs (208326 bytes/sec)

$ diff -s hoge.txt fuga.txt
Files hoge.txt and fuga.txt are identical

dd で hoge.txt から fuga.txt をコピーして、diff でファイルの内容が同一であることが確認できた。 ただファイルのパーミッションやタイムスタンプまではコピーされないっぽい。

注意点

出力先にデバイスを指定するとそのまま書き込まれちゃうので、実行する際は注意が必要かも。 他サイトでも危険とか書いてるとこあるし。

news.mynavi.jp

/bin/[ という謎コマンドがあった

はじめに

気まぐれで macOS*/bin なフォルダの中にどんなコマンドがあるのか気になったので調べてみた、そしてまず最初にコマンドっていくつあるの、というのが前回の話。

kkznch.hatenablog.com

今回はなんとなく /bin からとっついてみようと思い、以下のコマンドを実行してみた。

$ ls -l /bin | head
total 4888
-rwxr-xr-x  1 root  wheel    35824 12  5 18:33 [
-r-xr-xr-x  1 root  wheel   623344 12  5 18:33 bash
-rwxr-xr-x  1 root  wheel    36768 12  5 18:33 cat
-rwxr-xr-x  1 root  wheel    47296 12  5 18:33 chmod
-rwxr-xr-x  1 root  wheel    42272 12  5 18:33 cp
-rwxr-xr-x  1 root  wheel   528688 12  5 18:33 csh
-rwxr-xr-x  1 root  wheel   110848 12  5 18:33 dash
-rwxr-xr-x  1 root  wheel    41728 12  5 18:33 date
-rwxr-xr-x  1 root  wheel    45168 12  5 18:33 dd

ls/bin の中にあるコマンドをリスト形式で取得し、 head でリストの頭から10行を表示させている。

見慣れたコマンドの中に謎の記号がいるのが分かるだろうか。

/bin/[

そう、 /bin/[ こいつである。 え、コマン...ド?コマンドなの?と最初は思った。

ここで man [ を実行してこいつが何者なのかを見てみる。

TEST(1)                   BSD General Commands Manual                  TEST(1)

NAME
     test, [ -- condition evaluation utility

SYNOPSIS
     test expression
     [ expression ]

略

test と同じっぽい

なるほどどうやら test というコマンドと同じ内容らしい。 test 条件 で与えられた条件の判定を行うことができる。

例えば test で指定したフォルダが存在しているか確認したい場合、以下のように実行する。

$ test -d Library
$ echo $?
0

test で Library といフォルダが存在しているか確認し、echotest の実行結果を表示している。 echo $? の結果が 0 のときは Library フォルダが存在しており、1 のときは存在していないことになる。

/bin/[ で書いてみる

これを [ で書くと以下のようになる。

$ [ -d Library ]
$ echo $?
0

どこかで見たことあると思ったら、 Shellscript で if 文を書くときに評価される箇所と同じだなと思った。

Shellscript だとこんな感じかな。

if [ -d Library ]; then
  なんか処理実行する
fi

普段Shellscriptで書いてた if 文の角括弧の正体はこいつだったのか...。

macOS って */bin にどんなコマンドがあるんだろ

はじめに

ふといつも使ってる mac*/bin にどんなコマンドがあるのか気になった。

というのも、大体いつも同じコマンドばかり(ls とか cd とか mkdir とか)使っているため、新しいコマンドを覚える勉強などほとんどしていないと気づいたから。

ひとまず今回は各フォルダのコマンドの個数を確認する。

環境

対象フォルダ

以下のフォルダについて調べていこうかな。

  • /bin
  • /sbin
  • /usr/bin
  • /usr/sbin
  • /usr/local/bin
  • /usr/local/sbin

各フォルダにあるコマンドの数

ls -l /bin | wc -l

上記のコマンドを実行してフォルダ内のコマンドの数を見てみた。

各フォルダにあるコマンドの数は以下の通り。

パス コマンドの数
/bin 37
/sbin 62
/usr/bin 1013
/usr/sbin 233
/usr/local/bin 326
/usr/local/sbin 7

どのフォルダから見ていこうかなー。

参考

qiita.com qiita.com

2019年振り返り

はじめに

去年から引き続き、2019年の振り返りをしてみる。

ちな去年の振り返り。 やはり記録に残しておくと後から見返せるから良いな〜。

2018年振り返り - けけずんセルフハッキング

しかし今年は前半部分が思い出せない。 どこかに何をやっていたか残していたと思うのだけど、行方不明。 思い出しながら書いていく...。

月毎の振り返り

身につけたスキル

プログラム言語

フレームワーク

  • Laravel6.x
  • Vue.js
  • Nuxt.js
  • Express <- New!

その他

  • Docker
  • AWSいろいろ
  • Swift UI <- New!

おわりに

2019年は毎月登壇するという目標を立てていたが、登壇回数だけ見るとほぼ毎月登壇することができた。 今年は登壇するだけでなく、勉強会を主催する側にシフトしていければなと考えている。

2020年も頑張るぞい。

よく忘れる ESLint の設定

ESLint を使うときにプラグインを入れるだけでいい感じに動くと思っていたが、毎度そのへんの設定でいつも苦しめられていたので少し調べた。

設定ファイルについて

設定ファイルの読み込み優先度

ESLint の設定はいくつかの形式で記述できるが、それぞれ読み込みに優先度があるらしい。優先度は以下の通り。

  1. .eslintrc.js
  2. .eslintrc.yaml
  3. .eslintrc.yml
  4. .eslintrc.json
  5. .eslintrc
  6. package.json

対応するESのバージョン

ESLint はデフォルトではES5のみ扱えるらしく、それ以外に対応したい場合はオプションを設定する必要があるらしい。 例えば ES6 に対応させたい場合は以下のように env プロパティで es6 を true にすればよいらしい。

module.exports = {
  env: {
    es6: true,
  },
};

以下のように parserOptions で指定もできるが、これだと自動的にグローバルに設定されないって公式に書いてたけどよく分からんかった。

module.exports = {
  parserOptions: {
    ecmaVersion: 6,
  },
};

env に設定してあげるほうが無難かもしれん。

pluginsとextendsの違い

これ毎回どっちがどっちだよってなる。 ざっくりとこんな感じか?

plugins

ルールセットを持つプラグインを指定する項目。 本来であれば plugins にプラグインを指定して、且つ extends にそのプラグインが持つルールを指定しないと検証時にルールが適用されないらしいが、prettier はなぜか plugins に指定しただけでルールが適用されてる。謎。

基本的には eslint-plugin-xxx というパッケージの xxx の部分を plugins に記述してあげればいいらしい。

extends

プラグインが提供するルールを指定する項目。 eslint-plugin-xxx というパッケージを plugins で指定した場合は、extends に xxx/yyy というふうにルールを指定してあげるらしい。

また、plugins は使わずに eslint-config-zzz というパッケージをインストールし、extends に zzz と指定してあげてもなんとかなるっぽい。

プラグインについて

複数のプラグインを使用する場合、記述した順番次第で設定が上書きされるらしいので注意が必要。

Prettier

eslint --fix コマンドで ESLint だけでもコードフォーマットは行えるらしいが、 Prettier の方が優れたコードフォーマットをしてくれるらしいので ESLint 入れるときはプラグインとして Prettier も大体一緒に入れられるっぽい。

静的検証のみ行いたい場合

ESLint と一緒に Prettier の検証をしたい場合は以下のパッケージをインストールして設定するだけでよい。

  • prettier
  • eslint-plugin-prettier
module.exports = {
  plugins: [
    'prettier',
  ],
  rules: {
    'prettier/prettier': 'error',
  }
};

コードフォーマットもしたい場合

plugins に prettier を追加しただけだとフォーマットの際に ESLint の設定と衝突する場合がある。 それを避けるために以下のパッケージをインストールして設定する必要がある。

  • eslint-config-prettier
module.exports = {
  extends: [
    'prettier',
  ],
  plugins: [
    'prettier',
  ],
  rules: {
    'prettier/prettier': 'error',
  }
};

ちなみに以下は上記の記述の短縮形らしい、ややこしいなホンマ。

module.exports = {
  extends: [
    'plugin:prettier/recommended',
  ],
};

Vue

Vueのスタイルガイドの項目に合わせた検証を行なうことができるっぽい。 以下のパッケージをインストールして設定を行えばおっけー。

  • eslint-plugin-vue
module.exports = {
  extends: [
    'plugin:vue/recommended',
  ],
};

extends に指定した項目の末尾 recommended の他にも essential とかあって、それぞれでルールのレベルが異なるらしい。 参考URLに貼ったページの先で解説してあるから詳しくはそっち見てね。

TypeScript

ESLint にTypeScriptのプラグインを入れればちゃんと検証してくれるらしい。 ただTypeScriptの場合は ESLint の設定に parser を指定する必要があるので、忘れずに。 以下はインストールするパッケージ。

  • @typescript-eslint/eslint-plugin
  • @typescript-eslint/parser

個別に設定されたルールを指定したい場合は以下の通り。 @typescript-eslint/rule-namerule-name は適宜置き換えて使ってとのこと。

module.exports = {
  parser: '@typescript-eslint/parser',
  plugins: [
    '@typescript-eslint'
  ],
  rules: {
    '@typescript-eslint/rule-name': 'error'
  }
};

用意されたルールセットからルールを指定したい場合は以下の通り。 parser の指定すら必要ないっぽい。

module.exports = {
  extends: [
    'plugin:@typescript-eslint/recommended',
  ],
};

ESLint が推奨しているルールと併用したい場合は以下の通り。

module.exports = {
  extends: [
    'eslint:recommended',
    'plugin:@typescript-eslint/eslint-recommended',
    'plugin:@typescript-eslint/recommended',
  ],
};

Prettier と併用したい場合は以下の通り。順番に注意。

module.exports = {
  extends: [
    'plugin:@typescript-eslint/recommended',
    'prettier',
    'prettier/@typescript-eslint',
  ],
};

おわりに

ここまでざっと書いたけど、基本的に公式ドキュメントや各パッケージの README に書いてるものをまとめただけ。 詳細について知りたい方はドキュメント見てね。

参考URL

GitLab CI VariablesにFileとして保存したPEM形式の鍵を展開する際にハマった

概要

GitLab CIでVariablesに保存したPEM形式の鍵を展開し、プログラムの中でその鍵を読み込んで使用しようとしたが上手く動かなかった。

そのときの原因と解決方法について書く。

やりたいこと

以下のPEM形式(説明しやすいように内容はてきとうです)の鍵があるとする。

-----BEGIN RSA PRIVATE KEY-----
1行目です〜
2行目です〜
3行目です〜
4行目です〜
-----END RSA PRIVATE KEY-----

こいつをGitLab CI Variablesに登録して、GitLab CI上でファイルとして展開し、プログラムの中で使用したい。

問題発生までの手順

GitLab CI Variablesに鍵の内容を保存する

GitLab CI Variablesを開き、以下の内容を入力していく。

  • Type: 「File」を選択する
  • Key: 「YOUR_PRIVATE_KEY」と入力する
  • Value: 上記の鍵をコピペする

画面的にはこんな感じ。

f:id:kkznch:20190728221255p:plain

GitLab CI用の設定ファイルを書く

以下の内容で .gitlab-ci.yml を作成する。

内容としては、GitLab CI Variablesに登録した環境変数を一度 .gitlab-ci.yml のvariablesで受け取ってそれをファイルとして書き出しているだけ。

stages:
  - test

set_privatekey:
  stage: test
  image: alpine:latest
  variables:
    PRIVATE_KEY: YOUR_PRIVATE_KEY
  script:
    - echo ${PRIVATE_KEY} > private.key

この状態でcommit & pushする。

プログラム中で使用...できない

上記と同様のことを実際のプロジェクトで行いデプロイまでしたのだが、デプロイ後にプログラムを動かしても動く気配なし。

ログを見ると、鍵の形式が不適切なため読み込めないとのこと。どういうこったい。

原因

ということで原因を特定するために .gitlab-ci.yml を以下のようにしてみた。

stages:
  - test

set_privatekey:
  stage: test
  image: alpine:latest
  variables:
    PRIVATE_KEY: YOUR_PRIVATE_KEY
  script:
    - echo ${PRIVATE_KEY} > private.key
    - cat private.key

そのときの出力結果がこちら。

$ echo ${PRIVATE_KEY} > private.key
$ cat private.key
-----BEGIN RSA PRIVATE KEY----- 1行目です〜 2行目です〜 3行目です〜 4行目です〜 -----END RSA PRIVATE KEY-----

ふぁ!?なぜにワンライナーで表示されるし??

改行まで含めてPEM形式のため、しっかりと改行されてる状態じゃないと読み込んでくれないらしく、こいつが原因だった模様。

こちら参考ページ。

解決

二通りの解決方法がありけり。

その1

.gitlab-ci.yml を以下のようにする。

stages:
  - test

set_privatekey:
  stage: test
  image: alpine:latest
  variables:
    PRIVATE_KEY: YOUR_PRIVATE_KEY
  script:
    - echo "${PRIVATE_KEY}" > private.key

何が違うかって?

    - echo "${PRIVATE_KEY}" > private.key

この echo で渡す引数をダブルクォーテーションで括ってる。 これで意図したようにファイルに展開される。

その2

.gitlab-ci.yml を以下のようにする。

stages:
  - test

set_privatekey:
  stage: test
  image: alpine:latest
  script:
    - cat ${YOUR_PRIVATE_KEY} > private.key

GitLab CI Variablesに登録した環境変数をそのまま cat してあげてる。

ここで echo を使ってない理由は、GitLab CI VariablesにFileとして登録した環境変数には値がそのまま入っているわけではないから。 もし echo で実行すると、以下のように登録した値が格納されたファイルへのパスが出力される。

/builds/{ユーザID}/test-variables.tmp/YOUR_PRIVATE_KEY

なるほど、 cat だと上記のパスにあるファイルの中身を出力してる感じになってるらしい。

おわりに

公式サイトにFileな値を出力する方法が載ってたので、まずはそれを見るべきだった気もする。

個人的に気になってるのが、GitLab CI Variablesで登録した値を使用する際は .gitlab-ci.yml のvariablesを経由して使用する必要があるのか?といったところ。 いちいちGitLab CI Variablesのページにいかなくても、CI上で必要な環境変数を一覧できるという意味では割と有効かもしれんが、実際のところどうなのかは分からない。