项目引入模式的案例——Excel扩展单元格

前些日子做一个Excel扩展行的机制,简单说,模板-->生成文件,模板和文件均是excel文件,其中模板有很多公式,其中要说的是这个扩展行的公式#L:${}(至于如何解析Excel,有兴趣的朋友可以去了解poi和js的犀牛引擎,ps:java项目)
具体如下图所示:
  上图模板经过解析后的结果图:

  到现在扩展行功能运行的很好,很快顶头上司跟我说了他的新想法,他想为扩展行提供分组隐藏,负数显红色等等功能支持。具体是像下面的样子:

  直觉上我感觉这个“等等”是做不完的,很明显今天说偶数行变斜体,明天就会出来单元格内容含有“张”字的变8号宋体,甚至出现某单元格类型是数字类型另外一个单元格是日期类型。该怎么去实现这些无穷尽的变化呢?解决问题前,我先介绍下我的工作性质,我是做平台开发支持的,所开发的东西都服务于其他部门人员,也即我做工具平台,别人拿来结合业务2次开发。我的客户是跟我一样的程序员。
  来想想我的客户需要什么,我需要给他们提供以下支持:单元格内容的动态变化,单元格Style(包含字体、边框等样式)变化,单元格类型变化,除此之外,还有什么地位值得注意呢?有没有发现这种变化机制和具是体单元格是松耦合的,比如“偶数行斜体”这个你可以在A1列使用,也可以在A2列使用,看来这种机制要独立可重复,同时我们还能发现,“偶数行斜体”和“负数显红色”可以叠加。
  现在问题已经很清晰了,我们需要为“某单元格”提供一个可以独立、叠加“装饰”的机制。我真的不知道除了“装饰”二字我还能用什么词语更好的形容这种机制,坦言当时我的脑海里已经浮现了“装饰模式”,也许这是很自然的,因为问题已经被分析用“装饰”词语去描述。
  本文不打算拿大段文字去描述何为装饰模式,也许你可以到这里去了解它 装饰模式。我们知道Decorator Pattern意图是:动态地给一个对象添加一些额外的职责。从前面的分析我们可以看到我们确实需要动态地给一个对象(单元格对象)添加额外的职责(让它变红,变斜体等等)。
  你是否同意我用装饰模式呢?这里插入一段我和我们经理的讨论:(我老大是个比较强势的人,一般喜欢用自己的经验去压制你,让你按他的想法去实现,呵呵,我习惯了)。
  正当我对自己画出的草图happy的时候,经理过来问我打算怎么做,我说了下自己的想法,他想了下说,他有个办法,他说首先提供一个单元格信息的context(上下文)其内容包含CellType、CellValue、CellStyle等等,然后做一个管道,管道每个节点有一个get和set方法,最后让CellContext(某一个上下文)依次经过每个节点,改变其状态,最后通过上下文取得CellType、CellValue、CellStyle。
  不能不说下我老大已是有10年的开发经验牛人,很多时候我都是按他的思路去实现,对于老大刚刚说的办法我感觉不错,可当时我脑子里都是装饰模式,我不想放弃自己的方案,他看出了我的不愉快,接着他介绍到这就和监听模式一样,我疑问到“监听模式?是观察者模式么?”老大说一个context被一个个监听然后改变,我很怀疑老大是不是搞错了,因为我据我所知观察者不是为了改变状态,观察者是为某些对象建立一种“通知依赖关系”至于观察者是不是想要改变自身或者被观察者的状态那是另外一回事。从意图上看老大是没有使用好观察者,我们不是需要“当一个对象的状态发生改变时, 所有依赖于它的对象都得到通知并被自动更新”。我们需要的是如何实现“动态改变自身的状态”。
  当然最后我之言了老大对模式的理解偏差,当然我能感觉到他的管道模式确实可以解决这个问题,后来也证明了这种管道的解决方案可以提供更高的性能,我甚至怀疑管道模式是不是装饰模式的简化版。不管怎样我还是用了自己的方案。
  下面这张图是简化的解决方案类图。

  上面这个类图能看出来IExcelComponent接口是关键,其中实现次接口的DefaultCell相当于微粒其包含一个ExcelContext对象,对应到装饰模式类图,DefaultCell便是ConcreteComponent这是个被装饰的对象,我感觉叫做微粒很合适,有了微粒空气中的水蒸汽会附着凝结降下雨水。CellDecorator这里是所有修饰子类的基类。
