質問: ユーザーがログインしていなくても起動時に外付けドライブを/ media / labelに自動的にマウントしますか? この質問 は似ていますが、欲しいものとは反対のものです。誰もログインしていなくても、外付けusbドライブを起動時に自動的に/media/<label>のような場所にマウントしたいのです。面倒で面倒なこともありますが、すべてのデータをfstabに入力する必要はありませんが、プラグインするものや将来パーティションがどのように変わるか予測できないためです。ドライブが mpd のようなものにアクセスできるようにし、sshでログインしたときに利用できるようにします。 gnome-mountは、あなたがローカルでgnomeグラフィカルセッションにログインしているときにだけ、ものをマウントするようです。
回答: ubuntu server 11.10に関するメモ:このスクリプトは、廃止されたvol_idコマンドが原因で、ubuntu server 11.10で失敗します。 vol_idはblkidに置き換えられました。スクリプトを修正するには、udev-auto-mount.shスクリプトの「vol_id」を「blkid -o udev」に置き換えます。 私はしばらくの間、これに頭を悩ませてきました、そして、私は実用的な解決策を見つけたと思います。これはdebianベースのシステムで開発されテストされているので、ubuntuでも動作するはずです。それが他のシステムにも適応できるようにするために私はそれが作る仮定を指摘するつもりです。 それは自動的にプラグインにusbドライブをマウントするでしょう、そしてfirewireに適応するのにそれほど多くはかかりません。 これはudevを使用しているので、hal/devicekit/gnome-anythingを使用しても問題ありません。 デバイスをマウントする/media/labelディレクトリが自動的に作成されます。 ただし、他のオートマウンタに干渉する可能性があります。それをテストすることはできません。 gnome-vfsがアクティブな状態では、両方ともマウントを試みることができます。gnome-vfsがマウントに失敗した場合、デスクトップアイコンが設定されない可能性があります。 gnomeからのアンマウントは可能ですが、gksudoなどが必要かもしれません。 私はシステム起動時にこれをテストしていませんが、システムがマウントする準備ができる前にそれがusbドライブをマウントしようとした場合、それがうまくいかないかもしれないことを見ることができる唯一の理由です。その場合は、おそらくマウントスクリプトに1つ追加の調整が必要になります。 (私は serverfault で何かアドバイスがあるかどうかを調べていますが、それについてはあまり興味がありません。)それに、それで。udevの参照 udevルールを書く (udevルールのリファレンス) man udev (最新バージョンについてはシステムを参照してください) man udevadm (udev管理ツール。やはり最新のシステムを参照してください) マウント時にusbドライブにバックアップ (まったく異なる問題ですが、解決策を理解するのに役立ちます) 背景(udev?whuzzat?)udevはカーネルのホットプラグシステムです。起動時にも、システムの実行中に追加されたデバイスに対しても、適切なデバイスとデバイスシンボリックリンク(例:/dev/disk/by-label/<label>)を自動的に設定します。d-busとhalはデスクトップ環境のようなリスナーにハードウェアイベントを送るために使われます。そのため、gnomeにログインしてcdを挿入するかusbドライブを接続すると、そのイベントは次のようになります。kernel -> udev -> dbus -> hal -> gnome-vfs/nautilus (mount) そして、あなたのドライブはマウントされます。しかし、ヘッドレスシステムでは、自動マウントの利点を得るためにログインする必要はありません。 udevのルールudevでは、デバイスの挿入時にルールを作成したりプログラムを実行したりできるため、これは理想的な選択肢です。私たちは、debian/ubuntuの既存のルールを利用して、/dev/disk/by-label/<label>シンボリックリンクを私たちに設定させ、そして私たちのためにデバイスをマウントする別のルールを追加するつもりです。udevの規則は/etc/udev/rules.d(およびkarmicでは/lib/udev/rules.d)に保持され、数値順に処理されます。番号で始まっていないファイルは番号付きファイルの後に処理されます。私のシステムでは、halルールは90-hal.rulesというファイルに入っているので、自分のルールを89-local.rulesに入れて、それらがhalに到達する前に処理されるようにします。主に、これらの規則が60-persistent-storage.rulesの後にくるようにする必要があります。 local.rulesで十分かもしれません。これを新しいルールファイルに入れてください:# /etc/udev/rules.d/local.rules # /etc/udev/rules.d/89-local.rules # add rule: if we have a valid id_fs_label_enc, and it's usb, mkdir and mount env{id_fs_label_enc}=="?*", action=="add", subsystems=="usb", \ run+="/usr/local/sbin/udev-automounter.sh %k" \の後にスペースがないこと、ちょうどnewline(\n)があることを確認してください。 firewireサポートのためにsubsystems=="usb"をsubsystems=="usb|ieee1394"に変更してください。 デバイスを常に特定のユーザーが所有するようにしたい場合は、owner="username"句を追加します。特定のユーザーが所有するファイルだけが必要な場合は、代わりにマウントスクリプトを微調整してください。 ルールを読むこれにより、実行するプログラムがデバイスの実行プログラムリストに追加されます。 usbパーティションデバイスを<label>で識別してから、この情報をマウントを実行するスクリプトに渡します。具体的には、この規則は一致しています。 env{id_fs_label_enc}=="?*" - 以前のシステムルールによって設定された環境変数。非ファイルシステムには存在しないので、それをチェックします。実際にはマウントポイントにid_fs_labelを使いたいのですが、udevにそれをエスケープするようには思わせないので、マウントスクリプトにそれを処理させます。 この環境変数およびその他の環境変数は、udevによってvol_idコマンドを使用して取得されます( deprecated )。パーティションに関するすばやく詳細を確認するのに便利なツールです。 $ sudo vol_id /dev/sdc1 id_fs_type=ext2 id_fs_uuid=a40d282a-4a24-4593-a0ab-6f2600f920dd id_fs_label=travel dawgs id_fs_label_enc=travel\x20dawgs id_fs_label_safe=travel_dawgs action=="add" - addイベントにのみ一致します... subsystems=="usb" - usbバス上にあるデバイスだけに一致します。ここではsubsystemsを使用しています。これは私たちのデバイスの親に対して一致するからです。私たちが興味を持っているデバイスは実際にはsubsystem == "scsi"です。親のusbデバイスと照合することで、内蔵ドライブにプログラムを追加することを避けられます。 run+="..." - 一致ではなく、アクション:実行するプログラムのリストにこのプログラムを追加してください。プログラムの引数では、%kはデバイス名(例えばsdc1ではなく/dev/sdc1)に展開され、$env{foo}は環境変数fooの内容を取得します。 ルールをテストする最初の参照リンク(上)は優れたudevチュートリアルですが、少し古くなっています。ルールをテストするために実行されるプログラム(特にudevtest)は、catch-all udevadmユーティリティに置き換えられました。ルールを追加したら、デバイスを接続します。数秒待ってから、割り当てられているデバイスを確認します。$ ls -l /dev/disk/by-label/* lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_foo -> ../../sda1 lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_bar -> ../../sdb1 lrwxrwxrwx 1 root root 10 2009-10-25 07:27 label_baz -> ../../sdc1 取り外し可能ドライブにlabel_bazが含まれている場合、それはデバイスsdc1上にあります。これを実行して、最後の方の出力を見てください。$ sudo udevadm test /sys/block/sdc/sdc1 parse_file: reading (...) (many lines about files it reads) import_uevent_var: import into environment: (...) (many lines about env variables) (...) (many lines tracing rule matches & programs run) update_link: found 1 devices with name 'disk/by-label/label_baz' update_link: found '/block/sdc/sdc1' for 'disk/by-label/label_baz' update_link: compare (our own) priority of '/block/sdc/sdc1' 0 >= 0 update_link: 'disk/by-label/label_baz' with target 'sdc1' has the highest priority 0, create it udevtest: run: '/usr/local/sbin/udev-automounter.sh sdc1 label_baz' udevtest: run: 'socket:/org/freedesktop/hal/udev_event' udevtest: run: 'socket:@/org/kernel/udev/monitor' 最後の数行で、このrun+=ルールからスクリプト名を探します(この例では下から3番目)。この装置に使用される引数を見ることができます。このコマンドを実行して、引数が正しいことを確認できます。それがあなたのコマンドラインで動作するなら、それはデバイスが挿入されたときに自動的に動作するはずです。udevイベントをリアルタイムで監視することもできます。sudo udevadm monitorを実行します(スイッチの詳細についてはman udevadmを参照)。それから新しいデバイスを接続してイベントがスクロールするのを見てください。 (あなたが本当に低レベルの詳細に陥っていない限り、おそらくやり過ぎるでしょう...) ルールの再読み込みルールが正しく読まれていることを確認したら、新しいルールが有効になるように、udevにそのルールをリロードするように指示する必要があります。これらの方法のいずれかを使用してください(最初の方法でうまくいかない場合は、2番目の方法でも構いませんが、最初の方法を試してください)。 sudo udevadm control --reload-rulesを実行する sudo /etc/init.d/udev reloadを実行する リブート スクリプト!実際には、2つのスクリプト... これが最初のスクリプトです。実行するプログラムは短時間で完了する必要があるため、これは2番目のスクリプトをバックグラウンドで回転させるだけです。これを/usr/local/sbin/udev-automounter.shに入れます。#!/bin/sh # # usage: usb-automounter.sh device # device is the actual device node at /dev/device /usr/local/sbin/udev-auto-mount.sh ${1} & これが2番目のスクリプトですこれはもう少し入力チェックを行います。これを/usr/local/sbin/udev-auto-mount.shに入れてください。以下のマウントオプションを微調整することをお勧めします。このスクリプトは現在、パーティションlabelをそれ自身で見つけることを処理します。 udevはdevice名のみを送信します。起動時にドライブのマウントに問題がある場合は、このスクリプトにnice long sleep 60を設定して、スクリプトが実行を試みる前にシステムが起動するまでの時間を確保することができます。ドライブをマウントしてください。どのようにチェックするかについてのコメントで提案をしました(ウェブサーバが動いているかどうか見るためにpsを走らせてください)、しかしあなたはあなたのシステムのためにそれを微調整したいでしょう。 nfsd、smbd、apacheなど、ほとんどのネットワークサーバーでこの目的に十分であると私は思います。もちろん、サービスが実行されていないとマウントスクリプトが失敗する可能性があります。特定のファイルの存在はより良い解決策になるでしょう。#!/bin/sh # # usage: udev-auto-mount.sh device # device is the actual device node at /dev/device # # this script takes a device name, looks up the partition label and # type, creates /media/label and mounts the partition. mount options # are hard-coded below. device=$1 # check input if [ -z "$device" ]; then exit 1 fi # test that this device isn't already mounted device_is_mounted=`grep ${device} /etc/mtab` if [ -n "$device_is_mounted" ]; then echo "error: seems /dev/${device} is already mounted" exit 1 fi # if there's a problem at boot-time, this is where we'd put # some test to check that we're booting, and then run # sleep 60 # so the system is ready for the mount below. # # an example to experiment with: # assume the system is "booted enough" if the httpd server is running. # if it isn't, sleep for half a minute before checking again. # # the risk: if the server fails for some reason, this mount script # will just keep waiting for it to show up. a better solution would # be to check for some file that exists after the boot process is complete. # # httpd_up=`ps -ax | grep httpd | grep -v grep` # while [ -z "$httpd_up" ]; do # sleep 30 # httpd_up=`ps -ax | grep httpd | grep -v grep` # done # pull in useful variables from vol_id, quote everything just in case eval `/sbin/vol_id /dev/${device} | sed 's/^/export /; s/=/="/; s/$/"/'` if [ -z "$id_fs_label" ] || [ -z "$id_fs_type" ]; then echo "error: id_fs_label is empty! did vol_id break? tried /dev/${device}" exit 1 fi # test mountpoint - it shouldn't exist if [ ! -e "/media/${id_fs_label}" ]; then # make the mountpoint mkdir "/media/${id_fs_label}" # mount the device # # if expecting thumbdrives, you probably want # mount -t auto -o sync,noatime [...] # # if drive is vfat/nfts, this mounts the filesystem such that all files # are owned by a std user instead of by root. change to your user's uid # (listed in /etc/passwd). you may also want "gid=1000" and/or "umask=022", eg: # mount -t auto -o uid=1000,gid=1000 [...] # # case "$id_fs_type" in vfat) mount -t vfat -o sync,noatime,uid=1000 /dev/${device} "/media/${id_fs_label}" ;; # i like the locale setting for ntfs ntfs) mount -t auto -o sync,noatime,uid=1000,locale=en_us.utf-8 /dev/${device} "/media/${id_fs_label}" ;; # ext2/3/4 don't like uid option ext*) mount -t auto -o sync,noatime /dev/${device} "/media/${id_fs_label}" ;; esac # all done here, return successful exit 0 fi exit 1 スーパーボーナスクリーンアップスクリプトもう1つのスクリプトこれは、デバイスをアンマウントしてマウントポイントディレクトリを削除するだけです。これにはprivがあると仮定しているので、sudoを付けて実行する必要があります。このスクリプトはコマンドラインのフルマウントポイントを取得します。例えば:$ /usr/local/sbin/udev-unmounter.sh "/media/my random disk" これを/usr/local/sbin/udev-unmounter.shに入れます。#!/bin/sh # # usage: udev-unmounter.sh mountpt # mountpt is a mountpoint we want to unmount and delete. mountpt="$1" if [ -z "$mountpt" ]; then exit 1 fi # test mountpoint - it should exist if [ -e "${mountpt}" ]; then # very naive; just run and pray umount -l "${mountpt}" && rmdir "${mountpt}" && exit 0 echo "error: ${mountpt} failed to unmount." exit 1 fi echo "error: ${mountpt} does not exist" exit 1