いぇいいぇい

ASP.NET、PHPを中心に書いています

gulp-watchで新規ファイルが認識しない問題が解決

以下のようにgulp-watchでファイル監視しているとき、ふと新規ファイルやリネームしたファイルが認識しないことに気づきました。

gulp.watch('./sass/**/*.scss', ['sass'])

調べて見たところ、解決策があったのでここで紹介します。

gulp-watchで新規ファイルを認識させる方法

gulp-watchではファイル監視にGazeを使っています。

Gazeでは、作業ディレクトリ(cwd)というパラメータがあります。規定値はprocess.cwd()となっており、最初の例では規定値が使われます。

どうもGazeではファイル監視に問題を抱えているようで、パラメータの指定の仕方にコツがいるようです。(参考:#41)

以下のようにcwdパラメータを指定して、監視パスから./をなくすと、新規ファイルでもうまく認識できるようになりました。

gulp.watch('sass/**/*.scss', { cwd: './' }, ['sass'])

これはGazeのバグかと思いますが、もう何年も放置されているようですね。。

GazeはGruntでも使われているようなので同じ問題があるかもしれませんね。

stackoverflow.com

github.com

複数のGitHubデプロイキーを同じマシンで使う方法

GitHubでは、デプロイキーは1つのリポジトリにのみ関連付けられます。ですので、通常はリポジトリ毎に異なるSSHキーを作成してデプロイキーとします。

ここで困るのが、同じマシンで複数のリポジトリをデプロイしたい場合です。例えば複数サービスを同じVPSに共存させる場合や、同じサービスだけど複数のリポジトリがある、という場合などです。

GitHubの場合、ホスト名とSSHキーを関連付けるために~/.ssh/configで以下のように指定しますが、単純に複数個指定してもうまくいきません。

Host github.com
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_proj1
Host github.com
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_proj2
> git clone git@github.com:tsu1980/proj2.git
ERROR: Repository not found.
fatal: The remote end hung up unexpectedly

同一マシンで複数デプロイキーを共存させる方法

そこで、以下のようにHostの値を分けて定義し、Git URLも同じ値を指定してやるとうまく動きます。

Host github.com-proj1
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_proj1
Host github.com-proj2
    Hostname github.com
    User git
    IdentityFile ~/.ssh/id_proj2
> git clone git@github.com-proj2:tsu1980/proj2.git
Initialized empty Git repository in /var/projects/proj2/.git/
remote: Counting objects: 833, done.
remote: Compressing objects: 100% (480/480), done.
remote: Total 833 (delta 400), reused 748 (delta 315), pack-reused 0
Receiving objects: 100% (833/833), 800.30 KiB | 523 KiB/s, done.
Resolving deltas: 100% (400/400), done.

Hostの値とGit URLのホスト名部分を一致させることがポイントです。この例ではgithub.com-proj2の部分になります。

cloneではなく既存リポジトリのURLを変更するにはgit remote set-urlを使ってください。

参考

Managing deploy keys | GitHub Developer Guide

superuser.com

Windows10でスタートアップフォルダを一発で開く方法

Windows10になってスタートメニューからスタートアップが消えました。今までスタートメニューから辿っていたのでとても困ります。スタートアップフォルダ自体は以前と同じ場所にあるのですが、それがとても深い階層にあるため、記憶だけではなかなか辿り着けません。スタートアップフォルダがどこにあるのか、簡単に開く方法はないのか、調べてみました。

一発でスタートアップフォルダを開く方法

  1. Windows+Eでエクスプローラーを起動します
  2. アドレスバーにshell:startupと入力してエンターキーを押します

f:id:sumi2:20160420122152p:plain

これでスタートアップフォルダを開けます。

ちなみに、すべてのユーザーのスタートアップフォルダを開くにはshell:common startupと打ちます。

hostsファイルが反映されない問題が解決

hostsファイルに書いたホスト名が反映されない問題で試した方法と原因、解決策についてまとめてみました。

症状

僕の場合はChromeでは名前解決できるのに、IEやpingではダメという状態になりました。

hostsファイルの中身

まずはhostsファイル(C:\Windows\System32\drivers\etc)の中身。

127.0.0.1       localhost abc1.localhost abc2.localhost abc3.localhost abc4.localhost abc5.localhost abc6.localhost abc7.localhost abc8.localhost abc9.localhost

全部で10個のホスト名を127.0.0.1に振り向けています。

このうち、abc9.localhostについてのみ、IEなどで名前解決できない状態になりました。

(本当は15個くらいあったのですが、表記上10個にしています。)

環境

  • Windows 10

名前解決の確認方法

名前解決ができているかどうかは、pingが通るかどうかで確認します。

ping abc.localhost

NGの場合はこうなります。

C:\WINDOWS\system32>ping abc9.localhost
ping 要求ではホスト abc9.localhost が見つかりませんでした。ホスト名を確認してもう一度実行してください。

OKの場合はこうなるはずです。

C:\WINDOWS\system32>ping abc9.localhost
abc9.localhost [127.0.0.1]に ping を送信しています 32 バイトのデータ:
127.0.0.1 からの応答: バイト数 =32 時間 <1ms TTL=128
...

1) DNSキャッシュのクリア