文章开始部分谈到如何实现这无穷尽的变化---这里变化就是CellDecorator的子类变化。我打算支持做到这里,子类的编程留给其他人来做,至于使用者打算做成什么样子,我不需要考虑。
  真正写程序时你会发现自己勾勒的美好蓝图,实施的时候会遇到一些小麻烦。我就遇到一个困难——装饰子类的实例化问题,正常情况通过构造器把IExcelComponent当作参数实例化。
那么代码应该这么写:
1 DefaultCell dcell = new  DefaultCell( new  ExcelContext( " 和当前单元格相关信息 " ));
2 MergeGroupDecorator gd = new  MergeGroupDecorator(dcell);
3 FontColorDecorator fd = new  FontColorDecorator(gd);
  上面写的是分组隐藏和颜色更改两个装饰使用的伪代码。
可以看到既然现在子类是由使用者实现,那么我无法估计到怎么实例化他,就是装饰子类的构造器我都无法知道我怎么实例化呢?真实使用模式我们也许根本无法完全套用模式的案例,也没必要完全模仿,我们只要把握模式的精髓就可以了。
既然无法预计怎么实例化那么就不去用构造器,我们自己定义set方法给CellDecorator,
1 ExpandedBlockStart.gif ContractedBlock.gif      /** */ /**设置待修饰构件*/
2 ExpandedBlockStart.gifContractedBlock.gif     public   void  setComponent(IExcelComponent component)  {
3        this._component = component;
4    }
  这样子类继承后,我们自然可以使用这个方法,进而避免了实例化的困窘。我们需要做的是收集所有子类的类型,可以提供一个注册装饰类的方法,装饰类集中在一个字典里,我们可以在扩展列声明每列使用哪些装饰,然后去查找对应的装饰类。
  接下来我从构建到使用给出所有部分代码和文档。
IExcelComponent   装饰基础接口:
ContractedBlock.gif ExpandedBlockStart.gif Code
 1package lovebaobao.util.template.excel;
 2
 3import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 4
 5ExpandedBlockStart.gifContractedBlock.gif/** *//**
 6 * 单元格修饰构件基类接口
 7 * 
 8 * @author zhangmm
 9 * 
10 */

11ExpandedBlockStart.gifContractedBlock.gifpublic interface IExcelComponent {
12
13ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
14     * 取得上下文
15     */

16    ExcelContext getContext();
17
18ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
19     * 取得显示值
20     */

21    Object getValue();
22
23ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
24     * 取得显示样式
25     */

26    HSSFCellStyle getStyle();
27
28ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
29     * 取得此单元格类型
30     */

31    int getType();
32}

33
CellDecorator  装饰者基类:
ContractedBlock.gif ExpandedBlockStart.gif Code
 1package lovebaobao.util.template.excel;
 2
 3import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 4
 5ExpandedBlockStart.gifContractedBlock.gif/** *//**
 6 * Cell修饰基类
 7 * 具体设置可以参考——http://www.diybl.com/course/3_program/java/javajs/2008920/143868.html
 8 * @author zhangmm
 9 * 
10 */

11ExpandedBlockStart.gifContractedBlock.gifpublic class CellDecorator implements IExcelComponent {
12
13ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 持有私有的原始构件 */
14    private IExcelComponent _component;
15    
16ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**设置待修饰构件*/
17ExpandedSubBlockStart.gifContractedSubBlock.gif    public void setComponent(IExcelComponent component) {
18        this._component = component;
19    }

20
21ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 调用原始构件功能:取得显示值 */
22ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object getValue() {
23        return _component.getValue();
24    }

25
26ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 调用原始构件功能:取得显示样式 */
27ExpandedSubBlockStart.gifContractedSubBlock.gif    public HSSFCellStyle getStyle() {
28        return _component.getStyle();
29    }

30
31ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 调用原始构件功能:取得此单元格类型 */
32ExpandedSubBlockStart.gifContractedSubBlock.gif    public int getType() {
33        return _component.getType();
34    }

35
36ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 调用原始构件功能:取得此单元格的上下文 */
37ExpandedSubBlockStart.gifContractedSubBlock.gif    public ExcelContext getContext() {
38        return _component.getContext();
39    }

40
41}

