Wi-Fiダイレクトで直接デバイスに無線接続するときに、いちいち/etc/network/interfaces
をいじってifdown wlan0 && ifup wlan0
とかしていた訳ですが、いかんせん面倒くさい。
そこで、SSIDとパスワードを指定するだけでお手軽に接続できるスクリプトを作りました。
Raspbian Wheezy、Ubuntu14.04で動作確認済みです。ちなみにMac編はこちらです。
wificonn_linux.sh
#!/bin/bash
set -u
export LANG="C"
function usage() {
cat <<EOT
Usage: bash ${0##*/} <interface-name> <network-SSID> <password>
EOT
}
# 引数チェック
if [ $# -ne 3 ]; then usage && exit 1; fi
# 指定されたインターフェースが存在するか調べる
iwconfig $1 > /dev/null 2>&1
if [ $? -ne 0 ]; then
echo "Device named '$1' not found."
exit 2
fi
# すでに接続されていれば終了
iwconfig $1 | grep -wq "ESSID:\"$2\"" && ifconfig $1 | grep -q 'inet addr'
if [ $? -eq 0 ]; then
echo "Already connected."
exit 0
fi
# インターフェースを再起動
ifconfig $1 down
ifconfig $1 up
if [ $? -ne 0 ]; then
echo "Failed to activate interface $1"
exit 4
fi
# 指定のSSIDを持つアクセスポイントがあるか調べる
iwlist $1 scan | grep -wq "ESSID:\"$2\""
if [ $? -ne 0 ]; then
echo "The wi-fi network with SSID:'$2' not found."
exit 3
fi
# wpa_supplicantが動いていたら殺す
pkill -f "wpa_supplicant.+-i *$1 .*"
# SSIDを設定
iwconfig $1 essid $2
# WPA認証タイムアウト秒数
WPA_AUTH_TIMEOUT=20
is_connected=false
current_time=$(date +%s)
# wpa_supplicantをnohupで起動し接続。stdbufはバッファリングを防止するために必要
while read -t ${WPA_AUTH_TIMEOUT} line; do
echo " $line"
echo $line | grep -wq 'CTRL-EVENT-CONNECTED'
if [ $? -eq 0 ]; then
is_connected=true
break
fi
# タイムアウト判定
if [ $(($(date +%s) - ${current_time})) -gt ${WPA_AUTH_TIMEOUT} ]; then
echo "Timeout."
break
fi
done < <(nohup bash -c "wpa_passphrase $2 $3 | stdbuf -oL wpa_supplicant -i $1 -D wext -c /dev/stdin 2>&1 &")
if ! $is_connected; then
echo 'WPA authentication failed.'
pkill -f "wpa_supplicant.+-i *$1 .*"
exit 5
fi
# IPアドレス割り当て
ifconfig $1 | grep -q 'inet addr'
if [ $? -ne 0 ]; then
dhclient $1
ifconfig $1 | grep -q 'inet addr'
if [ $? -ne 0 ]; then
echo 'IP address cannot not be assgined.'
exit 6
fi
fi
echo 'Connected successfully.'
exit 0
使いかた
$ bash wificonn_linux.sh <interface-name> <network-SSID> <password>
- 実行にはルート権限が必要です。一般ユーザーは
sudo
してください。 -
<interface-name>
はwlan0, wlan1などのインターフェース名を指定します。インターフェース名はiwconfig
で確認できます(老婆心)。 - 生のパスワードを入力する必要があるので、共同のマシンでは注意してください。
一応解説
Debian系Linuxで無線LANの設定を行うときは、種々の解説サイトにもあるように
-
wpa_passphrase
の出力をリダイレクトし、PSKの暗号化と同時に設定ファイルを作成する -
/etc/network/interfaces
にwpa-conf <設定ファイルのパス>
と書く
のが一般的です。こうしておくとwpa_supplicant
が勝手に立ち上がり、設定ファイルを読み込んでよろしく認証を行ってくれます。今回は設定ファイルを使わないため、wpa_supplicant
の設定ファイルを-c /dev/stdin
として標準入力に設定し、wpa_passphrase
の出力をパイプで流しこむようにしました。
-
wpa_supplicant
を起動させたらそのログ出力を一行ずつ読み込んで、OKっぽいログ(CTRL-EVENT-CONNECTED)が出ていたら成功とみなします。もっといい判定方法があるかも? - 一定時間以上経ってもダメならタイムアウトエラーにしています。環境によっては
WPA_AUTH_TIMEOUT
の値を調整する必要があるかもしれません。 -
stdbuf -oL
はバッファリング動作を変更するコマンドで、wpa_supplicant
が出力をバッファに貯めずに一行ずつ吐き出すようにしています。 - IPアドレスは
dhclient
コマンドで動的に割り当てています。
バグや指摘などありましたら、ぜひコメント欄かTwitterの方までお願い致しますm(__)m