まずは定番のDNSキャッシュのクリアです。

ipconfig /flushdns
ipconfig /displaydns

しかし、状態は変わらずでした。

2) hostsファイルのアクセス権限

ファイルのアクセス権限をいじれば治ったという書き込みを見たので、ファイルにEveryoneフルコントロールのアクセス権限を追加してみました。 しかし、これも効果ありません。

セキュリティ上よくないのでアクセス権限は元に戻しておきます。

3) 1行あたりのホスト名制限

なんとWindowsのhostsファイルは1行あたりのホスト名に最大9個までという制限があるそうです。

superuser.com

確認してみると僕のhostsファイルには1行あたり10個以上のホスト名を記載していました。この情報に従って1行あたり9個までとなるようにhostsファイルを修正しました。

127.0.0.1       localhost abc1.localhost abc2.localhost abc3.localhost abc4.localhost abc5.localhost abc6.localhost abc7.localhost abc8.localhost
127.0.0.1       abc9.localhost

ただ、修正してもpingがまだ通りません。。

4) hostsファイルを1回削除してみる

何らかの理由により、hostsファイルの変更が検知できないような状態になっていると考え、一旦hostsファイルを削除してみることにしました。 もちろんファイルは別名のファイルに退避しておきます。具体的には以下の手順です。

cd C:\Windows\System32\drivers\etc
mv hosts hosts.bak
mv hosts.bak hosts

これでhostsファイルが正しく認識し、すべてのホスト名が名前解決できるようになりました。

まとめ

今回のケースでは1行に10個以上のホスト名を書いたことが原因でした。Chromeでは10個以上でも問題なく認識していたのですが、Chromeは独自にhostsファイルを読みに行っているのかもしれませんね。

また、hostsファイルの変更を検知させるためにファイルを一旦削除する方法が有効でした。これも1つの発見でした。

Evernote(Windows版)で書式なしでペーストする方法

Evernoteでコピーした文章をペーストすると、通常はリッチテキスト形式でペーストされます。リンクや色など書式付きになるわけですね。この動作はページ内容を見た目そのままで貼り付けたい場合はいいのですが、テキストだけを貼り付けたい場合は邪魔な動作になってしまいます。

今回はWindows版のEvernoteで、書式なしでペーストする方法と、それを既定の動作にする方法を掲載します。

書式なしでペーストするには

リッチテキスト形式ではなく、書式なしでペーストするには、[テキストとして貼り付け]コマンドを実行する方法があります。こうすることでプレーンテキストのみを貼り付けることができます。

メニューからの場合

Evernoteのメニューから、[編集]-[テキストとして貼り付け]を選びます。

ショートカットの場合

「Ctrl+Shift+V」キーを押します。

けど、貼り付けのショートカットキーといえば通常は「Ctrl+V」。Evernoteだけ異なるキーを押すというのはなんかイヤ。。

書式なしペーストを既定の動作にするには

もし「Ctrl+V」と「Ctrl+Shift+V」を置き換えることができれば、書式なしペーストを既定の動作にすることができます。しかし残念ながらEvernoteではショートカットキーのカスタマイズ機能は用意されていません。

