プレイヤーズ・ハイ

 雑多な日記

ひさびさの小ネタ集

ひさびさに小ネタをいくつか投下します。

【目次】

特定ディレクトリー配下に存在するファイルの拡張子をすべて抜き出す

「あるディレクトリー配下に存在するファイルの拡張子をすべて抜き出したい」

そういうことってありませんか?

ファイル数が数千を超えると、目視では辛くなってきますよね。

そこで。

まずはお馴染み、find でディレクトリーのみ抜き出す方法

  • 特定ディレクトリー配下のディレクトリーのみ抜き出す
$ find . -type d

続いて、あるファイルパスから拡張子のみ抜き出す方法

  • 拡張子のみ抜き出す 方法その一
$ file_path='/tmp/foo/bar/aaa.txt'
$ file_extension="${file_path##*.}"
$ echo "${file_extension}"
txt
  • 拡張子のみ抜き出す 方法その二
$ file_path='/tmp/foo/bar/aaa.txt'
echo "${file_path}" | sed 's/^.*\.\([^\.]*\)$/\1/'

以上を組み合わせて、特定ディレクトリー配下に存在するファイルの拡張子をすべて抜き出すシェルスクリプトを書きます。

第一引数に、調べたいディレクトリーのパスを指定してください。

「方法その一」か「方法その二」をコメントアウトして実行してください。

  • 特定ディレクトリー配下に存在するファイルの拡張子を抜き出しリスト化
#!/bin/bash

set -ue

echo -n '' > /tmp/tmp.extensions.list