42

ExcelContext 上下文类

ContractedBlock.gif ExpandedBlockStart.gif Code
  1package lovebaobao.util.template.excel;
  2
  3import java.util.List;
  4
  5import org.apache.poi.hssf.usermodel.HSSFCell;
  6import org.apache.poi.hssf.usermodel.HSSFCellStyle;
  7import org.apache.poi.hssf.usermodel.HSSFFont;
  8import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  9
 10ExpandedBlockStart.gifContractedBlock.gifpublic class ExcelContext {
 11    private HSSFCell _cell;
 12    private List<Object> _lis;
 13    private int _index;
 14    private HSSFWorkbook _book;
 15    private VariableDependentManager _VDM;
 16    private List<Object> _sourceLis;
 17
 18    public ExcelContext(HSSFCell cell, List<Object> lis, int index,
 19            HSSFWorkbook book, VariableDependentManager vdm,
 20ExpandedSubBlockStart.gifContractedSubBlock.gif            List<Object> sourceLis) {
 21        this._cell = cell;
 22        this._lis = lis;
 23        this._index = index;
 24        this._book = book;
 25        this._VDM = vdm;
 26        this._sourceLis = sourceLis;
 27    }

 28
 29ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前单元格 */
 30ExpandedSubBlockStart.gifContractedSubBlock.gif    public HSSFCell get_CurrentCell() {
 31        return _cell;
 32    }

 33
 34ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前单元格的Style */
 35ExpandedSubBlockStart.gifContractedSubBlock.gif    public HSSFCellStyle get_CurrentCellStyle() {
 36        return _cell.getCellStyle();
 37    }

 38
 39ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前单元格的数据Type */
 40ExpandedSubBlockStart.gifContractedSubBlock.gif    public int get_CurrentCellType() {
 41
 42        return _cell.getCellType();
 43    }

 44
 45ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前单元格值的索引 */
 46ExpandedSubBlockStart.gifContractedSubBlock.gif    public int get_CurrentCellIndex() {
 47        return _index;
 48    }

 49
 50ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前单元格值的列表 */
 51ExpandedSubBlockStart.gifContractedSubBlock.gif    public List<Object> get_CurrentList() {
 52        return _lis;
 53    }

 54
 55ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前单元格的值 */
 56ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object get_CurrentObject() {
 57        return _lis.get(_index);
 58    }

 59
 60ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前工作集 */
 61ExpandedSubBlockStart.gifContractedSubBlock.gif    public HSSFWorkbook get_Book() {
 62        return _book;
 63    }

 64
 65ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
 66     * 取得一个变量的值
 67     * 
 68     * @throws Exception
 69     */

 70ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object get_Variable(String varName) throws Exception {
 71        return _VDM.getVariable(varName);
 72    }

 73
 74ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//** 取得当前数据源列表 */
 75ExpandedSubBlockStart.gifContractedSubBlock.gif    public List<Object> get_sourceList() {
 76        return _sourceLis;
 77    }

 78
 79ExpandedSubBlockStart.gifContractedSubBlock.gif    protected void applyNewStyle() {
 80        HSSFCellStyle style = _book.createCellStyle();
 81        style.cloneStyleFrom(_cell.getCellStyle());
 82        // clone Font
 83        HSSFFont newFont = _book.createFont();
 84        HSSFFont oldFont = _cell.getCellStyle().getFont(_book);
 85        newFont.setCharSet(oldFont.getCharSet());
 86        newFont.setBoldweight(oldFont.getBoldweight());
 87        newFont.setColor(oldFont.getColor());
 88        newFont.setFontHeight(oldFont.getFontHeight());
 89        newFont.setFontHeightInPoints(oldFont.getFontHeightInPoints());
 90        newFont.setFontName(oldFont.getFontName());
 91        newFont.setItalic(oldFont.getItalic());
 92        newFont.setStrikeout(oldFont.getStrikeout());
 93        newFont.setTypeOffset(oldFont.getTypeOffset());
 94        newFont.setUnderline(oldFont.getUnderline());
 95        style.setFont(newFont);
 96
 97        _cell.setCellStyle(style);
 98    }

 99
100ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
101     * 克隆source(style)的内容至当前单元格的style, 比如一類相同的單元格可以共享一類style而达到提高性能的目的
102     */

103ExpandedSubBlockStart.gifContractedSubBlock.gif    public void cloneStyleFrom(HSSFCellStyle source) {
104        _cell.getCellStyle().cloneStyleFrom(source);
105    }

106}

