Monthly Archives: June 2013

WordPress Popular Posts(ja)

English version is available in WordPress Popular Posts

ブログ投稿や固定ページの閲覧回数や、コメントの数を計算して、サイトのどこがもっとも利用されているかを訪問者に知らせるプラグインがあります。昔はどこのサイトにも「アクセスカウンタ」というものが設置してあって、閲覧回数を数値で表示していました。サイト作成者の虚栄心を満たすにはよいツールでしたが、ブログの投稿でそれをやろうというのがこのタイプのプラグインです。ランキングにする、というのがミソで、ウェブでデータベースを普通に使えるようになったおかげですね。ただし、現在は、Google Analyticsや、Automattic社の運営するWordPress.comとそれが提供するJetpackのようなプラグインがあって、人気のある投稿を表示するのに、ウィジェットを使うことができるようになっているので、必ずしも自前のデータベースで運用しなければならないということはなくなりました。

Google APIを利用するものには、Google Analyticsと連動した、Google Analytics Popular Postsというのもありますが(*1)、今回はWordPress Popular Posts(WPPと略記)の方を使ってみます。WPPは、Google Analytics Popular Postsとはちがって、プラグイン単体で使えるというお手軽さが魅力です。

  1. もうメンテナンスされていないかもしれません。日本語のサポートページはつながらず、2年近く更新がとまっています。

Super Cacheと同時に使えないという報告もちらほらあります。この手のプラグインは、画面推移をトリガーにして、現在のページIDの閲覧数を加算していくというデータの持ち方をするのが基本ですから、そのままの動作を維持しながらキャッシュ系のプラグインと同時に使うのは難しいでしょう。WPPはページIDの取得を、the_contentをトリガーにして、WordPressの$post変数を通して受け取るモードと、$_POST[‘ID’]を使うモードを分けて、キャッシュ系プラグインがある場合は後者を使うことで、両立させようとしているようです。が、My Thumbnails keep dissapearing after upgradeを見ると、W3 Total CacheでCDNを使っているとサムネールが表示されないとか、まだ不具合があるようです。その他、qTranslateにも対応させてあるようです。「一緒には使えません」、「仕様です」って言ってもいいのに、ちゃんと対応しようとしている姿勢は好感が持てます。

さて、SQLite Integrationで使う場合ですが、インストール、有効化は問題なくできますが、そのままでは意図したとおりに動作しません。原因は、エイリアスにシングル・クオートを使っているためです。たとえば、こういうところ。

カラムのエイリアスには全てシングルクオートが使われ、テーブルのエイリアスには使われていません。バッククオートを使っている場所は一か所もありません(*1)

  1. ANSIモードでMySQLを使う場合、Oracleでは、ダブルクオーテーションが使えます。MS SQL Server、MS Accessではスクエアブラケット([])が使えます。

ためしに実験してみました。コマンドラインで、sqlite3を使っています(バージョンは3.7.14)。

sqlite> SELECT p.ID AS id, p.post_title AS title FROM wp_posts AS p;
id          title
----------  ----------
1           Hello world!
2           サンプルページ

sqlite> SELECT p.ID AS 'id', p.post_title AS 'title' FROM wp_posts AS 'p';
id          title
----------  ----------
1           Hello world!
2           サンプルページ

