Access Denied
のエラーになることがある。
この手に対策によく見るのは、クッキーやキャッシュを削除しろというものだ。単にサーバーがメンテテナンス中で、しばらく経てば直るということもある。しかし、先日、私が経験したのは、そのどちらでも解決しなかったので、参考までに書いておこうと思う。
ある日、ときどき利用する、あるネットショップにアクセスすると、Access Denied
が表示されて閲覧できないことに気付いた。
ブラウザはGoogle Chromeを使っていて、複数のGoogleアカウントで使いわけている。そのひとつでなぜかアクセスできない。他のアカウントだと問題ないので、買い物をするのに困ったわけではない。
クッキーを削除しても変化なし。キャッシュを削除したり、ブラウザを再起動してみたり、WAN側を再起動してIPアドレスを変更してみたりしたが同じ。シークレットウィンドウでアクセスすると正常に閲覧できるという、いまひとつよくわからない状態だった。
いろいろ調べた結果、原因は、Chromeが最初に送信するHTTPリクエストのaccept-language
ヘッダーの違いで、サーバーのアクセス制限にひっかかっていることがわかった。
正常にアクセスできるHTTPリクエストは次のとおり。
accept-language: ja-JP,ja;q=0.9,en-US;q=0.8,en;q=0.7
一覧にすると次の4つが設定されている。
ja-JP
の1.0でその数値は省略されている。一方、Access DeniedされたHTTPリクエストには、微妙な違いがあった。
accept-language: ja,en-US;q=0.9,en;q=0.8
ja-JP
がない。しかし、どちらのChomeも、設定画面の優先言語は同じになっている。
設定画面では同じなのに、なぜaccept-language
の値が違うのか?の理由はさておき、とりあえず、Access DeniedになるChromeで、優先言語の設定を次のように英語(アメリカ合衆国)
を削除して試しみた。
これで正常にアクセスができるようになった。
ということは、今回のネットショップに関して言えば、今回の事象は、HTTPリクエストのアクセス制御にひっかかっていたと言える。
試しに言語設定をいろいろ変更してみて、わかったのは、accept-languageの値の先頭がja,en-US
で始まるときにアクセス制御がかかるようだ。ja-JP,ja,en-US
だと問題ないので、単にサーバーの設定の問題のように思えるが、どちらの振舞いが正しいのかはわからない。
利用者の立場として、Access Deniedになる原因にはこんなこともあるのだと妙に感心したので記事にしてみた。今回はaccept-language
だったが、どのヘッダーでアクセス拒否されているかは調べてみないとわからない。Google ChomeのDevToolsが役に立った。
ところで、Chromeの優先言語の設定は同じ日本語なのに、リクエストヘッダーのaccept-language
の値がja
だったり、ja-JP,ja;q=0.9
する現象については、原因がまたわかったら記事にしたいと思います。
コマンドの出力をファイルへ保存したいなら、シェルのリダイレクトという機能を使って、標準出力をファイルへ紐付ける。
$ COMMAND > file.txt
一方、コマンドのエラーメッセージは、標準エラー出力
へ送られるが、この標準エラー出力
もターミナルに紐付いている。変更するには2>
を使う。
$ COMMAND 2> error.txt
この2
という番号はファイルディスクリプタ(File Descriptor)と呼ばれる。
標準出力が1、標準エラー出力が2というのが決っているようだ。指定しなければ、1がデフォルトになる。
標準出力と標準エラー出力の両方を変更するなら、次のように書く。
$ COMMAND 2> error.txt 1> file.txt
ファイルディスクリプタの1は書かなくても同じなので、これでいい。
$ COMMAND 2> error.txt > file.txt
標準エラー出力を標準出力と同じに紐付けるなら、&
を使う。
$ COMMAND 2>&1
標準出力1と標準エラー出力2を同じファイルへ紐付ける。
$ COMMAND 1>file.txt 2>&1
次のように順番が逆だとうまく動かない。
$ COMMAND 2>&1 1>file.txt # 悪い例
なぜなら、最初に2>&1
を指定しても この時点では標準出力はターミナルに紐付いているので、標準エラー出力はターミナルに紐付いてしまうからである。
コマンドの標準出力を別のコマンドの標準入力へ紐付ける仕組みはパイプと呼ばれる。
$ COMMAND1 | COMMAND2
標準エラー出力もパイプで送るのであれば、リダイクレトを使う。
$ COMMAND1 2>&1 | COMMAND2
zshやbashのマニュアルを読むともっと複雑な書き方があるが、これぐらいをしっかり身に付けておけば、普段使いには十分な気がする。
例えば、zshには、上の書き方の省略形があるが、すぐに忘れそうだ。
$ COMMAND1 |& COMMAND2
Bundler gem
コマンドを使って、Gemを新規作成すると、名前の”-“と”_“の違いによって生成ファイルが異なる。
‘_‘の例
$ bundle gem my_tool -t -b
生成されるモジュール
module MyTool
....
end
’-‘の例
$ bundle gem my-tool -t -b
生成されるモジュール
module My
module Tool
....
end
end
このふるまいは、RubyGemsの規約に従っているようで、次のページに説明があった。
Name your gem - RubyGems Guides
_
は複合語に使う-
はGemの拡張に使う例えば、Jekyllなら、Jekyll本体がjekyll
で、jekyll-archives
はその拡張のひとつである。-
で区切られているので、モジュールは、module JekyllArchives
ではなく、module Jekyll
のなかに、module Archives
が定義されていると予想できるし、実際、そうなっている。
先頭から何行目か移動してから、行内でさらに移動する
(progn
(beginning-of-buffer)
(end-of-line 2))
次のように引数Nを指定すると、N/10の位置に移動する。 5を指定すると5/10なので、ちょうど真ん中、 10なら、末尾へ移動する。
(beginning-of-buffer N)
(goto-char (+ (point) 10))
現在値を (point)
で取得し、その結果に文字数を加減することで、新しいポイントへ移動する。
(re-search-forward "word" nil t)
どのやりかたでも、まず
(beginning-of-buffer)
を実行して、カーソルを先頭へ移動したほうがいいかも。
]]>レイアウト用のHTMLを編集していたら、ファイルのパスをこんな書き方にしていた。
<a href="{{ site.baseurl }}/assets/image.jpg"/>feed</a>
以前、古いテーマを参考にして、自分のソースでもこの書き方にしてしまったようだ。Jekyllの仕組みがわかっていれば、理屈はわかるが、いささか ad hoc なやり方のようにも見える。
今は、Jekyllのフィルターを使う(とはいえ、2016年10月にJekyll 3.3で導入されているので、ずいぶん前の話)。
<a href="{{ "/assets/image.jpg" | relatvie_url }}"/>feed</a>
やはり、このほうがJekyll、というかLiquidらしくて、いい感じ。
_config.xml
のbaseurl
を例えば、"/base"
と指定していれば、
<a href="/base/assets/image.jpg"/>feed</a>
こんな感じのHTMLが生成される。
絶対パスでも考え方は同じで、absolute_urlフィルターを使えばよい。
<a href="{{ "/assets/image.jpg" | absolute_url }}"/>feed</a>
わざわざ説明する話でもないけれど、紛らわしいこともあるので、一応、記事にしてみた。
]]>今までは専用のツールを使っていたが、ふとImageMagickでできるのでは?と調べたら、案の定できることがわかったのでメモ。
$ convert -strip 入力ファイル 出力ファイル
このように-strip
オプションを使えるだけでよい。入力と出力を同じファイル名にすれば上書きになるが、簡単に
$ mogrify -strip 入力ファイル
としても上書きできる。
さらにEmacsと組合せることで、GUIなソフト並に手軽に、EXIF情報の掃除ができる。
要するに、dired-do-shell-command
を使うだけで、別にImageMagickに限った話ではない。Emacsユーザーにはお馴染の話だろうが、やっぱりEmacsは最高だと思ったので、あえて説明しておく。
Diredバッファを開き、変換したいファイルを選択しておく。
/Users/bird/images:
total used in directory 28960 available 6194084
drwxr-xr-x 9 bird staff 306 5 13 09:42 .
drwxr-xr-x@ 164 bird staff 5576 5 13 09:39 ..
* -rw-r--r--@ 1 bird staff 2272263 5 5 17:27 image1.jpg
* -rw-r--r-- 1 bird staff 1849400 5 5 17:27 image2.jpg
-rw-r--r-- 1 bird staff 2443233 5 5 17:27 image3.jpg
!
キー押下でdired-do-shell-command
を実行すると、次のようなプロンプトが表示されるはず。
! on * [2 files]:
ここで、次のようなコマンドを入力する。
convert -strip ? new-`?`
` ? と
?
`がファイル名に置き換わり、この例では二つのコマンドがそれぞれ実行される。
convert -strip image1.jpg new-image1.jpg
convert -strip image2.jpg new-image2.jpg
これでEXIF等がないJPGファイルが得られる。Diredを使えば、ファイル名を指定する手間が減るので便利だ。
もし上書きでいいのであれば、mogrifyを使って
mogrify -strip
とすれば、さらに手軽。しかし、その分、誤ってオリジナルを消してしまうリスクが増えるので、こっちは覚えないほうがいいかも。
ちなみに、 ?
と`?`
の違いは、 ?
が前後にスペースが必要なのに対して、`?`
はスペースが使えない場所で使う。
そういうことを知らずに、iPhone7で撮影した写真をMacに取り込んだら、拡張子が、.heic になっていたから、ちょっとビビった。
いろいろ調べてみると、HEIFはすでに国際標準規格になっているようで、安心してJPEGから移行できそうだ。それに、HEIF自体はコンテナすぎないという仕様がなかなかクールで気に入った。
【ミニトピ】iOS 11の写真/動画形式「HEIF」と「HEVC」。従来とは何が違う? - AV Watch Watch
問題は、今使っているMacが10.11のEl Capitanなので、残念ながら、heicには対応していないこと。
というわけで、画像ファイルのフォーマット変換といえば、ImageMagick。
HomebrewのImageMagickは、3ヶ月ほど前のバージョンで、標準でlibheifが有効になっている。 使っていたのが、古いバージョンだったので、まずはアップデート。
$ brew upgrade imagemagick
これで、次にようにすれば、変換できる。
$ mogrify -format jpg image.heic
image.jpgが生成されるはず。
複数のファイルをまとめて変換するなら、ワイルドカードを使えばよい。
$ mogrify -format jpg *.heic
逆にHEICファイルへ変換することもできるようだ。
$ mogrify -format heic image.png
ファイル名を変更するなら、convert
を使う。
$ convert image.heic image.jpg
画像を確認すると、exifやGPSなどの付加情報は保持されている(逆に消したい場合は、-strip
をつける)
当然、heicでしか保持できない付加情報は、除かれてしまうだろう。
画像ファイルのオリジナルとして、heicファイルを保管しておき、必要に応じてconvertしていこうと思う。
通常は、テンプレートに%T
とか%t
などの変数を書いておくのが、org-mode的だと思うのですが、独自のフォーマットが使いたいときは、次の形式を使います。
%<...>
例えば、
%<%Y-%m-%d %H:%M>
は
2018-06-01 12:34
のように変換されます。
%<%m月%d日の記録>
と書いて
06月01日の記録
こんな感じに変換できます。
書式は、elispのformat-time-string
と同じです。
EmacsのInfo Emacs Lisp
の40.8 Parsing and Formatting Times
の次の項目を参照してください。
– Function: format-time-string format-string &optional time zone
以上、メモでした。
]]>ですが、ちょっとやりたいことがあって、いろいろいじっていたところ、基本的なことで勘違いしていることに気付きました。
今まで、例えば、_assets
という名前のディレクリだけを表示したいとき、次のように実行していました。
$ find . -type d -path '*_assets*'
./_assets
./_assets/images
./_assets/images/fc
./_assets/images/lowspeed
./_assets/images/rakuten
./_assets/images/run
./_assets/js
-pathオプションには-path '_assets'
でなく、-path '*_assets*'
と、アスタリスクで囲って指定してやらないと、なにもマッチされません。-path '_assets'
だとなにもヒットしないのです。
なんだか気持ち悪いけれど、そういうもの、ということで深入りしてませんでした。
ですが、いろいろいじってMANページ読んで、いまさら気付いたのです。これ、検索結果の文字列にマッチされているだけなんですね。ディレクトリ構造として認識して処理してるわけじゃない。
前述の例から条件を変えて、-path './_assets'
にして試してみると、
$ find . -type d -path './_assets'
./_assets
このように、完全にマッチした行だけ表示されます。
さらに、検索するディレクトリを.
ではなく、./
へ変更すると、
$ find ./ -type d -path './_assets'
# 結果なし
なにもヒットしなくなります。これは検索している場所は同じなのですが、実行結果のパスの表記が違ってくるのです。
$ find ./ -type d -path '*_assets*'
.//_assets
.//_assets/images
.//_assets/images/fc
.//_assets/images/lowspeed
.//_assets/images/rakuten
.//_assets/images/run
.//_assets/js
単純に、.//_assets
と./_assets
をテキストとしてマッチさせているだけなので、マッチしないから何もヒットしないのですね。表現の形式が違うだけで、同じディレクトリを示しているので、マッチするものだと思い込んでました。
となれば、こんなマッチングもできるはず。
$ find ./ -type d -path '*s/fc*'
.//_assets/images/fc
.//_site/assets/fc
/
はパスの区切りという思い込みがあったので、今までこんな発想はありませんでした。
単純にテキストとしてマッチさせているだけなので、findって意外と簡単だなと思えるようになりました。
]]>~/.bash_profile
や~/.bashrc
のような初期化ファイルを起動時に読んでくれないようです。
不便なので調べてみたところ、きちんとそれ用のファイルが用意されていました。
通常のshellのスクリプトの代りに、~/.emacs_${shell名}
のファイルを用意しておけば、shellモードの起動時に読み込まれます。このファイルがなければ、~/.emacs.d/init_${shell名}
が読み込まれます。
僕はbashを使っているので、次のようなファイルを用意すればいいわけです。