107

 DefaultCell   包含上下文的被装饰类:

ContractedBlock.gif ExpandedBlockStart.gif Code
 1package lovebaobao.util.template.excel;
 2
 3import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 4
 5ExpandedBlockStart.gifContractedBlock.gif/** *//**
 6 * 一个内置默认的Excel修饰沙粒,上下文的最初包含者,其中style和font不会重新创建独立的对象
 7 * 
 8 * @author zhangmm
 9 * 
10 */

11ExpandedBlockStart.gifContractedBlock.gifpublic class DefaultCell implements IExcelComponent {
12    private ExcelContext _context;
13
14ExpandedSubBlockStart.gifContractedSubBlock.gif    public DefaultCell(ExcelContext context) {
15        _context = context;
16    }

17
18ExpandedSubBlockStart.gifContractedSubBlock.gif    public HSSFCellStyle getStyle() {
19        return _context.get_CurrentCellStyle();
20    }

21
22ExpandedSubBlockStart.gifContractedSubBlock.gif    public int getType() {
23        return _context.get_CurrentCellType();
24    }

25
26ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object getValue() {
27        return _context.get_CurrentObject();
28    }

29
30ExpandedSubBlockStart.gifContractedSubBlock.gif    public ExcelContext getContext() {
31        return _context;
32    }

33
34}

35
两个装饰子类(由使用者自己编程,此处为示例)
 MergeGroupDecorator :
ContractedBlock.gif ExpandedBlockStart.gif Code
 1package lovebaobao.util.template;
 2
 3
 4import java.util.List;
 5
 6import com.bokesoft.himalaya.util.template.excel.CellDecorator;
 7
 8ExpandedBlockStart.gifContractedBlock.gifpublic class MergeGroupDecorator extends CellDecorator {
 9
10    @Override
11ExpandedSubBlockStart.gifContractedSubBlock.gif    public Object getValue() {
12        Object value=super.getValue();
13        int index=this.getContext().get_CurrentCellIndex();
14        List lis=this.getContext().get_CurrentList();
15ExpandedSubBlockStart.gifContractedSubBlock.gif        if(index>=1){
16ExpandedSubBlockStart.gifContractedSubBlock.gif            if(lis.get(index)==null){
17                return value;
18            }

19ExpandedSubBlockStart.gifContractedSubBlock.gif            if(lis.get(index).equals(lis.get(index-1))){
20                value=null;
21            }

22        }

23        return value;
24    }

25
26}

27
 FontColorDecorator :
ContractedBlock.gif ExpandedBlockStart.gif Code
 1package lovebaobao.util.template;
 2
 3import org.apache.poi.hssf.usermodel.HSSFCellStyle;
 4import org.apache.poi.hssf.usermodel.HSSFFont;
 5import org.apache.poi.hssf.util.HSSFColor;
 6
 7import com.bokesoft.himalaya.util.template.excel.CellDecorator;
 8ExpandedBlockStart.gifContractedBlock.gif/** *//**
 9 * 字体颜色——橘黄色
10 * @author zhangmm
11 *
12 */

13ExpandedBlockStart.gifContractedBlock.gifpublic class FontColorDecorator extends CellDecorator {
14
15    @Override
16ExpandedSubBlockStart.gifContractedSubBlock.gif    public HSSFCellStyle getStyle() {
17        HSSFCellStyle style = super.getStyle();
18        HSSFFont font = style.getFont(this.getContext().get_Book());
19        font.setColor(HSSFColor.ORANGE.index); 
20        style.setFont(font);
21        return style;
22    }

23
24}