if [[ ${#} -ne 1 ]]; then
    echo 'Usage:'
    echo '$ bash listing_all_file_extensions.sh /path/to/directory'
else
    while read directory; do
    
        # 方法その一
        while read file_path; do
            file_extension="${file_path##*.}"
            # 拡張子がないファイルはフルパスが返ってくるのでリストには載せない。
            echo "${file_extension}" | grep -v '^/' >> /tmp/tmp.extensions.list
        done < <(find "${directory}" -type f)
        
        # 方法その二
        # 拡張子がないファイルはフルパスが返ってくるのでリストには載せない。
        # find "${directory}" -type f | sed 's/^.*\.\([^\.]*\)$/\1/' | grep -v '^/' >> /tmp/extensions.list
        
    done < <(find "${1}" -type d)
fi

sort /tmp/tmp.extensions.list | uniq > /tmp/extensions.list

exit 0

find コマンドで特定の名前のディレクトリー以下には降りないようにする

find コマンドで検索をかけるとき、あるディレクトリー配下は検索したくないという場合があります。

これを実現するのが -prune オプションです。

僕は最初、使い方が分からなかったので、備忘録としてこのメモを残しておきます。

今回説明する環境のディレクトリー構成

  • /tmp/foo/bar/111/222/333
  • /tmp/foo/bar/111/aaa
  • /tmp/foo/bar/111/bbb
  • /tmp/foo/bar/111/222/aaa
  • /tmp/foo/bar/111/222/bbb
  • /tmp/foo/bar/111/222/333/aaa
  • /tmp/foo/bar/111/222/333/bbb

特定ディレクトリー以下を検索しない -prune オプション

/tmp/foo/bar/111/222 以下のディレクトリーを検索対象から外す場合は以下のようにする。

  • ファイル名 aaa, bbb のものを検索
$ cd /tmp
$ find ./foo/bar -type d -name '222' -prune -o -name 'aaa' -o -name 'bbb'
./foo/bar/111/aaa
./foo/bar/111/bbb
./foo/bar/111/222 # <- 222 ディレクトリーも表示されてしまう。
  • ファイル名 aaa, bbb のもの「のみ」を検索
$ cd /tmp
$ find ./foo/bar -type d -name '222' -prune -o -type f -name 'aaa' -print -o -type f -name 'bbb' -print
./foo/bar/111/aaa
./foo/bar/111/bbb

なお、find コマンドのオプションは暗黙の -and が省略されています。厳密に書くと以下のようになります。

$ find ./foo/bar -type d -and -name '222' -prune -o -type f -and -name 'aaa' -print -o -type f -and -name 'bbb' -print

チェックボックスやチェックマークを Textile 記法で使う


ずばり以下のように書くだけ。

(Textile 記法は直接 HTML コードを書くことができる)

マークの種類 マーク表記 HTML Decimal
チェックボックス (チェックなし) &#9744;
チェックボックス (チェックあり) &#9745;
チェックマーク &#10003;
太いチェックマーク &#10004;

h2. Todo

---

&#9744; やること 1
&#9744; やること 2 
&#9744; やること 3

参考

Tick symbol in HTML/XHTML - Stack Overflow http://stackoverflow.com/questions/658044/tick-symbol-in-html-xhtml

? (0x2610 in Unicode hexadecimal [HTML decimal: &#9744;]): an empty (unchecked) checkbox
? (0x2611 [HTML decimal: &#9745;]): the checked version of the previous checkbox
? (0x2713 [HTML decimal: &#10003;])
? (0x2714 [HTML decimal: &#10004;])

PowerShell で GNU find

GNU の $ find -name foo っぽいことを PowerShell でやる。

ls -r | where { $_.Name -match "foo" }

RealForce 87UB 静音モデルを Windows 7 で使う

Windows 7 Professional 日本語版にて US キーボードを使うために行った設定のメモ。

  • 87 キーのキーボードを使用したい(RealForce 87UB)。
  • 右 Alt を半角/全角キーとして使いたい。

「AX キーボード用ドライバー」いうものを使うと、サクッとこれらの条件を満たすことができた。

レジストリーを変更して US キーボードレイアウトに変更する。

HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\servicec\i8042prt\Parameters

名前 種類 データ
LayerDriver JPN REG_SZ kbdax2.dll
LayerDriver KOR REG_SZ kbd101a.dll
OverrideKeyboardIdentifier REG_SZ AX_105KEY
OverrideKeyboardSubtype REG_DWORD 0x00000001 (1)
OverrideKeyboardType REG_DWORD 0x00000007 (7)

右 Alt が無いノートパソコンで作業するとき

Ctrl + Alt, Fn + Alt で右 Alt になるらしい。

【おまけ】コロンとセミコロンを swap する。

デフォルトでコロン、Shift と同時押しでセミコロンにしたかったので AutoHotKey を使用してカスタマイズした。.ahk ファイルを .exe に変換し、スタートアップに登録。

AWS CLI のタイムアウトとリトライについて

AWS CLI のタイムアウトとリトライについてのまとめ

【目次】

AWS CLI のタイムアウト

2 種類のタイムアウトがあります.個別にタイムアウト値を設定することができます.

各 AWS CLI タイムアウトのデフォルト値と変更方法

タイムアウトの種類 デフォルト値 変更方法
コネクトタイムアウト 60 秒 AWS CLI のオプション (--cli-connect-timeout 秒数)
リードタイムアウト 60 秒 AWS CLI のオプション (--cli-read-timeout 秒数)

AWS CLI コネクトタイムアウトの説明

AWS CLI の各種コマンドを実行すると,対応する AWS API エンドポイントに対して AWS CLI が http または https 接続でにいきます. 主にネットワークの不調などで,コネクション確立を待たされることがあります.そのときに何秒待つか,の設定値です.

AWS CLI リードタイムアウトの説明

AWS CLI の各種コマンドを実行すると,対応する AWS API エンドポイントに対して AWS CLI が http または https 接続でにいきます. コマンドの内容が AWS API に伝わると,問い合わせに応じた回答を返します. このとき,AWS (API) 側の原因,またはこちらのネットワーク不調などの原因で,回答の受取を待たされることがあります,そのときに何秒待つか,の設定値です.

AWS CLI のリトライ

AWS CLI のリトライ回数のデフォルト値

コネクトタイムアウト,またはリードタイムアウトが発生した場合に,何回リトライするかというと,デフォルトでは 5 回です. botocore の以下にデフォルト値は 5 ですよ,と記述されています("max_attempts": 5,).

github.com

その他の JSON 部分を読んでみると,AWS サービス毎にデフォルトリトライ回数をハードコードしたり,exponential backoff なリトライにするか,またそのときの挙動についても書かれているようです.

docs.aws.amazon.com

ちなみに,リトライ回数がデフォルトの 5 回だとして,コネクトタイムアウトが 3 回発生し,次にリードタイムアウトが発生したとしたら,リードタイムアウトのリトライ回数は 2 回なのか,一旦リセットされて 5 回までリトライするのか,は,実測もしていませんし,そこまでコードも読んでいませんので分かりません.すみません(実測していませんが「合計」5 回となるようです).

AWS CLI のリトライ回数の変更方法

AWS CLI のオプションにリトライ回数を変更するオプションは存在せず,

botocore/_retry.json を編集し上書きするしかないようです.

または AWS CLI 実行時のリトライ回数を制御するラッパーを書く,というのも考えられます(しかし,タイムアウト系はデフォルトリトライ回数を変更 (1 回タイムアウトしたら異常終了) するには,_retry.json を変更するしかありません.逆に 30 回までリトライさせるためにラッパーを書くという道もありますが,_retry.json を変更した場合と比べると,厳密に言えば動作は異なります.独自のラッパーのメリットとしては,タイムアウト系以外のエラーハンドリングを自由に定義できるところになると思います).

AWS CLI のタイムアウトとリトライについて調べたこと

AWS CLI は AWS SDK for Python の botocore というものを使用しており,タイムアウトとリトライは,その実装によるようです.

先ほども書きましたが,botocore の GitHub リポジトリーは以下です.

github.com

botocore は The low-level, core functionality of boto 3. だよ,という説明があります.

boto 3 (Boto3) とは,最新版 (2017/1/16 現在) の AWS SDK for Python のことで,pip install boto3 でインストールします. ちなみに Boto のオリジナル版は AWS SDK for Python バージョン 2 だそうです.

まとめると AWS SDK for Python (Boto3) の中に botocore があり,それの処理の中に,タイムアウトとリトライの制御が入っています.

また,詳細は以下にありますが「Amazon S3 の自動マルチパート転送」や,AWS リソースにおける事前定義ステータスの変化を自動的にポーリングする "waiter" も,Boto3 で実装されています.

AWS SDK for Python | AWS

AWS CLI のタイムアウトについて追記

以下の環境で,AWS CLI のタイムアウトについて,どのコードで定義されているか,もう少し調査してみました. (コネクトタイムアウト,リードタイムアウトともに,AWS CLI のオプションで変更できますので,以下の調査にあまり意味はないかもしれません)

  • Red Hat Enterprise Linux Server release 7.2 (Maipo)
  • 3.10.0-327.28.3.el7.x86_64
  • Python 2.7.5
  • pip 8.1.2 from /usr/lib/python2.7/site-packages (python 2.7)
    • boto3 (1.4.1)
    • botocore (1.4.49)

botocore の config に関しては,以下のウェブサイトに書かれています.タイムアウトに関する記述もあります.

Config Reference — botocore 1.8.13 documentation

ほんで,上記環境で適当に find や grep してみましたが,具体的には上記環境ですと, タイムアウトのデフォルト値は /usr/lib/python2.7/site-packages/botocore/config.py の中で記述されているようです.

更に深追いするには,適当に grep して掘っていきましょう(なんか雑になった.すみません).

唐突に番外小ネタ.su と sudo

当たり前過ぎて恥ずかしい記述もありますが...

root 権限を必要とするコマンドの手動実行は,sudo -i [コマンド] で,毎回パスワードを求められるスタイルがセキュアなのかな.

しかしそれだと障害対応のときに死ねる.

普段はパスワードを毎回要求し,障害対応用に,パスワードを要求しないようにするワンライナーを保持しておくのがいいのかな.

以下を読むと,色々と柔軟に設定できそうなので,また今度詳細に詰めてみようと思う.

sudo - Wikipedia

  • Amazon Linux
  • bash
  • 一般ユーザーから root になりたい.
  • 結論は su -sudo -i 使おう.
    • su - は,環境変数 $PATH に /usr/local/bin が含まれ「る」.
    • sudo -i は,環境変数 $PATH に /usr/local/bin が含まれ「ない」.
    • su - は,root (スイッチユーザー先) のパスワードが要求される(/etc/pam.d/su を編集し auth sufficient pam_wheel.so trust use_uid を有効化すれば,wheel グループに属するユーザーはパスワードなしで root に su できます.ちなみに wheel グループに属するユーザーのみに su を許可する場合は auth required pam_wheel.so use_uid を有効にします).
    • sudo -i は,スイッチユーザー元のパスワードが要求される.また root になるには /etc/sudoers 内での許可が必要.

その他詳細は,以下の Qiita にすばらしくまとめられています.

qiita.com

また PAM まわりは以下のブログにすばらしくまとめられています.

suコマンドによるrootへのスイッチを制限する | VPSサーバーでWebサイト公開 備忘録 ~Linux、MySQLからAJAXまで

唐突に小ネタ2

お恥ずかしながら POSIX 互換モードを知りませんで,

「sh は /bin/sh で,これはシンボリックで実体は /bin/bash なのに,なんで $ sh foo.sh と実行したときに bash 独自機能を使っているとエラーになるのか? シェバンも /bin/bash なのに」

という疑問があり,うやむやにしてしまっていました.

以下は,シェルスクリプトがどのシェルから呼び出されたのかを判別する部品です(メッセージが寒くてすみません).

#!/bin/bash

shell_prog=`ps h $$ | awk '{ print $5; }'`

case "${shell_prog}" in
    sh) echo '$ sh foo.sh ってやっちゃダメ.POSIX 互換モードのせいで bash 独自機能が使えないゾ☆'
        echo 'bash で出直してこい.'
        exit 1
        ;;
    *bash) echo 'bash マンセー!!'
        :
        ;;
    ksh) echo 'Korn Shell とかシブいね!!'
        :
        ;;
    zsh) echo 'zsh とか厨二ですか?'
        :
        ;;
    *csh) echo 'そなたが伝説の(ry'
        :
        ;;
    *) echo '「」'
        :
        ;;
esac

# シェルスクリプト本体の処理

以上

Mac のメンテナンス

僕の持っている MacBook Pro 15 インチ Mid 2015 に適用する前提で書いています.

僕のは El Capitan なんだけど,ずっと起動しっぱなしだと遅くなってくる気がして.詳細な原因は追っていませんが,できるだけ快適に使っていくための定期的な運用方法を考えてみました.おまけでトラブル・シューティングに関しても少しまとめました.

【目次】

マシン・パフォーマンスをできるだけ落とさないための Mac 定期運用

以下を週一回行うのが理想

  • セーフブート (色々なソフトウェア・キャッシュが削除される)
    • セーフブートのやり方は,(再)起動シーケンス中に shift キーを押しっぱなしにします.FileVault を使っていると2回ログイン画面が表示されることがあるらしいです.セーフブートすると画面の右上に赤い文字で Safe Boot と表示されます.
    • デメリットもあるかもなので注意してください.たとえば僕の環境ではディスプレイの解像度がリセットされました.これは大した問題じゃないけど他に大したものがあるかもしれません.
  • シャットダウン (根拠はないっちゃない.ただ一週間に一度は,機械ごと落としたいという気分的な問題だけ.再起動ではとおらないシーケンスもとおりそうだし.2度と起動しなくなるリスクもあるっちゃあるが,週に一度シャットダウンする運用を僕は選んだ)

だから,週に一度は,Time Machine バックアップ完了後に,シャットダウンして,セーフブートして,それからまたノーマルブート.

Mac のトラブル・シューティング

ハードウェア診断

  • ハードウェアの故障を疑う場合はハードウェア診断を行う.光学ドライブを内蔵しない MacBook Pro の場合,インターネットに接続された環境で、Mac OS X 起動時に option キーを押下しながら D キーを押下し続ける。地球儀のようなマークがでてきたら,ハードウェア診断に突入.

NVRAM クリアー

NVRAM に格納されている情報

- スピーカーの音量
- 画面の解像度
- 起動ディスクの選択
- 最近起きたカーネルパニックの情報 (存在する場合)
- タイムゾーン情報

これらが絡んでそうな問題は,NVRAM のクリアーで解決する,かも.

ちなみに NVRAM という名称は Intel Mac からで,PowerPC 時代は PRAM と呼ばれていたらしいです.

NVRAM クリアーのやり方

Mac OS X 起動時に command + option + P + R キーを押下し続ける.2回目のジャーン!でキーから手を話す.が,ジャーン!が鳴らない場合 (MacBook Pro Late 2016 は,鳴らないらしい) は最低 20 秒以上押し続ける.

最後の手段? SMC (システム管理コントローラー) のリセット

最後の手段?

かなり最後の手段っぽいので,実施前に必ず以下を参照のこと.実施方法もここに書いている.

support.apple.com

SMC リセットするしかないっぽい兆候

  • コンピューターの実行速度がかなり遅い.
  • 電源ボタンを押しても起動しない.
  • スリープからの復帰がおかしい.
  • バッテリーの充電ができない.
  • 電源アダプタを認識しない,など.

その他

Mac を快適に使うための小ネタを追記予定です.

  • Time Machine によるバックアップを常時走らせない.

などなど

以上

僕とスピンサーブ

ブログタイトルどおり,僕はスピンサーブが打てない.

ここで言うスピンサーブとは,硬式テニスの,いわゆるスピンサーブのことです(以下,テニス = 硬式テニスのことを指します.軟式は一回もやったことがありませんが,一度やってはみたい).

通っているスクールのコーチが,スクール生に向かって以下の問いかけをしていた.

「なんでサーブは2回打てると思う?」

正直,わかれへんくて,そして他の誰も分からなかった.

答えは,あらゆるテニスのショットの中で,サーブが一番むずかしいから,だそうです.

言われてみればたしかに,サーブは,打てる場所 (スタートポジション) も,あと,入れなければならないスペースも,他のどんなショットより限定されている.

ちょっと目からウロコだった(ってくらい,僕は何も考えずにテニスをやっていたわけです).

テニスコートの構造上,打ち下ろすタイプのサーブを打つには身長が2メートルくらい必要と言われています.

そんな人間はあまりいません.

ほんで,1本目のサーブはおもくそバコーンと打って入ればラッキーでもいいけど,セカンドサーブを相手に叩かれたくないなら,高確率で入る,かつチョンと押すような入れてけサーブではないサーブを打たなければなりません.それがスピンサーブです.もう少し具体的に言うと,ネットしないように,ネットぎりぎりではなくちょっと上をとおし,文字どおり (縦の) スピン回転をかけて,キャプテン翼のドライブシュートのようにグイっと下向きに曲げ,サービスエリアに沈めるサーブです.

あと,ラファエル・ナダルのフォアハンド・ストロークじゃないけど,ホントにスピンがかかっていると,跳ねたあとのバウンドが高くなって,慣れていないと打ちにくい.一部のプロの放つ本当にエグいスピンサーブは,洒落にならんくらい跳ねるので,力が入らない高いところリターンを打たされることになります.イズナーのスピンサーブがヤバかったかも.バウンド後ライジングで叩くのも難しく,センスや練習が要ります.でもぶっちゃけ,プロでも打つフォームでスピンサーブと分かるので,ああこれは跳ねるな〜と,事前に分かりますね.でも,どんな球種が事前に来るか分かる = 返しやすい,では必ずしもないですね(色々混ぜられるとミスさせられやすくなる).

スピンサーブの打ち方のイメージとして「ラケットヘッドをダウンさせ,背中から斜め前の上空に向けて振り出す」みたいなことが言われていて,要はボールに縦回転をかけるためにそういう感じで打つ,というのは文章では理解できるのですが,僕にはどうしても打てない.

僕がスピンサーブを打とうとすると,ほぼ百パーセント,変な回転のスライスサーブになる.

本当に変な具合に曲る.それはそれで打ちにくくて,いいのかもしれないが,スピンサーブを打とうとしているのに,スライスサーブになるんですよ.

それは屈辱以外の何物でもない(大げさ).

YouTube で,スピンサーブの打ち方動画みたいなのも結構みてて,その直後は,あそっかぁ,オレ打てるわスピンサーブ,とか思うのですが,いざ打つとまたスライスサーブになってる.

もう,この世には,生まれつき,スピンサーブを打てる人間と打てない人間の2種類が,運命的にはっきり決められているのか? と思いたくなるくらいです.

算数・数学が苦手,または外国語が苦手,みたいなコンプレックスに通ずるところも,あるのかもしれない(スピンサーブが打てるからと言って給料が上がったりはしないが).

しかし,物理的に正しくラケットをボールに当てれば絶対にスピンサーブは打てるはずで,当面それを目指してみようかなと思っています.

ちなみに,僕のテニスのレベルは,いわゆる初中級クラスで,フォアはまぁ普通.バックは片手も両手もいける,バックハンド・スライスは,浮いちゃうのと滑るのが半々くらい,ボレーは苦手意識なし,フラットサーブは (初中級レベルでは) むしろ上手い方と思っている,スマッシュは下手くそ気味 (単に練習不足の恐れあり) みたいな感じです.

サーブのフォームは,以前はおもいっきしフェデラーを意識していました.2016 年に一時期マレーにはまって,ステップインして,フォロースルーで左手が上にあがるフォームに変えました(左手はなんか自然にあがる).ジョコっぽいフォームでも打てるし,なんちゃってロディックフォームでも打てます.威力はヘボいですが.そして今,またフェデラーっぽいフォームに戻しています.ステップインしないやつ.

フォアハンド・ストローク速い人を見ると,すげえな,かっちょいいな,と思うんですけど,ちゃんとスピンサーブ打てる人は,もっと羨望の眼差しで見てしまうんですよね.

正しく努力して,グンッと落ちるスピンサーブを打てるようになり,あわよくばキックサーブも打てるようになり,そして,算数・数学への苦手意識もなくしていきたいと思っています(それはまた別の話).