そこで、AutoHotKeyという便利ツールを使います。AutoHotKeyはキー入力をフックして自由にカスタマイズすることができる常駐アプリです。今回のケースのようにアプリケーション側でキーカスタマイズ機能がない場合でもキー入力を置き換えることができます。

ただ導入には多少の手間がかかるのがデメリットですね。OS標準の機能としてくれてもいいような機能なんですけど。Evernoteを常用していて、どうしてもキーを置き換えたい!というひとはこの機会に導入しましょう。

導入方法は長くなるので省略し、スクリプトのみ紹介します。

;Swap Ctrl+V to Ctrl+Shift+V in Evernote
#IfWinActive, ahk_class ENMainFrame
    ^v::Send,^+v
#IfWinActive, ahk_class ENMainFrame
    ^+v::Send,^v

このスクリプトを追加することで、「Ctrl+V」と「Ctrl+Shift+V」を置き換えることができました。長く使うものだからこそストレスなく使えるようにしたいですよね。

autohotkey.com

(LINQ)SkipWhileの使い方、間違えていませんか?

はい!僕、間違えていました!

SkipWhile、単純に「条件に一致する要素をスキップする」ものだと思っていました。まったくの勘違い。アホですねー。

正しくは「条件に一致する限り要素をスキップする」ということみたいです。

以下サンプルです。

void Main()
{
    var names = new string[] { "太郎", "花子", "太郎", "花子" };
    var namesExclude = new string[] { "太郎" };

    // namesから"太郎"を除外したいとします。
    // まずはSkipWhileの場合
    var nameFiltered1 = names.SkipWhile(s => s == "太郎");
    Console.WriteLine("SkipWhile:");
    foreach (var name in nameFiltered1) {
        Console.WriteLine(name);
    }

    // Whereの場合は全要素フィルタリングできます
    var nameFiltered2 = names.Where(s => s != "太郎");
    Console.WriteLine("Where:");
    foreach (var name in nameFiltered2) {
        Console.WriteLine(name);
    }
}

出力結果

SkipWhile:
花子
太郎
花子
Where:
花子
花子

多分勘違いしたのはWhileの逆バージョンがほしくて、SkipWhileを見た時に「ああ、あるじゃん、これこれ」みたいな感じで勝手に自分の都合よく解釈しちゃったんだろうと思います。怖い怖い。

Realtek HD Audioの音飛び問題が解決

去年にPCをアップグレードしたときから悩まされてきた問題が解決しました。非常にうれしい。

現象

現象としては数分から数十分の頻度で音飛びが発生。具体的には突然音が「プツッ」っと止まって、1秒くらいでまた音が再開するというもの。

原因は音飛びじゃなかった

最初は音飛び問題ということでエフェクトとか、コーデックが悪さをしているんじゃないかと思っていろいろ探していたのですが原因わからず一旦諦めていました。

先日OSをWindows10にアップグレードしてからも同じ現象が発生して落ち込んでいました。ところが現象発生時に「デバイスが切断されました」、「デバイスが接続されました」的なバルーン通知が出るではないですか。

これは音飛びじゃなくてデバイスの切断が発生する問題じゃないかと思い再度ネット検索したところ、以下のページを見つけました。Realtek HD Audioにジャックなどのコネクタの切断/接続が発生する問題があることがわかりました。

www.sevenforums.com

www.youtube.com

解決

リンク動画を参考にオーディオマネージャという常駐プログラムを停止し、exeもリネームしました。今のところ問題は発生していません。よかった。

具体的な手順は以下です。

  1. タスクマネージャからRAVCpl64.exeを停止
  2. "C:\Program Files\Realtek\Audio\HDA"のRAVCpl64.exeをRAVCpl64_renamed.exeなどにリネーム

(RtkNGUI64.exeも同様にリネームしたほうがいいかもしれません)

参考までに環境は以下です。

  • Windows 10(64bit)
  • Realtek High Definition Audio(driver 6.0.1.7535)
  • H97-PRO

(2016/02/10 追記)

Windowsの自動更新などでドライバが再インストールされた場合は、exeが復活してしまうようです。その際は、再度リネームすればOKです。