25
注册所有装饰类
ContractedBlock.gif ExpandedBlockStart.gif Code
 1package lovebaobao.util.template;
 2ExpandedBlockStart.gifContractedBlock.gif/** *//**
 3 * DecoratorUtil
 4 * @author zhangmm
 5 *
 6 */

 7ExpandedBlockStart.gifContractedBlock.gifpublic class DecoratorUtil {
 8ExpandedSubBlockStart.gifContractedSubBlock.gif    /** *//**
 9     * 注册所有必备装饰类
10     * @param template
11     */

12ExpandedSubBlockStart.gifContractedSubBlock.gif    public static void registerAllDecorators(ExcelTemplate template) {
13        template.registerDecorator("EvenHiddenCellDecorator",
14                EvenHiddenCellDecorator.class);
15        template.registerDecorator("MergeGroupDecorator",
16                MergeGroupDecorator.class);
17        template.registerDecorator("ItalicDecorator", ItalicDecorator.class);
18        template.registerDecorator("AlignmentDecorator", AlignmentDecorator.class);
19        template.registerDecorator("FontColorDecorator", FontColorDecorator.class);
20        template.registerDecorator("NormalDecorator", NormalDecorator.class);
21        template.registerDecorator("FillForeGroundColorDecorator"
22                FillForeGroundColorDecorator.class);
23    }

24}

