CentOS 7にApacheを導入しようとして挫折する物語
これは、CentOS 7.2をインストールしたRaspberry Pi 3にApacheを導入する物語である。
筆者は、CentOSを3年もいじっているので、Apacheを入れるなんて朝飯前。
サーバを何回も初期化して、幾度とApacheを入れ直してるんで
Apacheを入れるのなんかカップラーメンにお湯を注ぐぐらい簡単だよって思ってます。
やることを頭に描き
## Apacheのインストール # yum install httpd ## Apacheの起動および自動起動の設定 # service httpd start # chkconfig httpd on ## 80番ポートの開放 # vim /etc/sysconfig/iptables -A INPUT -m state --state NEW -m tcp -p tcp --dport 80 -j ACCEPT // 追加 # service httpd restart
サラッと、これを実行して、http://__IP_Address__ にアクセスして下の画面を確認しよう!
第一章 Apacheを起動させよ
一瞬でApacheをインストールし、いざApacheを起動させようとした時、
普段なら下みたいに表示されるのに、表示されない…
まぁ、いっか。
きっと起動してるはず!
# いつも表示される結果 # service httpd start httpd を起動中: httpd: Could not reliably determine the server's fully qualified domain name, using localhost.localdomain for ServerName [ OK ]
# 今回、表示された結果 # service httpd start Redirecting to /bin/systemctl start httpd.service
第二章 挫折への前触れ
じゃあ、次にポートの開放をやってみよう。
えっ…「/etc/sysconfig/」に「iptables」がない…!
うん、きっと80番ポートはデフォルトで空いてるはず…
第三章 大いなる挫折
さぁ、http://__IP_Address__にアクセスして、いつもの画面を確認しよう!
「ページを開けません。このページのあるサーバが応答しません。」
な、な、なぜだ…!!
いつもの段取りでやってるのに、なんで出来ない…
いつもiptablesあるのに、なんでない…
ラズパイ用のCentOSだとないのかな…
第四章 解決へのアプローチ
実は、解決へのヒントが表示されていました。
そうです、「Redirecting to /bin/systemctl start httpd.service」です。
実は、CentOS 7になってから自分が大好きだったserviceコマンドがなくなっていました。
ついでに、iptablesもなくなってました。
新しいやり方では、「systemctl」というコマンドを使います!
## Apacheの起動および自動起動の設定 # systemctl start httpd.service # systemctl enable httpd.service ## 80番ポートの開放 # firewall-cmd --add-service=http --zone=public # firewall-cmd --add-service=http --zone=public --permanent
参考:Apache httpd 2.4 を CentOS 7 に yum でインストールする手順 | WEB ARCH LABO
で、http://__IP_Address__にアクセスしてみると、Apacheの画面を確認することができるようになりました。
CentOSでキーボードのレイアウトを変更
Raspberry Pi 3にCentOS 7.2を入れており、
設定をする時にSSHからじゃなくてキーボードを使ったんですが、
どうやっても「:(コロン)」が打てないんですよねぇ…
昔、Virtual BoxにCentOSを入れた時も同じ問題が発生して解決したので
次、同じ問題が発生しても忘れないようにメモしときたいと思います。
環境
CentOS 7.2
解決策
# localectl list-keymaps | grep jp106
jp106
とコマンドを入力して、「jp106」があることを確認してください。
ちなみに、localectlコマンドはCentOSのロケールを確認および変更するために使うコマンドのようです。
ロケールとは、ソフトウェアに内蔵される、言語や国・地域ごとに異なる単位、記号、日付、通貨などの表記規則の集合。または単に、利用する言語や国・地域の指定。多くのソフトウェアやプログラミング言語は、使用する言語とともにロケールを設定し、ロケールで定められた方式に基づいてデータの表記や処理を行う。
引用:ロケールとは|locale|ロカール - 意味/定義 : IT用語辞典
なるほど、また賢くなってしまいました…笑
(初めて見た時、「ローカルじゃないの?」って思っちゃいました…)
$ localectl set-keymap jp106
これで完了です。
無事にコロンが打てるようになりました!
wgetとcurlの違い
サーバ関係の作業をしていると、よくwgetを使っているサイトを見るんですが、
稀にcurlを使っているサイト見かけます。
どちらも、ダウンロードをするのに使うコマンドなんですが、
その違いを調べてみました。
wget
読み方は「ダブルゲット」です!
自分は、ずっと「ダブリューゲット」って読んでました…笑
みなさん、ご存知の通り、ファイルをダウンロードする時に使うコマンドです。
wgetには、2つの特徴があります。
- 再帰的にファイルをダウンロードすることができる
- 左手だけで入力することができる
curlと違って、再帰的にファイルをダウンロードすることができるのが最大の特徴です。
wgetで対応しているプロトコルは、HTTP・HTTPS・FTPのみです。
実は、アップロードもできたんですね…
今まで、wgetコマンドにオプションを使ったことがなかったんですが、便利なオプションがあるんですね!
ここで、wgetコマンドの便利なオプションを紹介したいと思います。
# index.htmlファイルをダウンロード wget http://xxxxx/yyyyy/zzzzz/index.html # オプション「-r」 # ディレクトリにあるファイルを全部ダウンロード wget -r http://xxxxx/yyyyy/zzzzz/ # オプション「-I」 # 再帰的にダウンロードする場合に、階層の数を指定する wget -r -I 3 http://xxxxx/yyyyy/zzzzz/ # オプション「-A」 # 指定した文字列のあるファイルをダウンロードする wget -r -A png http://xxxxx/yyyyy/zzzzz/ # オプション「-R」 # 指定した文字列のあるファイルはダウンロードしない wget -r -A jpg http://xxxxx/yyyyy/zzzzz/
curl
読み方は「カール」です。
curlの最大の特徴は、
- サポートが充実している
です。
例えば、wgetと異なり、curlで対応しているプロトコルには、
FTP、FTPS、Gopher、HTTP、HTTPS、SCP、SFTP、TFTP、TELNET、DICT、LDAP、LDAPS、FILE、POP3、IMAP、SMB/CIFS、SMTP、RTMP、RTSP
があります。
他にも、wgetでは対応していないものが、curlでは対応されているという場合があります。
# オプション「-o(小文字)」 # ダウンロードしたファイルを指定したファイルに出力する curl -o index2.html http://xxxxx/yyyyy/zzzzz/index.html # オプション「-O(大文字)」 # index.htmlファイルをダウンロード curl -O http://xxxxx/yyyyy/zzzzz/index.html # 連番ファイルをダウンロードする curl -O ftp://ftp.example.com/data[001-100].txt
curlコマンドは、SFTPプロトコルに対応しているので、
curlコマンドを使って、SFTPでアップロードできないのかな…?
どうやるのか、分からないので
教えていただけると嬉しいです!
参考:Linuxコマンド集 - 【 wget 】 ファイルをダウンロードする:ITpro
Linuxコマンド集 - 【curl】ファイルのダウンロードやアップロードを行う:ITpro
Raspberry Pi 3の起動時に自動無線LAN接続(2)
前回の続きです!
前回:Raspberry Pi 3の起動時に自動無線LAN接続(1) - usmysaの開発メモ
前回、コマンドから無線LANに繋ぐ方法を紹介しました。
今回は、シェルスクリプトを使って、それを自動化するスクリプトを作成したいと思います。
シェルスクリプトとは
シェルスクリプトとは、複数の処理をまとめて行う(バッチ処理)ときに使われる、OSのシェルが直接解釈・処理できるスクリプト。
引用:シェルスクリプトとは|shell script - 意味/定義 : IT用語辞典
そもそもスクリプトとは…
コンピュータプログラムの種類の一つで、機械語への変換や実行可能ファイルの作成などの過程を省略または自動化し、ソースコードを記述したら即座に実行できるようなプログラムのことをスクリプトという。
引用:スクリプトとは|script|scr - 意味/定義 : IT用語辞典
なるほど。
スクリプトとは、コンパイルが必要ない言語のことを言うんですね。
スクリプト言語の例としては、Python・Rubyなどがあります。
つまり、シェルスクリプトとは、シェルのスクリプト(=コンパイルが必要ないプログラム)ってことですね!
いざ、スクリプトを書いてみる
スクリプト名は、「wifi-connect-script」となっています。
コードは以下のとおりです。
# !/bin/sh # chkconfig: 2345 99 20 # description: wifi-connect-script LoopConnectWiFi(){ ssid=$1 password=$2 nmcli d wifi connect ${ssid} password ${password} result_connect='nmcli d wifi connect $ssid password $password' success_str="Device 'wlan0' successfully activated with" if [ ! 'echo ${result_connect} | grep ${success_str}' ]; then sleep 3 LoopConnectionWiFi $ssid $password fi } readonly ssid_array=($(nmcli d wifi)) readonly wifi="SSID名" readonly wifi_pass="SSIDのパスワード" case "$1" in start) for ssid in "${ssid_array[@]}"; do if [ $ssid = $wifi ]; then LoopConnectWiFi $wifi $wifi_pass fi done ;; stop) ;; *) ;; esac
解説
# !/bin/sh
まず、これを書くことで、「このテキストはシェルスクリプトである」ということを宣言します。
なので、シェルスクリプトを書く場合は絶対必要な部分となります。
# chkconfig: 2345 99 20 # description: wifi-connect-script
これは、chkconfigの設定を記述しています。
2345 | 起動させるランレベル | ランレベルを数字で入力。複数ある場合は、連続して2345のように各。- と書くと全てのランレベルでOFFとする。 |
99 | 起動時の優先度 | 数値(1~99までで記入するのが一般的)で記入。数字が大きくなるほど後で起動される。 |
20 | 停止時の優先度 | 数値(1~99までで記入するのが一般的)で記入。数字が大きくなるほど後で停止される。 |
0:システムの停止
1:シングルユーザーモード、ネットワーク無し
2:マルチユーザーモード(NFSマウントなし)
3:マルチユーザーモード(コンソール)、ネットワーク有り
4:未使用
5:マルチユーザーモード(X Windows)、ネットワーク有り
6:システム再起動
引用:ランレベルとは(chkconfig) - Linux入門 - Webkaru
「description」はサービスの説明です。
適当に書いといて大丈夫です。
readonly ssid_array=($(nmcli d wifi)) readonly wifi="SSID名" readonly wifi_pass="SSIDのパスワード"
「nmcli d wifi」はWiFiの一覧を表示するコマンドで、その結果を「ssid_array」という配列に代入しています。
また、ここら辺の変数は書き換えることはないと思うので、一応「readonly」にして読み込み専用にしています。
case "$1" in start) for ssid in "${ssid_array[@]}"; do if [ $ssid = $wifi ]; then LoopConnectWiFi $wifi $wifi_pass fi done ;; stop) ;; *) ;; esac
この部分は、switch文になってます。
「$1」っていうのは、シェルスクリプトでは第1引数を表します。
ここは覚えとく必要があります。
で、for文を使ってWiFi一覧の中から接続したいWiFiがあったら、LoopConnectWiFiメソッドを呼び出すという仕組みになっています。
この時、switch文で「start」の場合しか使ってないので、if文で書いた方が正しいのかなと思います。
nmcli d wifi connect ${ssid} password ${password}
前回で紹介しましたが、これでWiFiに接続しています。
result_connect='nmcli d wifi connect $ssid password $password' success_str="Device 'wlan0' successfully activated with" if [ ! 'echo ${result_connect} | grep ${success_str}' ]; then sleep 3 LoopConnectionWiFi $ssid $password fi
「result_connect」には、WiFiに接続した後に表示される文章を代入しています。
そして、result_connectが失敗していた場合、3秒ごとに再接続するような仕組みになっています。
chkconfigに登録する
$ sudo mv wifi-connect-script /etc/init.d/ $ sudo chkconfig --add wifi-connect-script $ sudo chkconfig wifi-connect-script on
これで、Raspberry Pi 3が起動した時に自動で無線LANに接続します!
個人的に、ソースコードにパスワードを書くのは非常に嫌いなんですが、良い方法を知っている方がいれば教えて下さい!
参考:bash: コマンドの実行結果を配列や変数に代入する | deadwood
(CentOS6まで)自作のサービスをchkconfigで登録する
シェルスクリプトで関数を利用する - Qiita
文字列Aに文字列Bが含まれるか - わからん
CentOSの起動スクリプトを書き方(+注意点) | 本日も乙
Raspberry Pi 3の起動時に自動無線LAN接続(1)
Raspberry Pi 3には、2とは違い
無線LANのモジュールがデフォルトで付いているらしいです。
で、Raspberry Pi 3に無線経由でSSHをするには、以下のような手順が必要です!
1. ラズパイに有線ケーブルをつないで、SSHで入ったあと、無線LANに接続する
2. ラズパイに有線ケーブル・キーボード・ディスプレイをつないで、無線LANに接続する
無線経由でSSHしたくても、どっちにしろ有線で一度繋がなきゃいけないんです…
それって面倒くさくないですか!?
ってことで、今回はラズパイが起動した時点で、自動的に無線LANに接続するようなスクリプトを作成したいと思います。
環境
Raspberry Pi 3
CentOS 7
そもそも、どうやって無線LANに繋げるのか
ラズパイを無線LANに接続するには、「nmcli」というコマンドを使います。
「nmcli d」というコマンドを打って、ネットワーク機器の一覧を表示します。
# nmcli d DEVICE TYPE STATE CONNECTION eth0 ethernet connected eth0 lo loopback unmanaged --
しかし、無線LANであるwlan0が認識できておらず、見当たらりません。
そこで、wlan0を認識するには、Firmwareというソフトウェアを準備しなくちゃいけないっぽいです。
# yum -y install git # git clone https://github.com/RPi-Distro/firmware-nonfree.git # mv /lib/firmware/brcm{,.org} # cp -R firmware-nonfree/brcm80211/brcm /lib/firmware/brcm # curl -L --output /usr/bin/rpi-update https://raw.githubusercontent.com/Hexxeh/rpi-update/master/rpi-update # chmod +x /usr/bin/rpi-update # rpi-update # reboot
で、リブートした後、もう一度ネットワーク機器の一覧を確認してみると
DEVICE TYPE STATE CONNECTION eth0 ethernet connected eth0 wlan0 wifi disconnected -- lo loopback unmanaged --
と、wlan0が認識されるようになります。
で、無線LANに接続するには、以下のような手順で接続することができます。
# nmcli d wifi connect ___ssid___ password ___password____ # nmcli d DEVICE TYPE STATE CONNECTION eth0 ethernet connected eth0 wlan0 wifi connected ___ssid___ lo loopback unmanaged --
ちなみに、無線LANの一覧を確認したい場合は、以下のようなコマンドを打てば確認できます
# nmcli d wifi
参考:Raspberry Pi 3 へCentOS7導入からWifi無線LAN接続まで設定メモ - YOMON8.NET
Raspberry Pi 3にCentOS 7をインストール
先日、Raspberry Pi 3を買ってみました!
お値段は5500円ぐらいですが、ケースや16GBのMicroSDやMicroUSBケーブルを買ったら合計1万円以上かかってしまいました…
友達から「ラズパイは安い!」って聞いてたのに、いざ買ってみると周辺機器を揃えるのにお金がかかってしまいます
バイトをしてない大学生には、ちょっと痛手です…
せっかく、買ったのでRaspberry Piで面白いものを作りたいと思います!
Raspberry Piは「Raspbian」というOSが推奨されてるっぽいんですが、
自分はCentOSが使い慣れているので今回、CentOS 7をインストールさせたいと思います。
準備
まず、以下のURLからイメージファイルをダウンロードします。
http://buildlogs.centos.org/centos/7/isos/armhfp/
このダウンロードしたファイルは「xz」という初めて見る拡張子になってます。
xz は、データ圧縮プログラムのひとつ、およびその圧縮データのフォーマットである。LZMA2圧縮アルゴリズムを利用している。先行するgzip, bzip2と比較すると、圧縮時にはこれら以上の時間とメモリを消費するが、圧縮率では概ね優位で、また伸張速度もgzipより多少遅いがbzip2よりは速い傾向にある。このことから、特にアーカイブ配布用途として、.tar.gzや.tar.bz2と並んで採用されるケースが増えている(.tar.bz2にとって代わる場合もある)。アーカイブ機能はない。
引用:xz (ファイルフォーマット) - Wikipedia
ふーん、よく分からないッス!笑
で、このファイルを解凍するために、コマンドをインストールする必要があります。
自分のPCはMacなので、Macでコマンドをインストールする方法を紹介したいと思います。
$ brew install xz $ xz -d xxxx.xz #解凍する方法
MicroSDに書き込み
PCにMicroSDを差し込んで、MicroSDカードの場所を調べる必要があるそうです。
$ diskutil list #: TYPE NAME SIZE IDENTIFIER 0: GUID_partition_scheme *121.3 GB disk0 1: EFI EFI 209.7 MB disk0s1 2: Apple_CoreStorage Macintosh HD 120.5 GB disk0s2 3: Apple_Boot Recovery HD 650.0 MB disk0s3 /dev/disk1 (internal, virtual): #: TYPE NAME SIZE IDENTIFIER 0: Apple_HFS Macintosh HD +120.1 GB disk1 Logical Volume on disk0s2 FD2938A5-EF87-4FFA-B79B-C2D6B41336E0 Unlocked Encrypted /dev/disk2 (internal, physical): #: TYPE NAME SIZE IDENTIFIER 0: FDisk_partition_scheme *15.9 GB disk2 1: Windows_NTFS SDCard 15.9 GB disk2s1
で、表示されたものを確認すると、MicroSDの場所は「disk2s1」ということが分りました。
次に、MicroSDをアンマウントします。
sudo diskutil umountDisk /dev/disk2 Unmount of all volumes on disk2 was successful
MicroSDの場所が「disk2s1」なのに、「disk2」をアンマウントするのはよく分からないです…
ここは、注意ですね!
$ sudo dd bs=1m if=xxxxx.img of=/dev/disk2 3072+0 records in 3072+0 records out 3221225472 bytes transferred in 1501.605507 secs (2145188 bytes/sec)
これで、MiroSDに書き込むことができました!
ちなみに、「dd」は書き込み(=コピー)をするコマンドっぽいです。
詳しくは、以下のURLを参照して下さい。
ddコマンド:Linuxコマンド集 - 【 dd 】 ファイルの変換とコピーを行う:ITpro
自分が犯した失敗
diskutilコマンドでMicroSDの場所が「disk2s1」と表示されていたので、
書き込みの時、「of=/dev/disk2s1」ってしたら、書き込みに失敗してました。
書き込みに失敗していたので、Raspberry Piが起動しなくて、泣いてました…
なので、みなさんご注意ください!
Rubyの勉強(2)
前回の続きです!
前回:Rubyの勉強(1) - usmysaの開発メモ
それでは、さっそく気温データのCSVファイルをRubyで読み込んで、データベースに追加したいと思います。
CSVファイルが読み込めない!
for csv_i in 1..15 do filename = "data-" + csv_i.to_s + ".csv" csvData = CSV.read(filename) end
15個あるCSVファイルをfor文を使って、読み込もうとしたら
# ruby setDB_weatherData.rb /usr/local/rbenv/versions/2.3.1/lib/ruby/2.3.0/csv.rb:2016:in `=~': invalid byte sequence in UTF-8 (ArgumentError) from /usr/local/rbenv/versions/2.3.1/lib/ruby/2.3.0/csv.rb:2016:in `init_separators' from /usr/local/rbenv/versions/2.3.1/lib/ruby/2.3.0/csv.rb:1538:in `initialize' from /usr/local/rbenv/versions/2.3.1/lib/ruby/2.3.0/csv.rb:1273:in `new' from /usr/local/rbenv/versions/2.3.1/lib/ruby/2.3.0/csv.rb:1273:in `open' from /usr/local/rbenv/versions/2.3.1/lib/ruby/2.3.0/csv.rb:1339:in `read' from setDB_weatherData.rb:19:in `<main>'
というエラーが表示されました。
「invalid byte sequence in UTF-8 (ArgumentError)」っていうことは、utf-8じゃないから問題が発生してるのかな?
原因
このCSVファイルをどうやって作ったかは分からないですが、
Excelで作ったCSVはSJISとして保存されるようです。
Excelで作った場合だと、終端文字が"\r\n"になるそうです。
その結果、エラーが発生してうまくいってないようです。
解決策
CSV.foreach('CSVファイル名', headers: true, row_sep: "\r\n", encoding: "SJIS") do |row| puts row[0] #rowの0番目を表示 end
ちなみに、「row_sep」とは行区切り文字列として使用する文字列を返すメソッドらしいです。
参考:Rails3でExcelで作ったSJISのCSVファイルをUTF-8で読み込む方法 - temitaの不思議空間
ライブラリ:csv > クエリ:row_sep > バージョン:1.9.3 | るりまサーチ (Ruby 1.9.3)
何とか解決できたので、はやくデータベースに追加して
夜ご飯を食べたい…