Gulpでcntl+cが効かない場合の対処法

Gakuです。
最近react+reduxあたりをちょろちょろ触っておりまして、それに付随しgulpもがっつり触っています。
その際、gulpコマンドを実行後、終了させるためにcntl+cを押しても反応しない問題に遭遇したので、その対処法を備忘録として残したいと思います。

現象

gulpfile.jsをgulpコマンドで実行し、終了しようとcntl+cを押しても反応しない。

[18:46:03] Using gulpfile ~\develop\projects\ToDoTool\electronapp\gulpfile.js
[18:46:03] Starting 'compile'...
[18:46:03] Finished 'compile' after 19 ms
[18:46:03] Starting 'electronstart'...
[18:46:03] Finished 'electronstart' after 4.42 ms
[18:46:03] Starting 'watch'...
[18:46:03] Finished 'watch' after 21 ms
[18:46:03] Starting 'default'...
[18:46:03] Finished 'default' after 2.28 μs
[gulp] compiled: 398 ms
[18:46:08] Starting 'compile'...
[18:46:08] Finished 'compile' after 11 ms
[gulp] compiled: 132 ms
[18:46:16] Starting 'compile'...
[18:46:16] Finished 'compile' after 5.21 ms
[gulp] compiled: 139 ms


←ここでcntl+cを押してもgulpが終了してくれない。

gulpfile.js

gulpfileはこんな感じで記述しています。

var gulp         = require('gulp');
var exec         = require('child_process').exec;
var babel        = require('gulp-babel');
var es2015       = require('babel-preset-es2015');
var react        = require('babel-preset-react');
var duration     = require('gulp-duration');

//設定
var props = {
  jsfilepath : 'src/scripts/**/*.{js,jsx}',
  outputdir  : 'src/dist'
};

//bebelで変換
gulp.task('compile',function(){
  exec('pwd');
  gulp.src(props.jsfilepath)
    .pipe(babel({
        presets: [es2015,react]
    }))
    .pipe(duration('compiled'))
    .pipe(gulp.dest(props.outputdir));
});

//electronの実行
gulp.task('electronstart', function(){
  exec('electron .', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
  });
});

//ファイル変更監視
gulp.task('watch',function(){
  gulp.watch(props.jsfilepath,['compile']);
});

gulp.task('default', ['compile','electronstart','watch']);

問題の対処法