25
注意图Excel模板的A2和D2 单元格包含注释,注释里面有装饰的描述:decorators=ItalicDecorator,FontColorDecorator
根据当前单元格构造上下文:
1 ExcelContext context  =   new  ExcelContext(cellWrite,
2                     (List) cr.result, i, book, vManager, (List) cr.result);
根据上下文和当前单元格的装饰描述去已经注册的装饰字典查找然后实例化
ContractedBlock.gif ExpandedBlockStart.gif Code
 1private IExcelComponent getComponetFormComment(VariableComment vc,
 2ExpandedBlockStart.gifContractedBlock.gif            ExcelContext context) throws Exception {
 3ExpandedSubBlockStart.gifContractedSubBlock.gif        if (vc.cellDecorators.size() == 0{// 当无修饰的时应使用单元格的原来style和font
 4            IExcelComponent iec = new DefaultCell(context);
 5            return iec;
 6ExpandedSubBlockStart.gifContractedSubBlock.gif        }
 else {// 有修饰时,元单元格的style和font都将会作废被新建替代
 7            IExcelComponent iec = new NewCell(context);
 8ExpandedSubBlockStart.gifContractedSubBlock.gif            for (int i = 0; i < vc.cellDecorators.size(); i++{
 9                String className = vc.cellDecorators.get(i);
10                Class dclass = decoratorClass.get(className);
11ExpandedSubBlockStart.gifContractedSubBlock.gif                if (dclass == null{
12                    throw new Exception("未注册" + className + "修饰类(注意逗号是英文格式)");
13                }

14                CellDecorator cd = (CellDecorator) dclass.newInstance();
15                cd.setComponent(iec);
16                iec = cd;
17            }

18            return iec;
19        }

20    }
取出想要的type、value、style
1 IExcelComponent iec  =  getComponetFormComment(vc, context);
2             Object valueTextResult  =  iec.getValue();
3             cellWrite.setCellStyle(iec.getStyle());
4             cellWrite.setCellType(iec.getType());
写单元格。
1 setCellValue(cellWrite, book, valueTextResult, cr.showCellAsError);

  最后想说的是,刚刚插曲最后说我感觉老大的管道方案更好,是因为我发现我现在方案会导致每个单元格都要实例许多装饰对象,而我老大说的管道,只需要几个固定的节点对象可以反复使用。从这点看他的比较好,究其原因是我的装饰本身使用组合,而他的管道仅是保存引用,还有仔细想想管道方案就是装饰模式的一种,如果把上下文看着被装饰对象,管道节点为装饰对象,那么get和set方法实现装饰,接口是仅仅包含get和set上下文的方法,可巧的是他没用对象组合引用上下文而是选择了聚合上下文。

 

LoveBaoBao

作者:LoveBaoBao

出处:http://lovebaobao.cnblogs.com

本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。

转载于:https://www.cnblogs.com/LoveBaoBao/archive/2009/06/12/DesignPattern.html

Busybox for Android v1.20.2 Stable built by Linus Yang [Aug 12, 2012 Update] - Update to 1.20.2 stable [Features] - Tested on Android 2.1, 2.3, 4.0 and 4.1. Should be capable with all Android devices (Use at your own risk) - ELF armv5te binary (statically linked) - More suitable for Android than the prebuilt ARM binaries from busybox.net - IPv6 support, using own DNS resolver, correct user name display and more improvements for Android [Install] wget http://yangapp.googlecode.com/files/busybox-1.20.2 mv busybox-1.20.2 busybox chmod 755 busybox ./busybox --install [INSTALL_DIR] You can build by yourself from my github's project: (forked from tias/android-busybox-ndk) https://github.com/linusyang/android-busybox-ndk [Information] BusyBox v1.20.2-linusyang (2012-08-12 21:41:27 CST) multi-call binary. Copyright (C) 1998-2011 Erik Andersen, Rob Landley, Denys Vlasenko and others. Licensed under GPLv2. See source distribution for full notice. Usage: busybox [function] [arguments]... or: busybox --list[-full] or: busybox --install [-s] [DIR] or: function [arguments]... BusyBox is a multi-call binary that combines many common Unix utilities into a single executable. Most people will create a link to busybox for each function they wish to use and BusyBox will act like whatever it was invoked as. Currently defined functions: [, [[, acpid, adjtimex, ar, arp, arping, ash, awk, base64, basename, bbconfig, beep, blkid, blockdev, bootchartd, brctl, bunzip2, bzcat, bzip2, cal, cat, catv, chat, chattr, chgrp, chmod, chown, chpst, chroot, chrt, chvt, cksum, clear, cmp, comm, cp, cpio, crond, crontab, cttyhack, cut, date, dc, dd, deallocvt, depmod, devmem, df, dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname, dos2unix, dpkg, dpkg-deb, du, dumpkmap, dumpleases, echo, ed, egrep, env, envdir, envuidgid, ether-wake, expand, expr, fakeidentd, false, fbset, fbsplash, fdflush, fdformat, fdisk, fgconsole, fgrep, find, findfs, flash_lock, flash_unlock, flashcp, flock, fold, free, freeramdisk, fsck, fsck.minix, fsync, ftpd, ftpget, ftpput, fuser, getopt, grep, groups, gunzip, gzip, halt, hd, hdparm, head, hexdump, hostname, httpd, hush, hwclock, id, ifconfig, ifdown, ifup, inetd, init, inotifyd, insmod, install, ionice, iostat, ip, ipaddr, ipcalc, ipcrm, ipcs, iplink, iproute, iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd, less, linuxrc, ln, loadkmap, logread, losetup, lpd, lpq, lpr, ls, lsattr, lsmod, lsof, lspci, lsusb, lzcat, lzma, lzop, lzopcat, makedevs, makemime, man, md5sum, mdev, mesg, microcom, mkdir, mkdosfs, mke2fs, mkfifo, mkfs.ext2, mkfs.minix, mkfs.reiser, mkfs.vfat, mknod, mkswap, mktemp, modinfo, modprobe, more, mount, mountpoint, mpstat, mv, nameif, nanddump, nandwrite, nbd-client, nc, netstat, nice, nmeter, nohup, nslookup, od, openvt, patch, pgrep, pidof, ping, ping6, pipe_progress, pivot_root, pkill, pmap, popmaildir, poweroff, powertop, printenv, printf, ps, pscan, pstree, pwd, pwdx, raidautorun, rdate, rdev, readlink, readprofile, realpath, reboot, reformime, renice, reset, resize, rev, rm, rmdir, rmmod, route, rpm, rpm2cpio, rtcwake, run-parts, runsv, runsvdir, rx, script, scriptreplay, sed, sendmail, seq, setconsole, setkeycodes, setlogcons, setserial, setsid, setuidgid, sh, sha1sum, sha256sum, sha512sum, showkey, slattach, sleep, smemcap, softlimit, sort, split, start-stop-daemon, stat, strings, stty, sum, sv, svlogd, swapoff, swapon, switch_root, sync, sysctl, syslogd, tac, tail, tar, tcpsvd, tee, telnet, telnetd, test, tftp, tftpd, time, timeout, top, touch, tr, traceroute, traceroute6, true, tty, ttysize, tunctl, tune2fs, ubiattach, ubidetach, ubimkvol, ubirmvol, ubirsvol, ubiupdatevol, udhcpc, udhcpd, udpsvd, umount, uname, uncompress, unexpand, uniq, unix2dos, unlzma, unlzop, unxz, unzip, uptime, usleep, uudecode, uuencode, vconfig, vi, volname, watch, watchdog, wc, wget, which, whoami, whois, xargs, xz, xzcat, yes, zcat, zcip
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值