たまに18歳未満の人や心臓の弱い人にはお勧めできない情報が含まれることもあるかもしれない、甘くなくて酸っぱくてしょっぱいチラシの裏。RSSによる簡単な更新情報を利用したりすると、ハッピーになるかも知れませんしそうでないかも知れません。
の動向はもえじら組ブログで。
宣伝。日経LinuxにてLinuxの基礎?を紹介する漫画「シス管系女子」を連載させていただいています。 以下の特設サイトにて、単行本まんがでわかるLinux シス管系女子の試し読みが可能!
発売から2年経ってニュース性がなくなっており、新規にレビューされることももはやなさそうなので、自分で読者の気持ちになってレビューしてみようという謎企画です。ダイマです。露骨ですね。それではいってみましょう。
本書は端的に言えば、「Linuxサーバーをコマンドで操作する事はあるが、決まりきったコマンド以外は使えずにいて、他にどんな事ができるのかわからないでいる人」「コマンド操作の訳の分からなさに挫折して、すっかり敬遠するようになってしまった人」のための本と言えます。
タイトルに「入門」とありますし、「マンガで分かる何々」と言うと全くの初心者向けの本という印象を受けますが、本書はむしろ全くの初心者にはハードルが高いくらいかもしれません。初心者から中級者へステップアップしようとしている人、ステップアップの仕方が分からず躓いている人向けのケーススタディ集というのが、本書の適切な位置付けでしょう。
世の中の「マンガでわかる何々」な本には大きく分けて2つの種類があります。1つは直前にレビューしたわかばちゃんシリーズのような、初心者の抵抗感を減じる導入・緩衝材としてマンガを使う物。もう1つは学研の「~のひみつ」シリーズや「マンガで分かる心療内科」のように、解説そのものがマンガになっている、解説のための表現手法としてマンガを使う物。実用書では前者のタイプが多いですが、本書は後者です。
本書はLinux初心者の「みんとちゃん」を主人公に立てて、みんとちゃんが遭遇する様々なトラブルや困った事態に対する解決策をメンターの「大野先輩」に教わる、という形でLinuxのコマンド操作を解説する構成になっています。前の話で紹介されたコマンドを後の話で使うという事はありますが、カリキュラム通りに学んでいくレッスン形式ではなく個別のケーススタディ形式で、マンガとしても4~8ページごとに1話完結のオムニバスとなっています。
それ故に本書は構成上のゴールが無く、スタイルとしては「技術雑誌の連載マンガの単行本」と言った方が適切でしょう(実際、本書は月刊誌である日経Linuxでの連載の最初の2年分をまとめた物で、次の2年分をまとめた物が続刊として出ています)。「1冊の技術書として通読することで何かを達成する、という性質の本」ではないことを把握しないまま読むと、尻切れトンボな最後で面食らってしまうかもしれません。
絵柄や絵の巧拙については、好みもある話なのでなんとも言えませんが、「これは何の事を描いているのか?」が分かる・解説として読む妨げにならない程度の水準は満たしているのではないかと思います。
本書で解説されている話題は、sshによるリモート操作からシェルスクリプトの基本までというLinuxの一般的な操作についてです。舞台設定やタイトルは「システム管理」を想起させますが、Webサービスの運用や組み込み機器の開発など、Linuxをコマンドで操作する際には共通して必要になる範囲の知識と言えます。コマンド操作を使い始めた頃に躓きがちな「あるある」な場面が多く、各トピックはいずれも実践的です。
また、紹介されているコマンドやツールは古くから今に至るまで現役で使われ続けている物がほとんどで、発売から2年が経過(※2017年現在)したものの、内容は陳腐化していません。一度読み込んでおけば、その後長く役に立つ知識が身に付くタイプの本と言えるでしょう。
ただ、本書の知識が長く役立つと言える理由は、単に解説されているツールが伝統的な物だからだけではありません。
コマンド操作が敬遠される理由の1つに、「覚えるのが辛い」というのがあります。コマンドの数は無数にあり、またそのそれぞれが多数のオプション指定を受け付けるため、組み合わせは膨大な数になり、とても覚えきれるものではありません。しかし実際には、中・上級者でもコマンドやオプションをすべて丸暗記しているわけではなく、よく使うコマンドがどのように作用し・どう相互に連携して・どんな結果になるのか、ということを頭の中で想像して適宜組み合わせて目的を達成している場合の方が多いです。
本書ではコマンドやファイルといった「登場人物」達を擬人化し、時にはナビゲーターであるみんとちゃん達自身をその図の中に飛び込ませることで、熟達した人達が頭の中で思い浮かべている主観的な「コマンド操作の向こうで起こっている事」のイメージをマンガとして描いています。文章での説明や抽象的な図よりもずっと生の感覚に近い「(擬似的な)映像体験」を得て、「そうか、先輩達にはコマンド操作の世界がこう見えているんだ!」と思うことができれば、抵抗感も薄れるのではないでしょうか。
全体を通して解説が24トピックというのは少ないように見えるかもしれませんが、個々の話題を丁寧に描いているので情報量自体は多く、実際に読むと物足りなさは感じないと思います(というか、自分は通読してものすごく頭が疲れました)。
誉めるべき所がある一方で、技術解説の書籍としての本書には難点もあります。
まず前述した通り、「入門」というタイトルとは裏腹に、本書には基本的なファイル操作のコマンドなどに対する説明が含まれていないため、そのレベルでLinuxの知識が無い人には本書はおすすめできません。事前に最低限、cd
やls
、cp
、rm
といったファイル操作の基本コマンドの使い方は把握している必要があります。
(ちなみに、Web上で無料公開されている特別編ではその辺りの基本知識が解説されています。いまいち自信が無い場合は、本書を読む前にまずそこから目を通しておくと良いでしょう。)
文字を読む印刷物として、スクリーンショットの中で文字の色がグレーになっていて背景との判読が難しい箇所があるのも地味に辛いです。読みやすいように文字の色を調整したり、文字はすべてフォントで入れなおしたりといった工夫が欲しかった所です。
また、根本的な所で、手元のPCがWindowsである場合の事が全く考慮されていないというのも、初心者を対象とした本と考えると重大な問題です。Linuxのデスクトップ環境やmacOSであればターミナルからの操作で問題無いのですが、Windowsの場合は、Windows 10の開発者向けの機能であるUbuntu on Windowsや、MSYSやCygwin、もしくは仮想マシンにLinuxをインストールするといった準備をしないと、本書の内容そのままの実践はできません。Tera Termなどのシェル環境一式を伴わない端末エミュレータを使う場合は、本書の内容をすべてサーバー間の話(Tera Termからの接続先が本書中の「みんとちゃんの手元のPC」に相当する)として読み替える必要があります。これは恐らく、連載の掲載誌である日経Linux誌が「Windows XPからUbuntuへの移行」といった記事を多く扱っており、Linuxのデスクトップ環境を使うのが当たり前という雰囲気があることから、それに引きずられたのでしょう……
上記のような難点はあるものの、本書にユニークな価値があるのは確かです。
クラウド、SaaS、DevOpsといった最近の技術的な潮流では、サーバーを操作するために自分でLinuxのコマンドを操作するという場面は減っていっています。しかし、障害発生時のトラブルシューティングや、サービス開発時のデプロイ手順の確立など、シェル上でのコマンド操作の知識が必要な場面は依然としてあります。
丸暗記でもコマンド操作は使えるには使えますが、コマンドや構文の意味を理解していないままだと応用が利かず、パターンから外れた途端にお手上げになります。また、コマンドの使い方をその都度検索しても、やりたい事に合致する例がすぐに見つかるとは限りませんし、最悪の場合、闇雲に実行したコマンドでファイルが消えてしまったなんて事も起こります。でも「自分が今何をしようとしているのか」を正確にイメージできるようになれれば、自信を持ってコマンドを組み合わせて、時には組み合わせを変えて、自在に使えるようになるはずです。本書は、そのようなレベルに自分自身を引き上げて、コマンドリファレンスなどの網羅性の高い情報ソースを活用できるようになるための、手がかりとなる1冊と言えるでしょう。
ということで、読者目線でのセルフレビューでした。
直前に読んだのがパッケージとして非常にまとまりの良いわかばちゃんのGit本だったので、それと読み比べると「シス管系女子」のパッケージとしての不完全さがどうしても目についてしまい、気が付くと「ここがダメ、そこがダメ」という事ばかり書きたくなってしまうのが辛い所です。でも、書評は駄目な所をあげつらうだけの物ではなく、その本の持つ価値を必要としている人のもとにちゃんと届くよう補助線を引く物でないといけないと思い、実用書としての評価をするよう努めてみました。
本書を薦められた人が「馬鹿にされた」と感じて拒絶してしまうという話を見ると、ああやっぱりピンクとオレンジがまずかったのかなあとか、タイトルがチャラそうなのが良くなかったのかなあとか、もっと成年誌っぽい絵柄だったらよかったかなあとか、詮無い事をつい色々考えてしまいます。レビュー内ではその辺りの事にあまり触れなかったのですが、実際どのくらい評価に影響するものなのでしょうか。気になります。
1つ前のエントリで、Rubyでバッククォートで実行した外部コマンドの標準出力を何故か受け取れないと書いてたんだけど、追記した通り、これは「RubyスクリプトがCGIで実行されているせいで標準入出力がCGI用に使われており、バッククォートで起動した子プロセスはその標準入出力を引き継ぐから、子プロセスから標準出力に出した内容が文字列として呼び出し元のスクリプトに返される代わりに、CGI経由でクライアント(GitHubのService Hookのエージェント)に返されてしまっている」ということだった(すとうさんに教えていただいた)。
で、対策として spawn()
と Process.waitpid()
を使うと良いというアドバイスを頂いて、以下のように直してみた。
#!/usr/bin/ruby1.9.1
require "cgi"
require "shellwords"
require "json"
require "logger"
require "stringio"
SYNC_SCRIPT = "/home/piro/shared/or/tools/upload_nightly_xpi.sh"
RELEASE_SCRIPT = "/home/piro/shared/or/tools/release_addon.sh"
SSH_KEY = "/path/to/secret_key"
BASE_DIR = "/home/piro/shared/xul"
USER = "piro"
logger = Logger.new("/home/piro/shared/post-receiver.log")
#logger = Logger.new("/dev/null")
logger.level = Logger::INFO
# 子プロセスの実行結果(標準出力)を常に文字列で受け取るユーティリティ
def run(command_line)
pipe_in, pipe_out = IO.pipe
Process.waitpid(spawn(command_line, [:out, :err] => pipe_out))
pipe_out.close
pipe_in.read
end
cgi = CGI::new
puts "Content-Type: text/plain\n\n"
begin
payload, = cgi.params["payload"]
payload = JSON.parse(payload)
project = payload["repository"]["name"]
project_dir = File.join(BASE_DIR, Shellwords.escape(project))
makefile = File.join(project_dir, "Makefile")
if File.exist?(project_dir) and File.exist?(makefile)
logger.info "build #{project}"
sudo = "sudo -u #{USER} -H"
command_line = "#{sudo} #{SYNC_SCRIPT} -i #{SSH_KEY} -b #{BASE_DIR} -d #{project_dir}"
logger.info command_line
logger.info run(command_line)
command_line = "cd #{project_dir}; git describe"
logger.info command_line
current_commit = run(command_line).strip
logger.info current_commit
# 現在のコミットがタグを打ったまさにそのコミットである場合、
# git describeの結果はタグ名だけになる。
# なので、それをトリガーにしてリリース処理を走らせる。
if !current_commit.empty? && !current_commit.match(/\A.+-[0-9]+-g[0-9a-f]+\z/)
logger.info "=> release commit"
command_line = "#{sudo} #{RELEASE_SCRIPT} -i #{SSH_KEY} -b #{BASE_DIR} -n #{project}"
logger.info run(command_line)
else
logger.info "=> regular commit"
end
end
logger.info "ok"
p "ok"
rescue Exception => error
logger.error error
logger.info "ng"
p "ng"
end
run()
というのを定義していて、ここでパイプを作って spawn()
の子プロセスの標準入出力に設定して、実行が終わるまで待ってパイプから実行結果を文字列として読み出す、ということをしている。(パイプを使う方法もすとうさんに教えていただいた。)
あと、このスクリプトは ~/public_html 以下に置いてるんだけど、apacheユーザで実行されてしまってファイルのアクセス権が……という事にも地味に悩まされていて、それでsudoを使ってたんだけど、suexecというApacheモジュールを使うと良いと教えてもらって sudo a2enmod suexec; sudo service apache2 restart としてみた。でもこの状態で git pull とかさせるとどういうわけか「error: cannot open .git/FETCH_HEAD: Permission denied」と言われてしまって(whoの結果ではapacheユーザじゃなくpublic_htmlがあるユーザになってるのに、何故だ……)、それで結局相変わらずsudoしている。
以前、update.rdf関係を半自動生成するために頑張ったことがあって、各アドオンの紹介ページのHTMLからupdate.rdf(未署名)を作るあたりまでは自動化できてたんだけど、そこ止まりになっててまだまだ手動でやらなきゃいけないことが多くて、億劫で余計にリリースが滞る……という状況になっている。
それで、これじゃいかん!と思ってもっと自動化を進めることにして、とりあえずリポジトリのmaster/HEADを元に自動でテスト用ビルドを作るようにはした。
で、その知見を元にもう少し頑張って、開発版ではなくリリース版の方ももっと自動化するというチャレンジをしている。
僕は会社では主にUbuntuを使用しているのですが、Sambaで共有してるフォルダの中にあったThunderbirdのプロファイルっぽい物を「あれ、これテスト用に作ったやつだっけ」と思ってWindowsから削除してしまった後になって「あ、これメインで使ってるThunderbirdのプロファイルへのシンボリックリンクやがな」と気がついて慌てて止めたものの、時既に遅しでメールフィルタもなんもかも消えてしまった。せめてNautilusからの削除だったらゴミ箱に残ってたのに……!
Thunderbirdは起動した状態のままだったので、設定エディタを開いて適当な設定値をいじって、一番重要なprefs.js(アカウント情報が入ってる)だけは書き出させた。アドレス帳は全く使ってないに等しい状態だったので、消えても構わない。メールフォルダの中身も、IMAPで自宅・サーバ上・このPCの3箇所で同じ物を複製しあってる状態だったのでなんとかなる。しかし、このPCでしか設定してなかったメールフィルタが消えてしまったのは痛い。
ということでなんとかundeleteする方法はないかと検索したら、extundeleteというのを使えばいいらしいという事が分かった。
試してみたらかなりの数のファイルを救出できたけど、なんやかやで一部壊れてる物もあった。とりあえず目当てのメールフィルタは無傷で救出できたので、なくさないようにDropboxに入れて自宅にもコピーを置いておこう……
自宅ではWindows Vistaで秀丸エディタを使っている僕は会社では主にUbuntuを使用していますが、viでもemacsでもなくgeditがメインのテキストエディタだったりします。という事を言うとワリと失笑されがちですが、geditそんなにわるくないよ!! むしろメモ帳(notepad)よりはずっといいよ!! タブの挙動とかはキモイけど!! シンタックスハイライトもあんまり賢くないけど!! あとShift_JISで「\」(半角バックスラッシュ)を含んだファイルを開くと勝手にUnicodeの円マークに変換しちゃうせいでそのまま保存するとJavaScriptの正規表現とかがぶっ壊れがちだけど!!
そんなgeditに対する不満の1つに、検索で正規表現を使えない、特に、正規表現による一括置換ができないという点が挙げられます。改行やタブをコピペして検索したり置換したりしようとした時には勝手に「\n」とか「\t」とかエスケープされて表示されますが、こういうのを自分で入力しても期待通りには認識されません。
んでまあずっと諦めていたのですが、改めて探してみたら、geditで正規表現検索できるようにするプラグインというのが世の中にはあったのですね。
以下、Ubuntu 10.10での導入手順。
置換先の入力欄の上で何か操作しないと、「Replace All」などのボタンが有効化されません。置換先の文字列を空にしたまま置換しようとすると(=マッチ箇所を削除する操作をしようとすると)「すべて置換」ボタンが有効にならないという風な事が起こるので、何か入力してそれをまた消す、という操作を必要に応じてやらなくてはなりません。という風に若干作りが甘いと思われる部分はあるものの、これでやっとgeditだけでもそれなりの事ができるようになったという事の方が嬉しくて、もうこれだけで満足してしまいがちな僕がいます。
あと「grepもできたらいいなあ」「でもってgrepでヒットしたファイルを一括置換したいなあ」とかも思って検索してみたら、grepだけならプラグインですぐにできる事も分かりました。
こちらで紹介されているGedit File Search PluginをRegex Search and Replaceと同じようにしてインストールして「編集」→「設定」→「プラグイン」で「File Search」にチェックを入れてgeditを再起動すると、「検索」メニューの「Find in files...」でgrepできるようになります。ヒット箇所をクリックするとその位置までスクロールした状態でファイルを開いてくれるので良いですね。さすがに「grepで置換」まではできませんが……
Windowsには昔からよく知られた便利機能でCommand Prompt Hereという物がありまして、要するに「フォルダの右クリックメニューから、そのフォルダをカレントディレクトリにした状態でコマンドプロンプトを開く」というやつなんですが、Windows 95の頃にはPower Toysというユーティリティ集でこの機能を簡単に追加できたりもしました。
これと同じ事をGNOMEのNautilusでやるパッケージがあったんですね。その名もnautilus-open-terminal。Debianにも同名のパッケージがあるようです。
CUIメインで使ってる人には用がなさそうですが、僕みたいにヌルい人にはあると便利です。
Ubuntuの場合、初期状態では1つのプロセスで開けるファイルの最大数は1024個までと決まっているようで、それ以上の数のファイルを開こうとするとエラーになる。普通に使っててこの制限を気にする場面は全然無いんだけど、自動テストで大量のファイルを処理するようなやつを実行するとたまにこの制限に引っかかってしまうことがある。
現在の制限がどうなっているかは、ulimit -a で調べられる。open filesと書いてある所の数値がそれだ。
この制限を一時的に緩和するには、ulimit -n 任意の整数 とやればいいらしい……んだけど、ulimitはsudoでは実行できないようだった。rootで操作すればいいんだけど、普通にUbuntuを使ってるとrootにはなれないので、この方向を頑張るのはちょっとやる気が出ない。
代わりの方法として、/etc/security/limits.conf を編集するという手もある。例えばすべてのユーザに対してファイルの最大オープン数を2048個に増やしたければ、/etc/security/limits.confに以下のような指定を書き加える。
* soft nofile 2048 * hard nofile 2048
これで再起動すれば、すべてのユーザについて、1プロセスで扱えるファイルの最大数が2048にまで増える。
Ubuntu 9.10 Karmic KoalaからUbuntu 10.04 LTS Lucid Lynxにアップグレードした。9.10の諸問題が解消されている事に期待して。
所感。
To re-enable php in user directories comment the following lines(ユーザのディレクトリでPHPを有効にしたかったら以下の行をコメントアウトせよ)と書かれていた事に気がついて、
<IfModule mod_userdir.c>~</IfModule>
をコメントアウトしたら、ファイルのダウンロードにならずにPHPのスクリプトとして解釈された結果が返るようになった。なんかあればまた追記していく。
WEPで無線LANに繋がらなくなったのでWPAにしたあと、正常に動いてるように見えたし、ハイバネーションからの復帰後もちゃんと動いてたんだけど、Ubuntuのアップデートがかかってその後再起動したらまたネットワークに繋がらなくなってしまった。
ログビューワでログを見た感じではハードウェア自体は認識されてるようで、 検索結果の見よう見まねで /etc/network/interfaces を以下のように編集してsudo /etc/init.d/networking restartしたら、とりあえずネットワークには繋がるようになった。
auto lo iface lo inet loopback auto wlan0 iface wlan0 inet dhcp wpa-essid ssid wpa-psk 共有キー
が、この状態だとGnomeパネル上のNetwork Managerアプレットが全く機能しなくなって、無線のアクセスポイントも何も切り替えられない。
キーワードを変えてさらに検索していたら、/etc/network/interfacesを消せばなんとかなるという話があったので、これ危なそうだなーと思いながら試してみた(interfacesを別の名前に変更してみた)ところ、再起動したらNetwork Managerアプレットがちゃんと動くようになった。WPAのアクセスポイントにもつながってる。
でもCtrl-Alt-F2とかでコンソールに切り替えるとログインプロンプトが出てなくて、これでまたトラブルになったら手の施しようがないと思ったのでもう少し検索してみたところ、今度はUbuntuフォーラムのやり取りがヒットした。やっぱりというかなんというか、最低限の記述はないといけないのか。ということでinterfacesの内容を以下のように削って最小限(?)にしてみた。
auto lo iface lo inet loopback auto wlan0
再起動したら、Ctrl-Alt-F2でもログインプロンプトがちゃんと出てて、Network Managerで無線LANにも繋がるという状態になった。
なんかどんなにやっても無線LAN繋がらなくなってしまって、以前詰まったステルスモードのアクセスポイントの問題でもないようだし、もう完全に手詰まりになってしまった。
daemon.logを見てみると、昨日のログではNetworkManagerのsupplicant connection stateがdisconnected→scanning→associating→associated→completedになってたのに、今日のログではassociatingの次にdisconnectedに戻ってしまってて、wpa_supplicantが「Associated with……」のログを出してなかった。
で、このあたりのキーワードで検索してたら2chのスレが引っかかった。
45 :login:Penguin:2008/10/05(日) 09:47:09 ID:6n0tInIX >>43 WEP 使っていたら、一度接続された後に /etc/init.d/network restart 入れてやらないと、通信できません > X61@Mo4.1 素直に WEP 捨てて、wpa_supplicant で WPA2-PSK/AES にするのが良いでしょう
今回の現象とはぜんぜん違う話題だけど、WEPじゃダメでWPA2なら問題ないというケースがあるのか。
僕の環境の問題も同じようにして解決されることを期待して、前々からWEP捨てなきゃと思ってたのをやっとWPA2-PSK(WPA2-パーソナル)に変更した。無線ルータの設定を変えた後、Ubuntuのネットワークマネージャで繋ぎ直したら、あっさりと繋がった。
結論:WEPは捨ててWPA2にしましょう。