同じ出力が得られます。ためしにダブルクオーテーションにしても同じ出力が得られました。その他、MS SQL Server互換のスクエア・ブラケット([])、MySQL互換のバッククオート(`)も使うことができます。SQL As Understood By SQLite, SQLite Keywordsを読むと、シングルクオートの場合だけ、文字列リテラルと解釈されるようですが、文字列リテラルが許されない場所で使われると、識別子として解釈されるそうです。

一方のMySQLはというと、MySQLに付属のユーティリティmysqlで試してみると、下のようになります。

mysql> SELECT p.ID AS id, p.post_title AS title FROM wp_posts AS p;
+----+-----------------------+
| id | title                 |
+----+-----------------------+
|  1 | Hello world!          |
|  2 | サンプルページ        |
+----+-----------------------+

mysql> SELECT p.ID AS 'id', p.post_title AS 'title' FROM wp_posts AS 'p';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''p'' at line 1

mysql> SELECT p.ID AS 'id', p.post_title AS 'title' FROM wp_posts AS p;
+----+-----------------------+
| id | title                 |
+----+-----------------------+
|  1 | Hello world!          |
|  2 | サンプルページ        |
+----+-----------------------+

どうやら、テーブルのエイリアスにシングルクオートを使うとエラーになるようです。ダブルクオートを使っても同じです。バッククオートは、テーブルエイリアスに使っても動作しました。

さて、上の実験を見ると、WordPress Popular Postsのコードは全く問題がないように見えます。事実、問題ないのですが、SQLite Integrationの関数を通すと、違った振る舞いをします。まず、クオートなしの場合。

実行結果は下のようになります。予想どおりですね。

Array
(
    [0] => Array
        (
            [id] => 1
            [title] => Hello world!
        )

    [1] => Array
        (
            [id] => 2
            [title] => サンプルページ
        )
)

クオートをつけた場合。

これを実行すると、空の配列が返ります。

Array
(
)

これは、SQLite Integrationのシングルクオートとダブルクオートの扱いによります。SQLite Integrationは、PHPのPDO::bindValueをエミュレートする形で、クオートの中を別の配列に保存し、SQLステートメントのほうは":param_number"というようなプレースホルダに変えてPDO::prepareを実行します。正しい場所で変換が行われれば、PDOStatementオブジェクトが返り、PDOStatement::execute()にその配列を渡して実行すれば正しい結果が返ります。詳しくは、PHP Data Objectsを参照していただければと思いますが、例をあげましょう。

:param_0のところには、もともと’Hello world!’というようなクオートされたデータが入っていたところです。もともとの機能としては、次のような使い方を想定しているようです。

  1. データがユーザの入力の場合、SQLステートメントに最初から入れるのではなくて、危険な入力を事前に処理できる(*1)
  2. 同じステートメントを値を変えただけで実行するときに、ステートメントがキャッシュされるので、2度目以降のオーバーヘッドがない
  1. WordPressが持っている$wpdb->prepare()メソッドはこれを模した仕組みで、addslashes()かmysql_real_escape_string()[PHP5.5.0で非推奨]を使ってデータをエスケープします。

ところが、後の例は、正しい場所に:param_numがないために、PDOStatement::prepareの段階でエラーになります。オブジェクトが作られず、例外が発生しますが、この例外はSQLite Integrationがキャッチして、エラー処理をします。この例外の結果は、$wpdb->suppress_errorsをfalseに、$wpdb->show_errorsの値をtrueにそれぞれセットすると出力されるようになりますが、デフォルトでは出力されません。

さて、これを回避する手段は今のところありません。申し訳ありませんが、WordPress Popular Postsの方を書き換えてご利用ください。というわけで、パッチです。上記の修正のほか、2か所ほどプロパティとメソッドを間違えているところがあったので、直してあります(*1)

  1. 作者のHéctorには報告済み。次のリリースで直すそうです。

readme.txt にあるように、WPP は、WP-PostRatingsと連動することができます。WP-PostRatings の方は特に何もしなくても使えます。必要な場合は、通常の手順でインストールしてください。

WordPress Popular Posts

Japanese version is available in WordPress Popular Posts(ja)

There are plugins that tells the visitors which posts or pages are most often viewed. Long time ago, every web page had access counter programs and showed the number of visits, which programs satisfied the vanity of the author. The WordPress plugins of this kind is the similar functionality, but they added a new feature which enables the number of veiws or comments in the list format. Visitors of your page can see which posts are frequently viewed and they will have more chance to be read. Surely the using of databases in the web sites made this feature possible. Now we can use the services like Google Analytics or Jetpack plugin provided by Automattic Inc. that is hosting WordPress.com. Google provides the API and Jetpack provides the widget, which enable WordPress to show the page views and others. So we don’t have to use our own database to store them.

We have the plugins like Google Analytics Popular Posts, which uses Google API. But this time we check WordPress Popular Posts(aka WPP). WPP has the advantage of simple and easy use without other web site services.

  1. It is very likely that this plugin is no more maintenanced. We can’t see the Japanese support page and it has not been updated for more than two years.

Some users report that this plugis doesn’t work with Super Cache. This kind of plugins updates the data stored in the database, triggered by the dynamic screen transition. This feature makes it difficult for the plugin to function with the caching plugins. WPP has the two mode of updating database, one is to update the data triggered by the_content() function, which is normal mode, and the other to update with AJAX through $_POST[‘ID’] global variable, which is optional mode. This feature enables WPP to be compatible with caching plugins. But seeing My Thumbnails keep dissapearing after upgrade, there are some problems concerning caching plugins. Furthermore, WPP seems to work with qTranslate.

When you are using SQLite Integration, you can install and activate WPP without problem. But it doesn’t work as you expect. The reason is that WPP uses single quote for the column aliases just like below.

All the aliases of the column are quoted with single quotation. There are no back ticks(*1).

  1. You can use double quotation with MySQL in the ANSI mode and with Oracle. You can use square blacket with MS SQL Server or MS Access.

I made an experiment, using commandline utility sqlite3 (version 3.7.14).

sqlite> SELECT p.ID AS id, p.post_title AS title FROM wp_posts AS p;
id          title
----------  ----------
1           Hello world!
2           Sample Page

sqlite> SELECT p.ID AS 'id', p.post_title AS 'title' FROM wp_posts AS 'p';
id          title
----------  ----------
1           Hello world!
2           Sample Page

The same output. We get the same with double quotation. You can use square blacket, which is compatible with MS SQL Server, and back tick, which is compatible with MySQL. SQL As Understood By SQLite, SQLite Keywords reads: when used with single quote, SQLite interprets it as a string literal and when used in the place where the string literal is not permitted, it interprets as an identifier.

I tried on MySQL, using the commandline utility mysql.

mysql> SELECT p.ID AS id, p.post_title AS title FROM wp_posts AS p;
+----+-----------------------+
| id | title                 |
+----+-----------------------+
|  1 | Hello world!          |
|  2 | Sample Page           |
+----+-----------------------+

mysql> SELECT p.ID AS 'id', p.post_title AS 'title' FROM wp_posts AS 'p';
ERROR 1064 (42000): You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''p'' at line 1

mysql> SELECT p.ID AS 'id', p.post_title AS 'title' FROM wp_posts AS p;
+----+-----------------------+
| id | title                 |
+----+-----------------------+
|  1 | Hello world!          |
|  2 | Sample Page           |
+----+-----------------------+

We can’t use single quote to the table aliases. The same output when using double quote. You can use back tick to the table aliases.

The results shows that the code of WordPress Popular Post seems to be no problem. It IS no problem, indeed. But when using SQLite Integration, the results are not the same. First try: without quote.

The result is like below, as you expected.

Array
(
    [0] => Array
        (
            [id] => 1
            [title] => Hello world!
        )

    [1] => Array
        (
            [id] => 2
            [title] => Sample Page
        )
)

With quote.

We get the result, empty array.

Array
(
)

This is from the manipulation of the single and double quote of SQLite Integration. SQLite Integration emulates PDO::bindValue, replace the quoted strings with placeholder ":param_number" and stores those strings in an array. After that, it execute PDO::prepare(). When the quoted strings are in the proper place, it returns PDOStatement object. And you can execute PDOStatement::execute() with that array and get the proper results. See more details in PHP Data Objects. I’ll give one example.

In the place :param_0 and :param_1 was a string value like ‘Hello world!’. This feature seems to be implemented originally for that reason below.

  1. It can avoid dangerous input data from the users, manipulating them before executing SQL statement(*1).
  2. PHP can cache the SQL statement and execute faster only with the replacement of the data.
  1. $wpdb::prepare() method is the similar feature. It escapes the data with addslashes() or mysql_real_escape_string()[not recommended in PHP5.5.0] functions.

The bad example has :param_0, :param_1 in the wrong places, which causes PDO::prepare() to throw an exception. SQLite Integration catches this exception and handles it. If you set $wpdb->supress_errors to false and $wpdb->show_errors to true, you can see the error messages, which isn’t enabled by default.

There’s no workaround way of avoiding this. So if you want to use WordPress Popular Posts with SQLite Integration, you have to rewrite it. There’s a patch file that includes minor fix(*1).

  1. I reported to the author Héctor. He will fix it in the next release.

As you see in readme.txt, WPP can collaborate with WP-PostRatings, which can be installed and activated normal way.

DebianでAirPrint

環境: Debian 7.0 wheezy、初代iPad、iPhone5

DebianでAirPrintを使う

アップルのiPhoneやiPadは、ネットワークに接続した機器の提供するサービスを設定なしで使うための、Bonjourという規格で通信をすることができます(*1)。昔のMacは他のMacや周辺機器との接続にAppleTalkというプロトコルが使われていて、つなげばすぐに使えるというのが売りでした。WindowsのSMBとともに、独自の規格のため、たとえば、Linuxで両者を使うには、AppleTalkにはNetatalk、SMBにはSambaというソフトウェアを使わなければなりませんでした。その後、ローカルなネットワークでもインターネット・プロトコル(TCP/IP)が使われるようになり、AppleではTCP/IPでもAppleTalkと同じ機能が使える規格としてBonjourを開発した、ということのようです。一方、AppleTalkは段階的に廃止する方針のようです(*2)

  1. アップルのサイトにあるBonjourのページからOverviewやテクニカルドキュメントを参照することができます。
  2. AndroidがJelly Bean(4.1.x, 4.2.x)からmDNS、DNS-SDをサポートし始めたそうです。How to use the new android.net.nsd package for Zeroconfを参照。

ネットワークに接続したiPhoneやiPadは、Bonjour語を話していますから、それを理解できるプリンタなら何もせずにAirPrintが使えることになります。AirPrint対応プリンタというのはBonjour語を話せるプリンタということなわけです。それなら、TCP/IPは話せるけれども、Bonjour語は話すことができないプリンタはどうればよいのか、ということになります。TCP/IPもBonjourも話せる機器が間に入れば、両者の通訳をすることができるはずです。もちろん、Linuxがその通訳を務めます。

AirPrint、CUPS、Avahiなどのキーワードで検索をすると、この仕組みを利用したHOWTOがたくさんヒットします。遅ればせながら、わが家もDebian wheezyを使って、AirPrintできるようにしましたので、やりかたを書いておきます。このページでしか知ることのできない情報というのは——たぶんありません。:-) また、GNOMEもKDEも入っていませんので、それらに付属の設定ツールを利用したやり方は書いてありませんので、他のサイトをお探しください。

CUPSとCanon MG6130ドライバ設定

インストールのときにCUPSは入れてあるので、Canonのgs用フィルタをインストールします。Canonはプリンタや複合機のLinux用ドライバを昔から配布していて、わが家のMG6130用ドライバもIJ Printer Driver Ver.3.40 for Linuxからダウンロードできます。ファイル名は、cnijfilter-mg6100series-3.40-deb.tar.gzとなっていました。以前は「ドライバ」ではなくて、「フィルタ」と呼んでいた記憶があるのですが、ファイル名は今でも「フィルタ」なのですね。説明に従ってインストールします。

$ tar zxvf cnijfilter-mg6100series-3.40-deb.tar.gz
$ cd cnijfilter-mg6100series-3.40-deb
$ sudo ./install.sh

あとはこのスクリプトが、CUPSデーモンを止めるところから、ドライバのインストール、設定ファイルの作成、デーモンの再起動まですべて面倒を見てくれます。Canonがgsのフィルタを配布し始めた頃は、/etc/printcapを編集した記憶がありますが、今では/etc/printcapファイルそのものが存在しません。自分が完全にout of dateになってしまっていることが実感できます。どこにどんなファイルが入ったかは、下のコマンドで見ることができます(/etc/cups以下の設定ファイルはリストされません)。

$ dpkg -L cnijfilter-mg6100series

CUPS用設定ファイルが、/etc/cups以下のディレクトリに作られています。

/etc/cups/ppd/MG6130.ppd
/etc/cups/printers.conf

Stateはプリンタの初期状態を指定するのですが、Stoppedになっていたので、Idleに変更しました。また、ErrorPolicyはプリンタ・エラーの時の動作を指定するところですが、stop-printerとなっていたので、abort-jobに変更しました。

$ man printers.conf

で、それぞれの項目に設定できる値を見ることができます。

これで設定は終了ですが、GNOMEもKDEも動いていませんので、外からブラウザでお手軽にプリンタの状態を見ることができるように、cupsデーモンの設定を少し変更しておきます。

CUPSの設定ファイルは、Apacheと似ているようで、微妙に違いがあるようです。1行にまとめては書けないようなので、2行に分けて許可するアドレスを指定しました。ウェブで検索すると、"ServerAlias *"を書き加えている方が多いようですが、そのままのホスト名でアクセスするので、指定していません。これで、他のPCからブラウザで設定画面を見ることができます。この、cupsd.confにもマニュアル・ページがありますので、下のコマンドで読むことができます。

$ man cupsd.conf

これで、本体からでも他のPCからブラウザを通してでも、テストプリントができればCUPSの設定は終了です。

CUPS HOME

Avahi設定

さて、今度は、DebianがBonjourを話せるように設定しましょう。Linux側で旧Netatalkにかわるものは、Avahiといいます。

インストールのときにネットワーク関連は一通り入れたので、SambaもAvahiもすでにインストール済みです。本体はavahi-daemonといいます。インストールされていない場合は、

$ sudo apt-get install avahi-daemon avahi-utils

で、必要なライブラリもインストールされるはずです。ユーティリティが必要ない場合は、avahi-daemonだけ指定します。

設定ファイルは、/etc/avahi以下にまとめられています。

  • /etc/avahi/avahi-daemon.conf
  • /etc/avahi/hosts

それぞれのファイルは、インストールした段階で、以下のようになっています。

設定できる項目は、マニュアル・ページに詳細な説明があります。下の表では簡単な説明をつけましたが、実際のマニュアルを参照してください。。

SECTION [SERVER]
host-name avahiデーモンがLANに登録するホスト名。省略すると、システムのホスト名が使われる。
domain-name デフォルトのドメイン名。省略すると、.localが使われる。
browse-domains ブラウズするドメインをカンマで区切ったリスト。
use-ipv4 yesまたはno。名前のとおり。
use-ipv6 yesまたはno。名前のとおり。
allow-interfaces avahiデーモンが利用するネットワーク・インターフェイス。カンマ区切りで複数指定できる。
deny-interfaces avahiデーモンが無視するネットワーク・インターフェイス。allow-interfacesより優先される。
check-response-ttl yesまたはno。yesなら、追加のセキュリティチェックをする。新しいmDNSとは非互換なので、デフォルトでnoになっている。
use-iff-running yesまたはno。ネットワークドライバのIFF_RUNNINGフラグをモニタする。サポートしないドライバが多いので、デフォルトno。
enable-dbus yes、noまたはwarn。yesでD-Busに接続する。コンパイルオプションに–enable-dbusがついていれば使える。warnは接続に失敗しても起動する。
disallow-other-stacks yesまたはno。yesとすると、他のプロセスはUDPポート5353に接続できない。
allow-point-to-point yesまたはno。インターフェイスにPOINTTOPOINTフラグをセットする。セキュリティ・ホールになる可能性があるので、デフォルトno。
cache-entries-max 符号なし整数でキャッシュの大きさを指定する。
clients-max 符号なし整数で、D-Busを共有できるクライアント数を指定する。
objects-per-client-max 符号なし整数で、1度にD-Busクライアントが登録できるオブジェクト数を指定する。
entries-per-entry-group-max 符号なし整数で、1度にD-Busクライアントが登録できるエントリ数を指定する。
ratelimit-interval-usec 符号なし整数で、インターフェイス毎のパケット転送率制限の間隔を指定する。
ratelimit-burst 符号なし整数で、一定時間にavahiデーモンが生成するパケット数の上限をコントロールする。
SECTION [WIDE-AREA]
enable-wide-area yesまたはno。有効にすると、.localで終わるドメインだけがmDNSで解決され、他は全てユニキャストDNSを通して解決されるようになる。
SECTION [PUBLISH]
disable-publishing yesまたはno。yesにすると、avahiは何もパブリッシュしない。デフォルトno。
disable-user-service-publishing yesまたはno。yesにすると、avahiはアドレスをパブリッシュするが、他のユーザ・アプリケーションはサービスをパブリッシュできない。
add-service-cookie yesまたはno。yesにすると、ローカルに登録されたサービスにTXTエントリが追加される。デフォルトno。
publish-addresses yesまたはno。yesにすると、avahiデーモンは全てのローカルIPアドレスに対するmDNSアドレスの記録を登録する。デフォルトyes。
publish-hinfo yesまたはno。yesにすると、avahiデーモンは、全てのインターフェイスについて、OSとCPUの情報を登録する。
publish-workstation yesまたはno。yesにすると、avahiデーモンは、_workstation._tcpのサービスを登録する。デフォルトyes。
publish-domain yesまたはno。yesにすると、avahiデーモンはローカルで使われているドメイン名を通知する。デフォルトyes。
publish-dns-servers ユニキャストDNSサーバのIPアドレス。カンマ区切りで複数指定できる。mDNSを通してDNSサーバを通知できる。
publish-resolv-conf-dns-servers yesまたはno。yesにすると、publish-dns-serversで指定した以外に、/etc/resolv.confのDNSサーバも通知する。デフォルトno。
publish-aaaa-on-ipv4 yesまたはno。yesにすると、avahiデーモンは、IPv4を通してIPv6のAAAAレコードを送信する。IPv6のアドレスがIPv4のトランスポートを使って解決できる。use-ipv4=trueとともに使うこと。デフォルトyes。
publish-a-on-ipv6 yesまたはno。yesに設定すると、avahiデーモンは、IPv6を通してIPv4のレコードを送信する。上の逆。use-ipv6=trueで使うこと。デフォルトno。
SECTION [REFLECTOR]
enable-reflector yesまたはno。yesにすると、avahiデーモンは、受け取ったmDNSリクエストを全てのローカル・ネットワーク・インターフェイスに返す。デフォルトno。
reflect-ipv yesまたはno。これがyesで、enable-reflectorが有効なら、IPv4とIPv6の間でmDNSがフォワードされる。推奨されない。デフォルトno。
SECTION [RLIMITS]
rlimit-as プロセスの仮想メモリ上限。バイト値。
rlimit-core コアファイルの上限。バイト値。デバッグしないなら0でも安全。
rlimit-data プロセスのデータセグメント上限。バイト値。システムに依存する。
rlimit-fsize プロセスが作るファイルサイズの上限。avahiデーモンはディスクにファイルを書き込まないので、0にしても安全。
rlimit-nofile オープンするファイルディスクリプタ数。avahiデーモンは15から20を越えてファイルを必要とするべきではない。
rlimit-stack プロセス・スタックの上限。バイト値。システムに依存する。
rlimit-nproc ユーザ・プロセス数。avahiデーモンはchroot(2)ができるところでは、補助プロセスをフォークするので、2より小さくしてはいけない。

サービスの設定ファイルは、/etc/avahi/services以下にまとめられています。udisksがすでにファイルを作っていて、MG6130用のものを追加して、下のようになりました。

  • /etc/avahi/services/udisks.service
  • /etc/avahi/services/AirPrint-MG6130.service

ファイルの中身です。

AirPrint-MG6130.serviceの方は、スクラッチから書くのは難しいので、airprint-generate.pyに作ってもらいました。ダウンロードして実行するだけです。できたファイルは下のようになっていました(改行を入れて読みやすくしてあります)。

このファイルの形式には、Appleの文書Bonjour Printing Specificationがあります。サービスのタイプは、DNS SRV (RFC 2782) Service Typesでも説明されています。それによると、「_<サービス>._<プロトコル>.<ドメイン>」という形で、ドメインは.localが追加されるようです。上の例なら、_ipp._tcp.localとなります。Appleの文書では、下のように示されています。

プロトコル サービス・タイプ
LPR _printer._tcp
IPP _ipp._tcp
AppSocker
PhaserPort
JetDirect
Port 9100
_pdl-datastream._tcp

TXT recordは付加情報のことで、Appleの文書で説明されているのは次のものでした。

TXT Record Keys
txtvers TXT recordのバージョン番号。
rp キューの名前。ユーザに表示される名前ではない。IPP TXT recordで使われる場合は、特定のプリント・キューに対するIPP URLのフルパスになる。上の例では、ipp://:/printers/MG6130となる。ポート番号が9100のときはこれを指定してはいけない。
note プリンタの場所を指定する。プリンタをセットアップするときにこの文字列が表示される。
qtotal この値はキューの合計数を指定する。よって、特定のポートを使うプロトコルに登録されたTXT recordの合計数ともなる。
priority 0-99の間で指定する。数字の小さい方が優先順位が高い。デフォルトのプロトコルとキューを指定することができる。
ty プリンタのベンダとモデルを記述する。ユーザが読める形式の記述がよい。
product ポストスクリプト・プリンタでも非ポストスクリプト・プリンタでも、CUPSを使うものは、PPDの中で"Product"の値となっているものと同じでなければならない。あるいは、開き括弧、製造者名、スペース、モデル名、閉じ括弧の形になっていなければならない。
pdl この値は、プロトコルあるいはキューでサポートされるページ記述言語のMIMEタイプをカンマ区切りで指定しなければならない。カンマで終わってはならない。
adminurl プリンタまたはキューの環境設定ページのURLを指定する。
usb_MFG プリンタの1284ディバイスIDから取得できる製造者の値。
usb_MDL プリンタの1284ディバイスIDから取得できるモデル名。
Printer Protocol TXT Record Keys
Transparent プリント・キューが00-1F文字コードを受け取ることができるなら、"T"を指定する。指定がない場合は、"F"と同じになる。
Binary プリント・キューが80-FF文字コードを受け取ることができるなら、"T"。8ビット・バイナリを示すのに、Transparentキーとともに使うことができる。
TBCP プリント・キューがTagged Binary Communication Protocolを受け取ることができるなら、"T"を指定する。指定がない場合は、"F"と同じになる。
Printer Feature TXT Record Keys
Color カラー印刷
Copies 高速印刷
Duplex 両面印刷。T, T, U
PaperCustom カスタム用紙サイズ。T, F, U
Bind 縁をつける。T, F, U
Collate 丁合を取る。T, F, U
Sort 並べ替え。T, F, U
Staple ホチキスどめ。T, F, U
Punch パンチ穴。0, 2, 3, 4, U
PaperMax 最大用紙サイズ。

最低限、名前とポートとサービス・タイプがあれば十分のようですが、今回はそのまま使うことにしました。設定ファイルの編集が済んだら、サーバを再起動します。

$ sudo /etc/init.d/avahi-daemon restart

$ avahi-browse -a
+    ra0 IPv4 Canon MG6100 series _773CC32BA1B7
+    ra0 IPv6 AirPrint MG6130 @ debian
+    ra0 IPv6 debian
+    ra0 IPv4 AirPrint MG6130 @ debian
+    ra0 IPv4 debian

これで、やっとAirPrintが使えるようになりました。iPad、iPhoneどちからも印刷できます。

Debian wheezyでBuffaloのWLI-UC-GNMを使う

環境: Linux debian 3.2.0-4-686-pae #1 SMP Debian 3.2.41-2+deb7u2 i686 GNU/Linux

AirPrint環境を作ろうとしてWLI-UC-GNMにはまる

Debian wheezyのインストールは有線LANを使って済ませたけれども、ファンが回るとけっこう喧しいPCをNTTのルータのそばに置いておくことはできないので、無線LANで接続することにしました。PCIにさしてあるVIA RhineのLANカードはつけたままで、USBの無線LANアダプタを採用(何より値段が安い)ということで、BUFFALO社のWLI-UC-GNMというアダプタを購入。

本体のUSBポートにさせば、自動的に認識され、何もせずにすぐ使えるというのが理想ですが、そうはいきませんでした。Xもあがっていないので、手動設定をします。

$ lsusb
Bus 001 Device 002: ID 0411:01a2 BUFFALO INC. (formerly Melco., Inc.) WLI-UC-GNM Wireless LAN Adapter [Ralink RT8070]

$ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 1: Dev 2, If 0, Class=vend., Driver=rt2800usb, 12M

認識はされているようです。IDのところにある411がベンダID、1a2がディバイスIDです。BUFFALOの前身はMelcoだったのか、といらぬ感慨に耽りながら、Ralink RT8070と製品名で検索してみると、WLI-UC-GNM の Linuxドライバーインストール(2012-07-10)というページがありました。このページで紹介されているLinuxでkai(wlan設定編) > rt3070staを見ると、Ralink RT8070Vとなっていて、Vの文字が余分です。wiki.debianのrt2800usbではRT8070となっています。同じ製品名でも、内部で使われている部品が異なることは珍しくありませんから、不思議ではないのですが、検索でヒットするページを漠然と見ていると、何もせずに使えたという報告とベンダが提供するドライバで動作したという報告が混在していて、チップの違いだけでなく別の要素もあるような予感がします。この検証は後ほど。

無線LAN設定

wiki.debian.orgのrt2x00のページの記述を見ると(日本語がないので、拙訳です)、こんなことが書いてあります。

このページは、Debianシステムで、Ralink 802.11n USBチップセットを使ったWiFiディバイスのサポートができるようにする方法を述べる。
Debian 6.0 "Squeeze"ユーザは、rt2870staのページでディバイスのサポートを見ていただきたい。
rt2800usbはrt2x00プロジェクトが作成したドライバで、Ralink 802.11n USBチップセットをサポートする。サポートされるディバイスはこのページの最後にリストする。
これは、バージョン2.6.31からLinuxカーネルの幹に統合され、Debian 7.0 "Wheezy"と後のリリースでは、実験段階のrt2870staドライバを置き換えるものである。ファームウェアが必要とされるが、firmware-ralinkパッケージで入手できる。
RT3370とRT3572チップの実験的サポートは、linux-2.6、つまり2.6.38-5で使えるようになった。RT3370のサポートは、Linux 3.0ではもう実験的ではなくなっている。

ファームウェアがインストールされていなかったので、インストールしました。

$ sudo apt-get install firmware-ralink

$ dpkg -L firmware-ralink
/.
/usr
/usr/share
/usr/share/bug
/usr/share/bug/firmware-ralink
/usr/share/bug/firmware-ralink/presubj
/usr/share/doc
/usr/share/doc/firmware-ralink
/usr/share/doc/firmware-ralink/changelog.gz
/usr/share/doc/firmware-ralink/copyright
/lib
/lib/firmware
/lib/firmware/rt2561.bin
/lib/firmware/rt2870.bin
/lib/firmware/rt73.bin
/lib/firmware/rt2561s.bin
/lib/firmware/rt3071.bin
/lib/firmware/rt2661.bin
/lib/firmware/rt2860.bin
/lib/firmware/rt3070.bin
/lib/firmware/rt3090.bin

同じく、wiki.debianのWiFi HowToUseを参考にして設定をしました。

WPA-PSK and WPA2-PSK

GNOMEもKDEも使っていないので、NetworkManagerを使わず、手動で設定します。ネットワークデーモンを止め、/etc/network/interfaceをwpa_supplicantを使うように編集します。

/etc/wpa_supplicant/wpa_supplicant.confがないので、作ります。

# wpa_passphrase SSID PSK > /etc/wpa_supplicant/wpa_supplicant.conf

man wpa_supplicant.confを見ると、様々な設定例が書いてありますが、最低限これだけでもいけるようです。最終的には下のようにしましたが。

ここで、ネットワークデーモンを再起動しても、dhclientでアドレスを取得できません。インターフェイス、wpa_supplicant、dhcpをひとつづつ手動で開始しても、アドレスの取得でタイムアウトして、スリープしてしまいます。たまたま、インターフェイスをスキャンしてみると…

$ /sbin/iwlist scan
lo      Interface doesn't support scanning.

wlan0   No scan results

eth0    Interface doesn't support scanning.

無線を受信できてません。ああ…

MediaTek Inc.のドライバ

ベンダのドライバを試してみることにします。ドライバの配布元は、MediaTek Inc.で、Downloadsというページがあります。RT8070 /RT3070 /RT3370 /RT5370 /RT5372 USB(10/22/2012更新) バージョン2.6.1.3をダウンロードします。ファイル名は2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO.bz2で、「Linuxドライバインストール」のページではファイル名を変えるように書いてありますが、そのまま展開できました(*1)

【2014-02-26 追記】
MediaTek 社のページがリニューアルされて、アドレスが変わり、ダウンロードページもメールアドレスを要求するようになったようです。新しいバージョンのドライバを見ていないので、わかりませんが、下の記述は古くなっている可能性があります。
$ tar jxvf 2011_0719_RT3070_RT3370_RT5370_RT5372_Linux_STA_V2.5.0.3_DPO.bz2

ファイルの修正は3点あります。

  1. archive_root/Makefile
    存在しないディレクトリにコピーしようとして、makeが止まるので、次の行をコメントアウトします。
  2. archive_root/common/rtusb_dev_id.c
    さきほど得たディバイス情報を追加します。
  3. archive_root/os/linux/config.mk
    wpa_supplicantにWPA2-PSKを任せるので、スイッチを有効にします。README_STA_usbの記述を参照。 README_STA_usbを読むと、NetworkManagerかwpa_supplicantのwextコマンドでコントロールする場合は両者をyに、wpa_supplicantでRalinkドライバを使う場合は、後者をnにするように、と書かれています。wpa_supplicantを起動するときに、
    /sbin/wpa_supplicant -D wext
    
    と、wextオプションをつけるか、
    /sbin/wpa_supplicant -D ralink
    
    と、ralinkオプションをつけるかのちがいです。

これでビルドの準備は終了です。

$ make
$ sudo make install

本体は、

/lib/modules/your_kerne_version/kernel/drivers/net/wireless/rt5370sta.ko

に、設定ファイルは、

/etc/Wireless/RT2870STA/RT2870STA.dat

に、それぞれインストールされます。ロードして確認しましょう。

$ sudo service networking stop
$ sudo killall -HUP wpa_supplicant
$ sudo kill dhclient pid
$ sudo modprobe -r rt2800usb
$ sudo echo blacklist rt2800usb >> /etc/modprobe.d/blacklist.conf
$ sudo echo blacklist rt2x00usb >> /etc/modprobe.d/blacklist.conf
$ sudo echo blacklist rt2x00lib >> /etc/modprobe.d/blacklist.conf
$ sudo echo blacklist rt2800lib >> /etc/modprobe.d/blacklist.conf
$ sudo modprobe rt5370sta
$ sudo modinfo rt5370sta
filename:    /lib/modules/3.2.0-4-686-pae/kernel/drivers/net/wireless/rt5370sta.ko
version:     2.5.0.3
lincense:    GPL
description: RT2870 Wireless Lan Linux Driver
author:      Paul Lin
srcversion:  AF10EDBE2D75FC6A4B65A2F
alias:
-- 略 --

$ sudo service networking start

$ lsusb -t
/:  Bus 01.Port 1: Dev 1, Class=root_hub, Driver=uhci_hcd/2p, 12M
    |__ Port 1: Dev 2, If 0, Class=vend., Driver=rt2870, 12M

$ /sbin/iwlist scan
ra0       Scan completed :
          Cell 01 - Address: XX:XX:XX:XX:XX:XX
-- 略 --

アドレスが取得できて、ステーションのscanもできています。

BUFFALO WLI-UC-GNMについてのページと情報

とりあえず、Google検索にて、検索文字列«WLI-UC-GNM Linux»でヒットしたページの情報をまとめてみます。長いタイトルは省略しました。あしからず。

紹介サイト OS(kernel) Chipset Vendor ID Device ID Driver
WLI-UC-GNMの… CrunchBang 11(?) RT8070V 0x0411 0x01a2 rt5370sta
Linux Wireless… Ubuntu 10.10 AMD64(?) RT2870 ? ? ?
Ubuntu日本語フォーラム Ubuntu 10.04 LTS(2.6.32) RT2870(?) 0x0411 0x01A2 rt2870sta
Linuxでkai (wlan設定) ?(<2.6.40) RT8070V 0x0411 0x01A2 rt3070sta
Linuxでkai (wlan設定) ?(>3.0) RT8070V 0x0411 0x01A2 rt2800usb(*1)
Ubuntu11.04で… Ubuntu 11.04(2.6.38) RT3070 0x0411 0x01A2 rt2870sta
Linux Mint 13… Linux Mint 13(?) ? 0x0411 0x01A2 rt2800usb
Linux Wireless ? RT3070V 0x0411 0x01a2
rt2800usb(wiki.debian) Debian 7.0(3.2.0) RT8070 0x0411 0x01A2 rt2800usb(*2)
  1. Linuxカーネル3.0(2.6.40)以降の場合。このドライバはファームウェアが必要とある。see also rt2x00 Project. ただし、このページには動作したかどうかの検証がありません。
  2. やはりファームウェアが必要(パッケージになっている)。rt2x00 Projectのもの。

これを見ると、チップは、RT2870、RT3070、RT8070、RT8070Vの四つ(または、三つ?)あって、一部は他のディバイス(たとえば、WLI-UC-GNなど)と共通だったりするようです。一覧表を提供しているサイトもありましたが、カーネルのバージョンとの関係がわかりませんでした。ひょっとすると、rt2800usbがエクスペリメンタルなときに、別のモジュールで動作していたのかもしれません、カーネルモジュールのrt2800usbが導入されて動作するようになったのかもしれません。3.0以上のカーネルの情報がほとんどなかったので、わかりませんが、

役立ったサイト・コマンド

サイト

コマンド

  • dpkg -L package_name
    debパッケージに含まれるファイルをディレクトリ毎に表示する。
  • /sbin/iwlist scan
    無線親機がブロードキャストしているデータを取得する。
  • tar jxvf archive_name
    アーカイブを展開する。オプションは、j: bzip2にフィルタする、x: ファイルを抽出する、v: 処理したファイル名を出力する、f: アーカイブファイルを指定する
  • /sbin/wpa_supplicant
    ネットワーク・インタフェイスを通してWi-Fi機器とネゴシエートするデーモン。
  • modinfo module_name
    読み込まれたカーネルモジュールの情報を出力する。

Debian revisited

AirPrint環境を作ろうとしてNVIDIAにはまる

四方山話です。情報量はほぼゼロに近いです。

家族がiPodやiPadを使っていて、ついにiPhoneまでが使われ始めました。iPodはともかく、iPadやiPhoneは携帯端末の拡張のように見えますが、基本的にコンピュータですから、アプリケーション・ソフトウェアから印刷をしたいと思ようになるのも必然でしょう。しかし、残念ながら、わが家のCanon製プリンタ、MG6130(*1)はAirPrintに対応していません。調べてみると、Linux(*2)でCUPSを使えばAirPrintできるとのことなので、古いデスクトップでLinux Boxを立てることにしました。

  1. ネット上の評価では、「インクの消費量が尋常ではない」という声が多い機種ですが、本体の安さから導入したのでした。
  2. FSF的には、Linuxはカーネルだけで、GNUのソフトウェアを主体に使っているのだから、GNU/Linuxと呼ぶのがよいとのことですが、私はLinus Torvaldsを尊敬しつつも、その信者ではないし、Richard M. Stallmanを尊敬しつつも、その信者ではないので、ここでは通称のLinuxとしておきます。

PCは、10年以上前に買ったDELL Dimension4100という機種です。当初はWindows MEが載っていて、すぐにWindows 2000となり、それがサポート終了となってからは、しばらく埃をかぶっていました。CPUはIntelのPentiumIII 1GHz、メモリは256MBしか積んでません。ハードディスクは2台つながっているのですが、それぞれ40GBと8GBです。今ではありえないスペックですが、調べてみると、現在のLinuxディストリビューションでは、デスクトップ(GNOMEの採用率が高いようです)で使うにはメモリ不足ですが、サーバ用途なら問題なさそうです。

USBメディアからのブートができず(*1)、DVDドライブもないので、最少構成のインストール・メディアを使い、残りはネットワークからダウンロードするという方法が使えるものでないとインストールできません。昔はCD1枚済んだVine Linuxでさえ、「DVD1枚または2GBのUSBメモリ」が必要となっています。結局、ネットワークインストールできるCDイメージを見やすいところで配布しているDebian GNU/Linux(*2)を使うことにしました。バージョンは7.0、コードネームはWheezyとなっています。

  1. GRUBを入れたCDから起動->USBメモリブート、というのができるらしいので、たぶんフロッピーディスク起動->USBメモリブートもできるはずですが、試してません。GRUBを入れたCDと最少構成のインストールCDでは、機能に変わりがありませんので。
  2. DebianのポリシーではGNUの意見を容れて、正式名称Debian GNU/Linuxというのです。

実は、Debianを使うのはこれが初めてではありません。最初のLinuxはSlackwareでした。1990年代に、羽根秀也さんの入門書や、O’ReillyのHOWTO本、久野靖さんの書かれたUNIXの参考書などを見て勉強しながら遊んでいました。いまでは多言語をコンピュータで表示するのはあたりまえになりましたが、当時は、日本語と英語、フランス語とドイツ語を同時に表示できるエディタもなく、パーソナルユースでは、表計算ソフトもデータベースも日本語と英語しか入れられませんでした。目的はEmacs(というよりMuleですね)とTeXでした。複数言語のまじった文書が作れて、複数言語の文献ファイルも管理できるという、Windows環境でもでもMac環境でもできないことを既に実現しているという驚きがあったのですが、それとは別に、UNIXのシステムやネットワークのよい勉強になりました。Debianは2.1のslink(*1)くらいから、3.1sargeの頃まで付き合っていましたが、ライブラリなどの更新が遅く、最新バージョンのソフトウェアを自分でコンパイルしていると(*2)、/usr/local/ディレクトリの中身が肥大化してきて、たとえdebパッケージを作ったとしても、結局Slackwareのようなシステムになってしまうので、ライブラリの更新が早いRed Hat系に移行してしまい、それ以降は全く見ていません。久しぶりの再会といったところです。ライセンスに厳しいディストリビューションですが、順調に開発が続けられているようです(*3)

  1. Debian.orgのリリースノートには日付がないので、いつ頃なのか確認できませんでした。
  2. EmacsはCVSリポジトリから匿名でcheckoutできたので、常に最新を自前でコンパイルしていました。
  3. Mozillaについては確執があるようですが…

さて、wheezyのインストールですが、何の問題もなく終わりました。サーバ用途としてなので、Xorgなどは必要ありませんが、興味本位でデスクトップ環境もインストールしたので、いきなりgdm3が起動してしまいます。Ctl-Alt-F1でコンソールにおりて、runlevel3で再起動すると、同じくgdm3が起動します。Debian sargeの後、Red Hat系を使っていたので、忘れていましたが、Debianではrunlevel2-5は全て同じになっているそうです。/etc/rc2.d/と/etc/rc5.d/の中身が同じでした。いやはや、また初心者レベルに逆戻りですね。

それなら試しに、ということで、GNOME3にログインしてみると…

画面が描画できていません。画面全体が青一色になって、Xorgのルート・ウィンドウを表示するところまで到達できません。ウィンドウ・マネージャをfluxboxにしたり、GNOME Classicにすると表示することができます。困ったことに、/etc/xorg.confファイルがありません。~/.xsession.errorを見ても、ちゃんと読めなくなっています(初心者以下ですね)。それなら、ということで調べました。Xorgのエラーというからには、たいていVGAカードかフォントに問題があり、というのが昔からの定番です。

$ lspci

の結果は次のようになっています。

01:00.0 VGA compatible controller: NVIDIA Corporation NV11 [GeForce2 MX/MX 400] (rev b2) (prog-if 00 [VGA controller])
        Subsystem: NVIDIA Corporation Device 004a
        Flags: bus master, 66MHz, medium devsel, latency 248, IRQ 11
        Memory at fd000000 (32-bit, non-prefetchable) [size=16M]
        Memory at e8000000 (32-bit, prefetchable) [size=128M]
        [virtual]Expansion ROM at fe9f0000 [disabled] [size=64K]
        Capabilities: 
        Kernel driver in use: nouveau

nouveauという見慣れないドライバが使われています。

$ lsmod

すると、NVIDIAらしきドライバはありません。ためしに、

# Xorg -configure

すると、とりあえずXorg.confができますが、エラーが出ます。中身を見ると、やはりDriverにnouveauというのが使われています。検索して判明したのは、このnouveauというモジュールは、プロプリエタリなNVIDIAのドラバをエミュレートすべく、X.Org FoundationとFreedesktop.orgがオープンソースで開発中のカーネル・モジュールとのことです(常識なのでしょうか?)。REnouveauというリバース・エンジニアリング用のツールまで配布しています。こういった場合、不具合を調べてバグがあればそれを調べて報告するというのが正しい態度ですが、まずは動かすのが先決なので、次に進みます。

ということで、次善の策、プロプリエタリなドライバを試しました。

$ sudo aptitude search nvidia

すると、けっこうな数のパッケージが存在します。Googleで検索すると、NVIDIAのサイトからドライバをダウンロードしてインストールした、というようなページが新旧たくさん見つかります。GeForce2 MX/MX 400にしぼると、あまり新しい情報が見あたりません。Debian wheezyにしぼると、Debianのサイトに行きつき、現行バージョンwheezyのドキュメントで、xserver-xorg-video-nvidia-legacy-96xxがバイナリの本体らしいことがわかります。その他はOpenGLのライブラリや、メタパッケージ、alternativesで提供するためのユーティリティ、カーネルを再構築するとき用のソースファイルという感じのようです。これくらいわかれば、あとはメタパッケージに狙いを定めて、

$ sudo apt-get install nvidia-support nvidia-glx nvidia-config

とすると、関連したパッケージがずらずらとインストールされます。これがDebianのよいところで、最も一般的な名称のパッケージを選択するとなんとなくそれらしいパッケージが一通りインストールされることになります。削除したいときにも、

$ sudo apt-get remove target package
$ sudo apt-get autoremove

すると一通り削除されることになります。もちろん、パッケージャがミスをする場合もありますが、バグリポートを参照すれば大抵のミスはわかります。

さて、NVIDIAドライバですが、インストールして、modprobeしてもロードされません。nouveauのほうも、rmmodeすると使用中だからできないと言われます。/etc/modprobe.d/の中を見ると、nvidia-kernel-common.confというファイルが追加されていて、aliasの設定とともに、

となっています。必要なことは全て設定済みのようです。が、nvidiaが読み込まれなければ意味がありません。blacklist.confのほうにも追加おきました。さらに、/etc/alternatives/の中を参考にして、update-alternativesで競合パッケージの状況を確認してみました。

$ update-alternatives --list glx
/usr/lib/mesa-diverted
/usr/lib/nvidia

$ update-alternatives --list nvidia
/usr/lib/nvidia/legacy-96xx

glxはnvidiaとmesaのライブラリがあるようですが、Xのドライバは一つで、nouveauは選択肢に入らないようです。もはや打つ手なしとなってしまいました。こんなときはもちろん、Google検索です。「UbuntuでNVidia ドライバのダウンロードとビルドとインストール」(http://www.kkaneko.com/rinkou/linux/nvidia_ubuntu.html)というページが、Nvidia GTS 460というカード(*1)をUbuntuで使った経緯を書いています。ここを見ると、nouveauを使わないようにする手段として、/etc/default/grubで、下のように設定する、とあります。

  1. 記事のリードではGTS 460となっていますが、GTX 460のようです。[追記: リンク先がつながらないので、アドレスだけにしておきます]

/etc/の下を見ると、grubのコマンドラインオプションをここで設定すると、/etc/grub/以下にあるスクリプトが起動時にそれを読み込んでカーネルに渡すようです。カーネルオプションなので、スペースで区切れば複数のオプションを指定できます。GRUB_CMDLINE_LINUXという変数もあり、これが先に読み込まれ、DEFAULTのついたほうが最後に読み込まれるようになっています。上のように設定すると、nouveauは後に読み込まれますが、コマンドで削除し、nvidiaをmodprobeすることができるようになります。最終的に、/etc/default/grubは下のように設定しました。

モジュール関係では、blacklist=nouveau(複数指定可)やnomodesetでも可能なようです(*1)

  1. ドキュメントを読んだだけなので、実際には試していません。

さて、nvidiaモジュールの読み込みができましたので、ここで再度

を実行してxorg.confを作ってみます。Deviceセクションは次のようになっていました。もちろん、必要最低限の設定しか書かれていませんが、ビデオカードだけなら十分でしょう。

ここでGNOME3を起動してみると…

一応、起動します。が、恐るべき重さです。最低要件の半分しかメモリを積んでませんから、仕方がないのですが、ウィンドウを開くまでの時間が長すぎます。すぐにコンソールにおりて、GNOME関連のパッケージは、Classicも含めて全て削除しました。

これなら、nouveauでもよかったではないか?——確かに、そのとおりなのですが、PC UNIX復帰のためのリハビリテーションにはちょうどよかったのです。

AirPrint? ああ、そうでした。それはまたの機会に…

利用したコマンド

  • lspci
    PCIバスのディバイスについての情報を出力する。本文で使った出力は、-vオプションをつけて実行したもの。The PCI Utilitiesに含まれる。wiki.debianのHowToIdentifyADevice USBを参照のこと。
  • lsusb
    USBバスについての情報を出力する。
  • lsmod
    Linuxカーネルモジュールの状態を出力する。
  • modprobe
    Linuxカーネルにモジュールを追加したり、削除したりする。
  • rmmod
    Linuxカーネルからモジュールを削除する。参考: modprobe -r
  • Xorg -configure
    xorg.confファイルを生成する。ファイルは、/root/xorg.conf.newに生成される。エラーが出てもファイルは生成される。
  • aptitude search package_name
    パッケージ名に一致するものを表示する。
  • apt-get
    Debianのパッケージを操作する。
  • update-alternatives
    同じ機能を持つソフトウェア間の優先順位を決める。
  • nvidia-config
    nvidiaドライバのおまけ。nvidia用のxorg.confを/etc/X11/以下に作る。