Ubuntu Gutsy(7.10)でuswsusp関連の設定を半自動で行うスクリプトを試作
「Ubuntu Gutsy(7.10)でuswsusp + hibernate-scriptによるハイバネーションを行う」で行った作業は結構面倒なので、その何倍もの手間をかけて、この作業を半自動化してみる実験。「Ubuntu Gutsy(7.10)でuswsuspのスワップ「ファイル」からの復帰ができなかった件の対処と、ファイルへの書き込みの流れ」をもとに、ファイルへの書き込みも、選択により、必要な作業を半自動で行う。
このスクリプトは、
- uswsuspの設定を行う際のインターフェースが端末(Dialog)になっている場合にDebConfの再設定をさせる(「Gnome」を選択することで、以降の設定がGUIになる)
- uswsuspとhibernateのいずれかがインストールされていない場合に自動でインストール
- スワップファイルへ書き込む場合に、「ファイル作成/初期化/fstabへ登録/swapon/位置情報(resume offset)の自動設定」を行い、スワップファイルを含むパーティションを選択させての反映も行う
- hibernate-scriptでuswsuspを優先して使用するための設定(自動)
- パスワード無しでhibernate-scriptを実行するためのsudoの設定を自動で行うか、もしくは、geditテキストエディタを使用してvisudoを実行
- 確認ダイアログの出るラッパースクリプトと、これを実行するランチャをインストール
といった作業を行うが、手動で設定ファイルを編集する部分が省略(自動化)できるのは大きい。
ファイル選択や、スワップファイルのサイズ指定、スワップファイルのあるパーティション選択などに、zenityを使用して、GUIでの入力を可能にしている。ダイアログ表示にも使用している。
一部、メッセージを「はい/いいえ」にしたかったが「OK/キャンセル」にしかならない部分もあるので、「キャンセル」を「いいえ」に読み替える必要のあるところもある。
また、何かしらの不具合が含まれている可能性もあるので注意。
[任意]ファイル名: uswsusp-config-gutsy.sh
#! /bin/bash USWSUSP_CONF=/etc/uswsusp.conf HIBERNATE_CONF=/etc/hibernate/hibernate.conf WRAPPER=/usr/local/bin/hibernate-wrapper LAUNCHER=/home/${SUDO_USER}/デスクトップ/休止状態.desktop cancel() { zenity --info --title "取り消し" --text "キャンセルされたので、終了します。" exit 1 } die() { zenity --error --title "エラー" --text "エラーが発生しました" exit 1 } # 一般ユーザ権限で実行したらエラー if [ $(whoami) != "root" ]; then zenity --error --title "管理者権限で実行してください" --text "\ このスクリプトは、ファイルマネージャの右クリックメニューの 「別のアプリで開く」から「コマンドを指定する」に 「gksudo」と入れて実行してください。 2回目以降は、メニューの「\"gksudo\" で開く」から実行できます。" exit 1 fi # 実行中であることを示すためにシステムトレイを使用 exec 3> >(zenity --notification --window-icon /usr/share/pixmaps/ubuntu.svg --text "uswsusp設定ツールの動作中" --listen) # DebConfが端末に設定されていたら変更させる debconf-show debconf 2> /dev/null | grep "frontend: Dialog" >/dev/null if [ $? = 0 ]; then echo "tooltip: DebConf設定ツールの設定" >&3 zenity --info --title "DebConfの設定" --text "\ uswsuspの設定をGUIで行うのに必要な設定を はじめに行っておくことを推奨します。 キーボードの矢印キーで「Gnome」を選んでEnterを押してください。 その後の質問には、そのままEnterを押していけばOKです。 (一度設定を行えば、2回目以降これを行う必要はありません)" gnome-terminal -t 'DebConf設定ツールの設定' --hide-menubar -x dpkg-reconfigure debconf fi # uswsuspとhibernateがインストールされているかをチェック USWSUSP_HIBERNATE=$(dpkg-query -W -f='${Status}\n' uswsusp hibernate | grep "install ok installed" | wc -l) if [ ${USWSUSP_HIBERNATE} != 2 ]; then echo "tooltip: uswsuspとhibernateをインストール" >&3 zenity --info --title "パッケージの自動インストール" --text "\ uswsuspもしくはhibernateのパッケージががインストールされていません。 自動的にインストールされるので、 終了するまでの間、出てきた端末を閉じないでください。 「利用可能なスワップ領域がありませんが、続行しますか?」 とだけ表示されたら、キャンセルせず、「次へ」をクリックしてください。 設定は後で行われます。" # インストール gnome-terminal -t 'インストール中...' --hide-menubar -x apt-get -y install uswsusp hibernate fi # ファイルへのイメージ書き込みを行うか質問 echo "tooltip: イメージ書き込みの質問" >&3 zenity --question --title "ファイルへのイメージ書き込みを行いますか?" --text "\ ファイルへのメモリイメージ書き込みを行うことはできますが、 DebConf設定ツールでは ファイルへの書き込みを設定することができないため、 本ツールで補助的な作業を行います。 ファイルへのイメージ書き込みを行いますか?" if [ $? = 0 ]; then # ファイルへ書き込む echo "tooltip: スワップファイルの質問" >&3 zenity --question --title "スワップファイルを作成しますか?" --text "\ スワップファイルが作成されていない場合は、ここで作成してください。 作成しない場合は、 現在有効になっているスワップファイルの場所を指定してください。 注意: 一度作成したスワップファイルの場所を変更/削除した後には、 「gksudo gedit /etc/fstab」を実行して、 自動マウントの設定ファイル(/etc/fstab)を開いて、 スワップファイルの含まれる行を編集/削除する必要があります。 作成しますか?" if [ $? = 0 ]; then # 新規作成 SWFILE=$(zenity --file-selection --title "スワップファイルの保存先" --save --confirm-overwrite) if [ $? != 0 ]; then cancel; fi SWFSIZE=$(zenity --scale --title "スワップファイルのサイズ" --text "MiB単位でスワップフ ァイルのサイズを指定してください。" --min-value 32 --max-value 2048 --value 96 --step 16) if [ $? != 0 ]; then cancel; fi echo "tooltip: スワップファイルの初期化中" >&3 dd if=/dev/zero of=${SWFILE} bs=1M count=${SWFSIZE} || die mkswap ${SWFILE} || die # 自動マウントの設定後、有効にする echo ${SWFILE} none swap sw 0 0 >> /etc/fstab || die swapon -a || die else # 既存のスワップファイルを選択 SWFILE=$(zenity --file-selection --title "スワップファイルの選択") if [ $? != 0 ]; then cancel; fi # スワップとして使用されているか確認 swapon -s | grep file | cut -d " " -f 1 | grep ${SWFILE} > /dev/null if [ $? != 0 ]; then zenity --error --title "使用されているスワップファイルではありません" --text "\ このファイル(${SWFILE})は、 現在使用されているスワップのリストに含まれていません。 正しいファイルを選択したか確認するか、新しく作り直してください。" exit 1 fi fi echo "tooltip: スワップファイルを含むパーティションの質問" >&3 DFT=0 CMD="zenity --list --title スワップファイルを含むパーティションを選択 --text スワップファイルを含むパーティションを下から選択してください。 --radiolist --column 選択 --column デバイス名" CMD=${CMD}$(cat /etc/mtab | grep ^/dev/ | cut -d " " -f 1 | while read x; do if [ ${DFT} = 0 ]; then DFT=1; printf " true ${x}"; else printf " false ${x}"; fi; done) RESUMEDEV=$(${CMD}) # リスト選択を起動 if [ $? != 0 ]; then cancel; fi # resume deviceを選択された値に置き換える sed -i -e "s|\(resume device =\).*$|\1 ${RESUMEDEV}|" ${USWSUSP_CONF} # resume offsetがあれば一旦消す sed -i -e 's/resume offset.*$//' -e '/^$/d' ${USWSUSP_CONF} # resume offsetを取得して設定ファイルに追記 swap-offset ${SWFILE} >> ${USWSUSP_CONF} echo "tooltip: uswsuspの設定" >&3 zenity --info --title "uswsuspの設定" --text "\ これから、uswsuspの設定を行います。 「利用可能なスワップ領域がありませんが、続行しますか?」は そのままで、それ以外の設定項目を編集します。 デバイスノードやログレベルは空のままでも大丈夫です。 スワップ領域の選択はいじらないでください。" else # パーティションへ書き込む SWP=$(swapon -s | grep partition) if [ $? != 0 ]; then zenity --error --title "有効なスワップパーティションが存在しません" --text "\ 有効なスワップパーティションが存在しないため、作業は続行できません。 再び実行後、スワップファイルを使用する設定を行ってください。" exit 1 fi SWPDEV=$(echo ${SWP} | cut -d " " -f 1 | head -n 1) # resume offsetがあれば消す sed -i -e 's/resume offset.*$//' -e '/^$/d' ${USWSUSP_CONF} # UUID表記があればデバイス名に修正 grep "resume device = UUID" ${USWSUSP_CONF} >/dev/null && sed -i -e "s/UUID=.*$/${SWPDEV}" ${USWSUSP_CONF} echo "tooltip: uswsuspの設定" >&3 zenity --info --title "uswsuspの設定" --text "\ これから、uswsuspの設定を行います。 「利用可能なスワップ領域がありませんが、続行しますか?」は そのままで、それ以外の設定項目を編集します。 デバイスノードやログレベルは空のままでも大丈夫です。 スワップ領域は、適切なものが選択されているかを確認してください。 (スワップファイルからパーティションに変更する場合は注意)" fi dpkg-reconfigure uswsusp # uswsuspを優先させるようにhibernate scriptを設定 sed -i -e 's/^\(TryMethod suspend2.conf\)$/TryMethod ususpend-disk.conf\n\1/' ${HIBERNATE_CONF} # sudoの設定 if [ $(grep HIBERNATE /etc/sudoers | wc -l) != 2 ]; then # 未設定とみなす echo "tooltip: sudoの設定" >&3 zenity --question --title "sudoの設定を自動で行いますか?" --text "\ 休止をパスワード無しで実行するために、sudoの設定が必要です。 /etc/sudoersファイルを直接更新するのは推奨されず、 visudoというコマンドで編集するのが一般的です。 しかし、自動編集では一瞬で終わる上に楽です。 直接このファイルを自動で編集しますか?" if [ $? = 0 ]; then sed -i -e 's|^\(# Cmnd alias specification\)$|\1\nCmnd_Alias HIBERNATE=/usr/sbin/hibernate|' /etc/sudoers echo "%admin ALL=NOPASSWD: HIBERNATE" >> /etc/sudoers else zenity --info --no-wrap --title "手動編集" --text "\ 「Cmnd alias」のセクションに「Cmnd_Alias HIBERNATE=/usr/sbin/hibernate」 最終セクションに「%admin ALL = NOPASSWD: HIBERNATE」を、それぞれ追加してください。" EDITOR=/usr/bin/gedit visudo fi fi # ラッパーの作成 if [ ! -f ${WRAPPER} ]; then cat <<EOF > ${WRAPPER} #! /bin/dash HIBERNATE_OPT="--force" VERSTYLE_OPEN="<span style='italic' weight='bold' foreground='darkred'>" VERSTYLE_CLOSE="</span>" if [ "$1" != "-f" ]; then zenity --question --title="休止状態の確認" --text "\ uswsusp:\t\t\${VERSTYLE_OPEN}\$(dpkg-query -W -f='\${Version}\n' uswsusp)\${VERSTYLE_CLOSE} hibernate-script:\t\${VERSTYLE_OPEN}\$(dpkg-query -W -f='\${Version}\n' hibernate)\${VERSTYLE_CLOSE} 休止しますか?" if [ \$? = 1 ]; then exit 1 fi fi sudo /usr/sbin/hibernate \${HIBERNATE_OPT} numlockx off; numlockx on EOF chmod 755 ${WRAPPER} fi # .desktopファイルの作成 if [ ! -f ${LAUNCHER} ]; then cat <<EOF > ${LAUNCHER} [Desktop Entry] Encoding=UTF-8 Version=1.0 Type=Application Terminal=false Name[ja_JP]=休止状態 Exec=/usr/local/bin/hibernate-wrapper Comment[ja_JP]=メモリの内容をディスクに書き込んで電源を切ります。 Icon[ja_JP]=ubuntu Name=休止状態 Comment=メモリの内容をディスクに書き込んで電源を切ります。 Icon=ubuntu EOF chown ${SUDO_UID}:${SUDO_GID} ${LAUNCHER} fi # 完了 echo "tooltip: 完了" >&3 zenity --info --title "設定完了" --text "\ 以上で設定は終了です。お疲れさまでした。 休止を行うには、アイコンから実行するか、 「/usr/local/bin/hibernate-wrapper」を実行してください。"
この内容をコピペして保存し、ファイルマネージャの右クリックメニューから「別のアプリで開く」を選び、「コマンドを指定する」に「gksudo」と入力するなどして、管理者権限で実行する。
関連記事: