debconf开发小本本

debconf开发者手册

主要针对bash脚本/程序的debconf开发
0814更新:一个基于debconf开发的demo

普通shell脚本

#!/bin/sh -e
echo -n "Do you like debian? [yn] "
read like
case "$like" in
n*|N*)
    echo "Poor misguided one. Why are you installing this package, then?"
    /etc/init.d/subliminal_messages start "I like debian."
;;
esac

debconf的templates模板文件示例


Template: packagename/something
Type: [select,multiselect,string,boolean,note,text,password]
Default: [an optional default value]
Description: Blah blah blah?
 Blah blah blah. Blah blah. Blah blah blah. Blah blah? Blah
 blah blah blah. Blah blah blah. Blah blah.
 .
 Blah blah blah. Blah blah. Blah blah blah. Blah blah. Blah blah blah.
 blah.

Template: ....
....
  1. 注意Type域有select, multiselect, string, boolean, note, text, password几种类型选一个
  2. Description域后面紧接着一段简短描述,下面写详细描述。且.表示一行空行
  3. Type域详细描述:
Type Description
string Holds any arbitrary string of data.
boolean Holds “true” or “false”.
select Holds one of a finite number of possible values. These values must be specified in a field named Choices:. Separate the possible values with commas and spaces, like this: Choices: yes, no, maybe
multiselect Just like the select data type, except the user can choose any number of items from the list. This means that the Default: field and the actual value of the question may be a comma and space delimited list of values, just like the Choices: field.Note: For compatability with old versions of Debconf, if you use this data type, please make your package depend on debconf (>= 0.2.26)
note This template is a note that can be displayed to the user. As opposed to text, it is something important, that the user really should see. If debconf is not running interactively, it might be saved to a log file or mailbox for them to see later.
text This template is a scrap of text that can be displayed to the user. It’s intended to be used for mostly cosmetic reasons, touching up around other questions that are asked at the same time. Unlike a note, it isn’t treated as something the user should definitely see. Less complex frontends may refuse to ever display this type of element.
password Holds a password. Use with caution. Be aware that the password the user enters will be written to debconf’s database. You should consider clearing that value out of the database as soon as is possible.

4. templates实例:

Template: foo/like_debian
Type: boolean
Description: Do you like Debian?
We’d like to know if you like the Debian GNU/Linux system.

Template: foo/why_debian_is_great
Type: note
Description: Poor misguided one. Why are you installing this package?
Debian is great. As you continue using Debian, we hope you will
discover the error in your ways.

templates模板本地化

  1. 例如对Description域进行本地化翻译,只需要在其下面添加一个Description-zh_CN.UTF-8域,然后把对应的英文翻译成中文即可
  2. 注意每种语言最好单独使用一个templates模板文件,比如templates.zh_CN
  3. 更新本地化templates模板:debconf-getlang zh\_CN templates > templates.zh\_CN
  4. 合并新的templates模板:debconf-getlang zh_CN templates templates.zh_CN > new.zh_CN
  5. fuzzy: 如果某个域设置了这个字段,则表示这个域无效
  6. 以上几点在不同环境/版本上可能有所不同,可以查查其他设置本地化的方法!

debconf的shell接口

  • 在shell脚本中设置. /usr/share/debconf/confmodule来导入debconf的大量函数
  • 采用debconf配置管理的shell脚本(注意这里的注释):
#!/bin/sh -e

# Source debconf library.
. /usr/share/debconf/confmodule

# Do you like debian?
## 注意!! 这里在测试的时候可以加上以下一行,将问题域设置为`unseen`——尚未处理的意思,否则域被设置一次后将不会被重复提起!:
## db_fset foo/like_debian seen false ||true
db_input medium foo/like_debian || true
db_go

# Check their answer.
db_get foo/like_debian
if [ "$RET" = "false" ]; then
    # Poor misguided one..
    db_input high foo/why_debian_is_great || true
    db_go
fi
  • 回退函数:db_capb backup,用于回退到上一个交互界面
#!/bin/sh -e

# Source debconf library.
. /usr/share/debconf/confmodule
db_version 2.0

# This conf script is capable of backing up
db_capb backup

## 注意这个状态机, 经常用来实现多个交互界面的串联
STATE=1 
while [ "$STATE" != 0 -a "$STATE" != 3 ]; do
    case "$STATE" in
    1)
        # Do you like debian?
        db_input medium foo/like_debian || true
    ;;

    2)
        # Check to see if they like debian.
        db_get foo/like_debian
        if [ "$RET" = "false" ]; then
            # Poor misguided one..
            db_input high foo/why_debian_is_great || true
        fi
    ;;
    esac

    if db_go; then
        STATE=$(($STATE + 1))
    else
        STATE=$(($STATE - 1))
    fi
done
  • 无限循环,注意对跳出循环的时机的把握
# 这里先初始化变量`ok`,避免死循环
ok=''
do while [ ! "$ok" ];
    db_input low foo/bar || true
    db_go || true

    db_get foo/bar
    if [ "$RET" ]; then
        ok=1
    fi
done
  • 选项的选择功能,实现多个(multiselect)或者单个(select)选项的选择,例如:

    1. 在templates目标中设置:

      Template: shared/window-manager
      Type: select
      Choices: ${choices}
      Description: Select the default window manager.
      Select the window manager that will be started by default when X
      starts.

    2. 在shell脚本中设置:

\# 获取`owners`域的值
db_metaget shared/window-manager owners
OWNERS=$RET
\# 获取`choices`域的值
db_metaget shared/window-manager choices
CHOICES=$RET
if [ "$OWNERS" != "$CHOICES" ]; then
    # 设置`shared/window-manager`域的显示信息
    db_subst shared/window-manager choices $OWNERS
    db_fset shared/window-manager seen false
fi
db_input medium shared/window-manager || true
db_go || true
  • 安装后脚本清理debconf数据库

    1. 在prerm脚本中添加以下内容,注意根据实际情况修改:
if [ -e /usr/share/debconf/confmodule ]; then
    . /usr/share/debconf/confmodule
    # I no longer claim this question.
    db_unregister shared/window-manager

    # See if the shared question still exists.
    if db_get shared/window-manager; then
        db_metaget shared/window-manager owners
        db_subst shared/window-manager choices $RET
        db_metaget shared/window-manager value
        if [ "" = "$RET" ] ; then
            db_fset shared/window-manage seen false
            db_input critical shared/window-manager || true
            db_go || true
        fi

        # Now do whatever the postinst script did tp upsate
        # the window manager symlink or whatever.
    fi
fi

小结

  1. db_set:设置某个域的值;对应db_get获取某个域的值
  2. db_fset:设置某个域的已设置标记,true表示已设置,false表示未设置;一般只有未设置的交互界面才会弹出来;对应db_fget,获取标记的值
  3. db_metaget:获取某个域的元域的信息,例如获取Description域的描述
  4. db_subst:设置域的属性,在需要弹窗时,一般先db_subst设置要显示的属性
  5. db_input:第一个参数为优先级别,一般有”low”, “medium”, “high”, “critical”,优先级别依次提高,一般达到”critical”肯定会被弹窗
  6. db_go: 一般表示下一步,进入下一阶段
  7. db_capb:一般跟一个backup,表示回退,具体的回退功能代码需要根据实际情况自己实现, 例如实现一个状态机

实际操作

  • 先摆一个可操作的shell脚本foo.config示例:
#!/bin/sh -e
# @filename: foo.config
#set -x
# Source debconf library.
. /usr/share/debconf/confmodule

# Do you like debian?
# db_input medium foo/like_debian || true
db_fset foo/like_debian seen false ||true
db_input critical foo/like_debian || true
db_go
# Check their answer.
db_get foo/like_debian
if [ "$RET" = "false" ]; then
    # Poor misguided one..
    db_metaget foo/why_debian_is_great Description
    db_subst foo/why_debian_is_great Description $RET
    db_fset foo/why_debian_is_great seen false||true
    db_input critical foo/why_debian_is_great || true
    db_go
fi

db_metaget shared/window-manager owners
OWNERS=$RET
db_metaget shared/window-manager choices
CHOICES=$RET

if [ "$OWNERS" != "$CHOICES" ]; then
    db_subst shared/window-manager choices $OWNERS
    db_fset shared/window-manager seen false
fi

db_fset shared/window-manager seen false|| true
db_input critical shared/window-manager || true
db_go || true
  • foo.templates目标示例
# @filename: foo.templates
Template: foo/like_debian
Type: boolean
Description: Do you like Debian?
 We'd like to know if you like the Debian GNU/Linux system.

Template: foo/why_debian_is_great
Type: note
Description: Poor misguided one. Why are you installing this package?
 Debian is great. As you continue using Debian, we hope you will
 discover the error in your ways.

Template: shared/window-manager
Type: select
Choices: a, b, c
Description: Select the default window manager.
 Select the window manager that will be started by default when X
 starts.

关于db_input函数的一些常用方法

你可能感兴趣的:(工作笔记)