この問題はwindows10環境でelectronアプリを起動した際に発生しました。
原因としては詳細に追求できていないのですが、gulp.watchが常駐しているため、cntl+cを押してもgulp.watchの処理が上書きされて終了できない状態になっていると推測します。
対処法としては、monitorctrlcというpackageを利用し、強制的にcntl+cを実行できるようにすると解消することが可能です。
[blogcard url=”https://github.com/pandell/node-monitorctrlc”][/blogcard]

monitorctrlcのインストール

npm install monitorctrlc --save

monitorctrlcの組み込み方

gulpfile.jsにmonitorctrlcをimportし、gulp.watchを記述するタスクにmonitorctrlc関数を記述します。

var gulp         = require('gulp');
var exec         = require('child_process').exec;
var babel        = require('gulp-babel');
var es2015       = require('babel-preset-es2015');
var react        = require('babel-preset-react');
var duration     = require('gulp-duration');
var monitorCtrlC = require('monitorctrlc'); //ここと

//設定
var props = {
  jsfilepath : 'src/scripts/**/*.{js,jsx}',
  outputdir  : 'src/dist'
};

//bebelで変換
gulp.task('compile',function(){
  exec('pwd');
  gulp.src(props.jsfilepath)
    .pipe(babel({
        presets: [es2015,react]
    }))
    .pipe(duration('compiled'))
    .pipe(gulp.dest(props.outputdir));
});

//electronの実行
gulp.task('electronstart', function(){
  exec('electron .', function (err, stdout, stderr) {
    console.log(stdout);
    console.log(stderr);
  });
});

//ファイル変更監視
gulp.task('watch',function(){
  monitorCtrlC();  //ここを追加
  gulp.watch(props.jsfilepath,['compile']);
});

gulp.task('default', ['compile','electronstart','watch']);

これでばっちりcntl+cの終了コマンドを実行することが可能です。

[18:47:57] Using gulpfile ~\develop\projects\ToDoTool\electronapp\gulpfile.js
[18:47:57] Starting 'compile'...
[18:47:57] Finished 'compile' after 20 ms
[18:47:57] Starting 'electronstart'...
[18:47:57] Finished 'electronstart' after 4.75 ms
[18:47:57] Starting 'watch'...
[18:47:57] Finished 'watch' after 18 ms
[18:47:57] Starting 'default'...
[18:47:57] Finished 'default' after 2 μs
[gulp] compiled: 366 ms



[20:18:48] '^C', exiting

RaspberryPi買ったら最初にやること

Gakuです。
1年半前に買ったRaspberryPiなのですが、押し入れに入れているだけではもったいないと思い、またちょこちょこイジイジしています。
そこで今回はRaspberryPiを購入したら最初にやった方が良い設定を少し掲載したいと思います。

前提

OSはrasbianを導入しています。かつ無線LAN子機でインターネットには接続可能な状態からスタートです。

apt-getの更新

まずはapt-getのパッケージリストを下記コマンドで更新します。

sudo apt-get update

これでOK。

無線LANのUSBアダプタのパワーマネジメント機能をOffにする

RaspberryPiを操作していると私の場合、頻繁にアクセスが切れます
原因としては無線LANのUSBアダプタにはパワーマネジメント機能というものが存在し、アクセスを行わないと電気を節約するために省エネモードになるらしいです。
そこでこのパワーマネジメント機能をOffにする設定を行います。

sudo vi /etc/modprobe.d/8192cu.conf

//編集点
# Disable power saving
options 8192cu rtw_power_mgnt=0 rtw_enusbss=1 rtw_ips_mode=1

//最後に再起動
sudo reboot

これでOK

VNCサーバの立ち上げ

RaspberryPiを触る際、いちいち周辺機器を接続するのはスタイリッシュではありません
RaspberryPiの周辺は配線を少なくスッキリさせたいものです。
そこで、RaspberryPi上でVNCを立ち上げ別PCから遠隔操作を行えるように設定します。

まずは下記コマンドでVNCサーバをインストールします。

sudo apt-get install tightvncserver

これでtightvncserverが導入されましたので、tightvncserver起動してみます。

tightvncserver

起動すると初期パスワードの設定を求められますので設定します。(PWは8文字までですので注意です。)

You will require a password to access your desktops.

Password://8文字までのパスワード入力
Verify://確認用にパスワード入力
Would you like to enter a view-only password (y/n)? n //閲覧専用PWを設定するか。(ここではn)

New 'X' desktop is raspberrypi:1

Creating default startup script /home/pi/.vnc/xstartup
Starting applications specified in /home/pi/.vnc/xstartup
Log file is /home/pi/.vnc/raspberrypi:1.log

導入は終わりです。別PCで立ち上げたVNCサーバに接続してみます。
今回はWindowsからUltraVNCを使用しアクセスします。
「VNC Server:」の部分に[RaspberryPiのIP::5901]を入力しConnectボタンを押します。
無題
パスワードを求められますので、tightvncserverで先程設定したパスワードを入力しLog Onをクリックします。
無題
接続できればOKです。
無題

自動起動設定

RaspberryPiを起動した際にtightvncserverを自動起動するように設定します。
sudo vi /etc/init.d/vncbootで開き下記のように編集します。

#! /bin/sh
# /etc/init.d/vncboot

### BEGIN INIT INFO
# Provides: vncboot
# Required-Start: $remote_fs $syslog
# Required-Stop: $remote_fs $syslog
# Default-Start: 2 3 4 5
# Default-Stop: 0 1 6
# Short-Description: Start VNC Server at boot time
# Description: Start VNC Server at boot time.
### END INIT INFO

USER=pi
HOME=/home/pi

export USER HOME

case "$1" in
start)
echo "Starting VNC Server"
#Insert your favoured settings for a VNC session
su $USER -c '/usr/bin/vncserver :1 -geometry 1440x900 -depth 24'
;;

stop)
echo "Stopping VNC Server"
su $USER -c '/usr/bin/vncserver -kill :1'
;;

*)
echo "Usage: /etc/init.d/vncboot {start|stop}"
exit 1
;;
esac

exit 0

編集が完了したら権限設定と自動起動設定を行います。

$ sudo chmod 755 /etc/init.d/vncboot
$ sudo update-rc.d vncboot defaults

これでrebootを行いUltraVNCで接続できれば完了です。

固定IPの設定

VNCサーバーの自動起動設定をしたとしても、DHCPでIPを割り振っている場合、今までアクセスしていたIPとは別のIPを振られる心配があります。
そうなるとアクセスできなくなってしまうので、先に固定でIPを割り振っておきましょう。
sudo vi /etc/dhcpcd.confで開き最下部に下記を追記します。

interface wlan0
static ip_address=192.168.10.20/24 //192.168.10.20に固定IPを入力(今回は20と振った)
static routers=192.168.10.1 //デフォルトゲートウェイのIPアドレス
static domain_name_servers=192.168.10.1 //デフォルトゲートウェイのIPアドレス

これでrebootし、UltraVNCで設定したIPアドレスでアクセスできればOK。

おわりに

とりあえず、RaspberryPiの初期設定をこんな感じで毎回行っています。
これをすることでRaspberryPiにマウスやキーボード、HDMIでのモニタ接続を排除できます。
それにしてもRaspberryPiは楽しいっすね!夢が広がります(´・ω・`)

参考文献

Raspberry Piで無線LANの反応が悪い時の対処法
tightvncserverの自動起動で困っている人向け
Raspbian(jessie)の固定IPアドレス設定方法