日志数据脱敏方法研究

日志文件中的敏感信息比如密码,电话号码等等进行过滤处理。第一个想到的方法就是去 log4j 中自定义 Appender,在 Appender 中正则匹配敏感信息进行过滤。

log4j 日志框架在之前 的文章中也也说过,主要有三个组件,Logger,Appenders 和 Layout,要过滤日志内容解决方法也就是从这三个地方着手。

log 时手动处理

Logger 着手就是在打日志的时候就处理,从根源解决。最精确的处理就是在每个类敏感的字段上手动处理,在打印日志时,封装方法手动转换 String 。这种方法唯一的缺点就是对于一个大型成熟的系统,要修改的日志打印地方太多,更本无法顾及。所以还需要寻找统一的方法。

自定义 Appender

如果从根源上没有解决,接下来就是在 Appender 中,Appender 决定了日志往哪里输出,那么这个时候就可以重写 subAppend 方法重新修改 LogEvent 来修改日志信息,将敏感的内容移除。比如

import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.spi.LoggingEvent;

public class DesensitizeDailyRollingFileAppender extends DailyRollingFileAppender {

    @Override
    protected void subAppend(LoggingEvent event) {
        String message = (String) event.getMessage();
        // do your stuff
        LoggingEvent modifiedEvent = new LoggingEvent(event.getFQNOfLoggerClass(), event.getLogger(), event.getTimeStamp(), event.getLevel(), modifiedMessage,
                event.getThreadName(), event.getThrowableInformation(), event.getNDC(), event.getLocationInformation(),
                event.getProperties());
        super.subAppend(event);
    }
}

扩展 PatternLayout

最后,如果自定义 Appender 的话,那么每一个日志删除的目的 Appender 都要手动实现一下,这个时候如果复写 PatternLayout 就可以让多个 Appender 来使用。

定义自己的 PatternLayout ,然后在配置文件 Appender 指定用我们自己的实现的 PatternLayout。

import java.lang.reflect.Field;
import org.apache.log4j.PatternLayout;
import org.apache.log4j.spi.LoggingEvent;

public class DesensitizeLayout extends PatternLayout {

    @Override
    public String format(LoggingEvent event) {
        if (event.getMessage() != null && event.getMessage() instanceof String) {
            String message = event.getMessage().toString();
            // do your stuff to change message
            try {
                Field msgField = LoggingEvent.class.getDeclaredField("message");
                msgField.setAccessible(true);
                msgField.set(event, message);
            } catch (NoSuchFieldException | IllegalAccessException e) {
                e.printStackTrace();
            }
        }
        return super.format(event);
    }
}

RewritePolicy

如果使用的是 log4j 2.x 版本,也可以使用这种方法重写 RewritePolicy,然后 Override rewrite 方法。

总结

通过自定 Appender 或者 PatternLayout 可以实现敏感信息的脱敏,那么其实扩展可以实现其他的同类业务。比如固定格式输出,比如打印日志到内部日志收集器等等。

reference


2018-12-20 log4j , log , desensitize , 日志 , 脱敏

log4j PatternLayout

log4j 下的 PatternLayout 只是 Layout 的一种,用来格式化日志文件的输出。在 PatternLayout 中,配置一个样板字符串,通过该字符串来定义输出格式。

log4j 还提供了其他三种 Layout

  • org.apache.log4j.HTMLLayout(以 HTML 表格形式布局)
  • org.apache.log4j.SimpleLayout(包含日志信息的级别和信息字符串)
  • org.apache.log4j.TTCCLayout(包含日志产生的时间、线程、类别等等信息)

这个类的目标是格式化 LoggingEvent 输出结果,这个结果依赖 conversion pattern.

conversion pattern 和 C 语言下面的 printf 方法非常类似。conversion patter 由逐字文本和格式化控制表达式(conversion specifiers) 组成。

每一个 conversion specifiers 都由一个 % 开始,紧跟着一个可选的 format modifiers (被称为 conversion character)。conversion character 指定了类型,比如日期,线程名。format modifiers z 则控制字段宽度,padding,左右调整。

比如 %-5p [%t]: %m%n 配置

root.debug("Message 1");
root.warn("Message 2");

则会输出

DEBUG [main]: Message 1
WARN  [main]: Message 2

ConversionPattern 参数的格式含义

格式名 含义

%c 输出日志信息所属的类的全名
%C 调用 logger 的类的全名(包含包路径)
%d 输出日志时间点的日期或时间,默认格式为 ISO8601,也可以在其后指定格式,比如:%d{yyy-MM-dd HH:mm:ss },输出类似:2002-10-18- 22:10:28
%f 输出调用 logger 所属的类的类名
%l 输出日志事件的发生位置,类,线程,代码行数
%L 调用 logger 的代码行
%m 输出代码中指定的信息,如 log(message) 中的 message
%M 调用 logger 的方法名
%n 输出当前平台的换行符,Windows 平台为“\r\n”,Unix 平台为“\n”
%p 输出优先级,即 DEBUG,INFO,WARN,ERROR,FATAL。如果是调用 debug() 输出的,则为 DEBUG,依此类推
%r 输出自应用启动到输出该日志信息所耗费的毫秒数
%t 输出产生该日志事件的线程名

reference


2018-12-19 log4j , java , log

Unix 进程

Unix 内核在硬件之上,与硬件交互,系统文件读写,网络数据发送,内存分配,扬声器播放音频等等。程序不能直接访问内核,通信通过系统调用完成。

系统调用是内核和用户空间交互的桥梁,规定了程序和计算机硬件之间可以发生的交互。

Unix 的系统调用文档已经在系统中,输入 man man 查看。

进程是 Unix 系统基石,所有的代码都在进程中被执行。

进程标示

唯一进程标示 PID,PID 本身没有任何进程信息,只是一个数字。系统中每一个进程都有其父进程,PPID。多数情况下,特定进程的父进程就是调用他的进程。

文件描述符值用来跟踪打开的资源,已经关闭的资源没有文件描述符。

每个 Unix 进程都有三个打开的资源,STDIN,STDOUT,STDERR。

限制打开的资源数量

每个进程打开的资源数量都是限制的,进程资源限制中,分为 soft limit 和 hard limit. soft limit 指的是内核所能支持的资源上限,hard limit 是 soft limit 的上限,当设置 hard limit 之后 soft limit 只能小于 hard limit.

可以使用 ulimit -a 来查看资源限制情况。

进程环境变量

所有进程都从父进程继承环境变量。

C 库函数 setenv()getenv()

进程都有参数

所有进程都可以访问 ARGV 的特殊数组,argv 是 argument vector 缩写,参数向量

进程 fork

forking 是 Unix 编程中最强大的概念,fork 系统调用允许运行中的进程以编程的形式创建新的进程,这个新进程和原始进程一样。

在 forking 时,调用 fork 的进程被称为“父进程”,而新创建的进程被称为“子进程”。

forking 时会创建一样的新进程,所以 fork 尽管很快,但是会有一些问题,比如如果内存占用比较大,fork 多份之后可能内存被撑爆。

现代 Unix 采用写时复制(copy-on-write, CoW) 方法来克服这个问题,将实际内存复制操作推迟到真正写入的时候,父进程和子进程实际共享内存数据,直到其中一个需要对数据进行修改,才复制。

当 fork 多个并发子进程时,进程看管这些子进程,确保能够保持响应,对子进程的退出做出回应。

信号

信号 动作 说明
SIGHUP 1 Exit Hangup
SIGINT 2 Exit Interrupt
SIGQUIT 3 Core Quit
SIGILL 4 Core Illegal Instruction
SIGTRAP 5 Core Trace/Breakpoint Trap
SIGABRT 6 Core Abort
SIGEMT 7 Core Emulation Trap
SIGFPE 8 Core Arithmetic Exception
SIGKILL 9 Exit Killed
SIGBUS 10 Core Bus Error
SIGSEGV 11 Core Segmentation Fault
SIGSYS 12 Core Bad System Call
SIGPIPE 13 Exit Broken Pipe
SIGALRM 14 Exit Alarm Clock
SIGTERM 15 Exit Terminated
SIGUSR1 16 Exit User Signal 1
SIGUSR2 17 Exit User Signal 2
SIGCHLD 18 Ignore Child Status
SIGPWR 19 Ignore Power Fail/Restart
SIGWINCH 20 Ignore Window Size Change
SIGURG 21 Ignore Urgent Socket Condition
SIGPOLL 22 Ignore Socket I/O Possible
SIGSTOP 23 Stop Stopped (signal)
SIGTSTP 24 Stop Stopped (user)
SIGCONT 25 Ignore Continued
SIGTTIN 26 Stop Stopped (tty input)
SIGTTOU 27 Stop Stopped (tty output)
SIGVTALRM 28 Exit Virtual Timer Expired
SIGPROF 29 Exit Profiling Timer Expired
SIGXCPU 30 Core CPU time limit exceeded
SIGXFSZ 31 Core File size limit exceeded
SIGWAITING 32 Ignore All LWPs blocked
SIGLWP 33 Ignore Virtual Interprocessor Interrupt for Threads Library
SIGAIO 34 Ignore Asynchronous I/O

进程可以在任何时候收到信号,常见的用法在 shell 中使用 kill 发送信号。在时间中,信号多由长期运行的进程使用,例如服务器和守护进程。

进程间通信

管道

管道是一个单向数据流,管道也是一种资源,有自己的文件描述符和其他一切,也可以和子进程共享。“流”数据没有开始和结束的概念,需要通过分隔符来确定。

套接字

Unix 套接字是一种只能用于同一台物理主机中进行通信的套接字,比 TCP 套接字快,适合用于 IPC。

管道提供的是单向通信,而套接字提供双向通信。

远程 IPC

如果要从单机扩展到多台机器,可以使用 TCP 套接字,或者 RPC,远程过程调用等来实现。

守护进程

在后台运行,不受终端用户控制。init 进程是所有进程的父进程。

总结

这本书能简单的了解下 Unix 下进程的一些知识,包括系统调用,资源限制,资源竞争,信号,进程通信等等内容,但内容都稍微有点浅,并且作者用了 Ruby,虽然不影响阅读,总有些隔阂。

reference

  • 《理解 Unix 进程》

2018-12-17 unix , linux , process

log4j appender

Appender 表示日志输出的地方,常见的有控制台,文件等等,log4j 自带了一些常用的 Appender。

日志中的 LEVEL 和 threshhold

log4j 框架中有两个概念 logger 和 appender。如果 logger 的最低 level 设置为 warn,这意味着任何日志 level 低于 warn 的日志都会被忽略。

一旦一个消息被 logger 接收,这条消息会被发送给一个或者多个 appenders(to console,to file,to mail server, etc). 每一个 appender 都会定义 threshold。比如可以限制打印到 console 的消息为 error,但是打印到文件的日志接收 warn 及以上。1

ConsoleAppender

可能是最常见的一个 Appender,输出到控制台,ConsoleAppender 将日志事件输出到 System.out 或者 System.err 中。

<appender name="console-appender" class="org.apache.log4j.ConsoleAppender">
  <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern"
      value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
  </layout>
</appender>

AsyncAppender

AsyncAppender 允许用户异步(asynchronously) 地打印日志,AsyncAppender 会收集所有发送到它的事件,并将它们分发到所有附加在它的 appenders 中。可以在 AsyncAppender 上附属多个 appenders。

AsyncAppender 会使用单独的线程来处理它缓冲区中的事件。

Important note: The AsyncAppender can only be script configured using the DOMConfigurator.

FileAppender

将日志 event 输出到文件,直接子类有 DailyRollingFileAppender,和 RollingFileAppender。

可选的 append 配置表示是否在原来的文件内容上追加日志,如果是 false,log4j 会清理文件内容,每次重启程序,原来的日志文件会丢失,默认为 true,日志文件会越来越大。

RollingFileAppender

RollingFileAppender 继承自 FileAppender 用来配置当日志文件到达一定大小则自动备份日志文件到其他地方。

两个参数 maxFileSize 和 maxBackupIndex

<appender name="file" class="org.apache.log4j.RollingFileAppender">
  <param name="append" value="false"/>
  <param name="maxFileSize" value="10KB"/>
  <param name="maxBackupIndex" value="5"/>
  <param name="file" value="/tmp/jutils/jutils.log"/>
  <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern"
      value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
  </layout>
</appender>

DailyRollingFileAppender

DailyRollingFileAppender 继承自 FileAppender,定义的日志文件在用户指定的频率下会定时产生新的日志文件。

日志周期由 DatePattern 选项定义,模式需要遵循 SimpleDateFormat 格式,此处定义的日期格式会作为滚动日志文件的后缀。

举例,如果 File 选项设置为 /foo/bar.log 并且 DatePattern 设置为 “’.’yyyy-MM-dd”,那么在 2001-02-16 的午夜,日志文件 /foo/bar.log 文件会被拷贝到 /foo/ba.log.2001-02-16,然后在 /foo/bar.log 日志文件中会继续记录 2001-02-17 的日志。

<appender name="dailyRolling" class="org.apache.log4j.DailyRollingFileAppender">
  <param name="File"  value="/tmp/jutils/roll_jutils.log"/>
  <param name="DatePattern" value=".yyyyMMdd"/>
  <param name="threshold" value="error"/>
  <layout class="org.apache.log4j.PatternLayout">
    <param name="ConversionPattern" value="%d{ISO8601} %-5p [%t] [%l] - %m%n"/>
  </layout>
</appender>

DailyRollingFileAppender 同样支持指定按照月,星期,半天,天,小时,分钟间隔的分割配置。

DatePattern Rollover schedule Example
’.’yyyy-MM 每月初  
’.’yyyy-ww 每个星期第一天,每星期第一天由地区决定  
’.’yyyy-MM-dd 每天 midnight  
’.’yyyy-MM-dd-a 每天 midnight 和 midday  
’.’yyyy-MM-dd-HH 每个小时  
’.’yyyy-MM-dd-HH-mm 每分钟开始时  

不要在 DatePattern 选项中使用冒号 : .

自定义 Appender

自定义 Appender 以实现在记录日志时将其中部分信息过滤。

import org.apache.log4j.DailyRollingFileAppender;
import org.apache.log4j.spi.LoggingEvent;

public class SensitiveDailyRollingFileAppender extends DailyRollingFileAppender {

    @Override
    protected void subAppend(LoggingEvent event) {
        String message = (String) event.getMessage();
        String modifiedMessage = SensitiveUtils.filterName(message);
        modifiedMessage = SensitiveUtils.filterName(modifiedMessage);
        modifiedMessage = SensitiveUtils.filterIdentityId(modifiedMessage);
        LoggingEvent modifiedEvent = new LoggingEvent(event.getFQNOfLoggerClass(), event.getLogger(), event.getTimeStamp(), event.getLevel(), modifiedMessage,
                event.getThreadName(), event.getThrowableInformation(), event.getNDC(), event.getLocationInformation(),
                event.getProperties());
        super.subAppend(event);
    }
}

如果想要更加基础可以继承 AppenderSkeletion,需要实现三个方法

  • protected void append(LoggingEvent loggingEvent) 打印日志核心方法
  • public void close() 关闭资源
  • public boolean requiresLayout() 是否需要 Layout

复写 append 方法实现自己的内容。

reference

  1. https://stackoverflow.com/a/5120069/1820217 


2018-12-17 log , java , log4j , slf4j

重构读书笔记

重构第一步,构造可靠的测试环境。

What

任何可以立即查阅的东西,都故意不去记忆。

什么是重构

重构,对软件内部结构调整,在不改变外部可观察行为的前提下,提高其可理解性,减低修改成本。

重构难题

对于修改接口,能获取所有调用者,那么可以安心修改。如果无法修改全部调用者,如果是公开已经发布的接口,就需要同时维护新旧两个接口,直到所有用户将该变化做出反应。

How

Duplicated Code

重复代码提炼。兄弟类,则推到 super class,如果是不完全相同的,则分解方法提炼统一的方法。

Long method

小函数准确的命名,积极地分解长函数。每当需要注释来说明,就应该把需要说明的内容写入独立函数,以其用途命名。

Large Class

如果类内部变量有相同的前缀和后缀,可能可以将其提炼到某个组件。

Long Parameter List

参数列表不应该过长,对象传递。

Divergent Change

类在不同方向上发生变化,针对外界发生的变化所有的修改都只发生在单一类中,需要找出特定原因造成的修改,将其提炼到另一个类中。

Shotgun Surgery

每次遇到某种变化,需要在不同的类内部做修改,这时候需要用 Move Method 和 Move Field 将所需要修改的代码放到同一个类中,如果没有合适的类,就创造一个。

Divergent Change 是“一个类受多种变化影响”,Shotgun Surgery 是“一种变化引发多个类修改”。

Feature Envy

面向对象的技术要点在于,这是一种“将数据和对数据的操作行为包装在一起”的技术。函数对某个类的兴趣超过了对自己所处类的兴趣,这种问题的焦点便是数据。比如某个函数为了计算某个值,从另一个对象调用半打取值函数,解法,将这个函数移动到另外的地方。

Data Clumps

数据泥团,数据项成群结队在一起。

Primitive Obsession

对象打破了基本数据和体积较大的类的界限。

Switch Statements

switch 用多态来代替

Parallel Inheritance Hierarchies 平行继承

在为某个类增加子杯,也必须为另一个类增加子类。

Lazy Class


2018-12-16 java , refactor , coding , programming

JProfile 简单使用

在学习 ThreadLocal 的时候有人推荐了 JProfiler ,可以用来对 Java 内存泄露分析,JProfile 其实是一个 Java 的性能分析工具,不仅可以用来排查 OutOfMemoryError 的错误,对于查找系统瓶颈,查看 Java 堆信息等等都有很强大的功能支持。

搜索一番之后发现也有很多 Java Profiler 的工具,JDK 自带也有 Java VisualVM 这样的工具。

JProfiler

JProfiler’s intuitive UI helps you resolve performance bottlenecks, pin down memory leaks and understand threading issues.

安装注册

官网地址:

JProfiler 是商业软件,有 10 天试用期,到期注册码自行解决。

特性

  • profile a demo session and a saved session
  • attach a running jvm
  • profile an application server, locally or remotely
  • open a snapshot, can open HPROF and PHD snapshots

数据采集方式

两种采集方式

  • Sampling 采样,间隔时间将每个线程栈中方法栈中的信息统计出来,对应用影响小,数据统计可能不精确
  • Instrumentation, 在 class 加载之前,JProfier 把相关功能代码写入到需要分析的 class 中,对正在运行的 jvm 有一定影响。

启动方式

  • Attach mode ,将本机正在运行的 jvm 加载 JProfiler Agent
  • Profile at startup,将指定的 JProfiler Agent 手动加载到该 jvm
  • Prepare for profiling
  • Offline profiling

jprofiler

Java VisualVM

reference


2018-12-14 java , jprofiler , visualvm

英语搭配语字典整理

最近用 GoldenDict 查词非常频繁且非常有效的提高了阅读的效率,但是在日常有的时候听一些英语口语的广播节目的时候,经常会有一些短语搭配,而我们平时如果写作的话,其实短语较于单词更为重要,口语亦然。所以产生了一个念头,如果有一本英语搭配语字典就能够提高不少效率,没想到都不用去刻意搜索,就出来了好几个推荐。

  • Oxford Collocation Dictionary 牛津英语搭配语词典
  • The BBI dictionary of English word combinations BBI 英语搭配词典
  • Longman Collocations Dictionary and Thesaurus 朗文搭配
  • Longman Language Activator 朗文英语联想活用词典,更准确来说这一本更像是一部同义词解析词典,但也有涉及短语搭配
  • Oxford Learner’s Thesaurus

比如在查阅 dictionary 时,将查阅字典这一类的词组 look up the dictionary 也能够显示出来。在别人分享的一篇文章中,作者举了一个例子 open up the possibility ,开启了什么的可能性,possibility 这个单词非常常见,但是却少有人意识到它可以和 open up 一起用。搭配字典在英语学习中,尤其是非母语人士的英语写作中起着很大的帮助作用。越普通,越常见的单词就越应该了解其常用的搭配。

牛津英语搭配语词典 Oxford Collocation Dictionary

一种全新的英文词典,提供词于词见常用并且地道搭配用法。可以有效帮组英语学生或成人 学习,写作和说地道的英文。 该词典对准备雅思、托福等英语考试也非常有益。

级别:Upper-Intermediate to Advanced

主要特点:

《牛津英语搭配词典》(英汉双解版)从崭新的角度探究了英语中词与词之间的组合关系,如 ‘bright idea’ or ‘talk freely’。这种组合不是任意的,而是受到语义、语法、语体和文化的制约。只有熟悉和掌握了英语搭配,才能真正做到让英语单词“为我所用”,地道自然地传达思想,与人高效沟通。本词典收录搭配丰富,逾 9,000 个常用英语词条, 达 150,000 个搭配词组;例句真实自然,50,000 条示例全部选自语料库;专辟 25 个不同主题的用法说明,加深对搭配词应用的理解;

oxford collocation

The BBI Dictionary of English Word Combinations

是一本非常轻薄的搭配语字典,词条详细,内容丰富,编排紧凑,同样也带来了一定阅读的不便。

bbi collocations

Longman Collocations Dictionary and Thesaurus

朗文搭配语词典,虽然没有牛津搭配语词典有名,但一样是一本非常地道的搭配语词典,排版甚至较牛津的更加清晰易读。

longman collocations

Longman Language Activator

朗文英语写作活用词典

Oxford Learner’s Thesaurus

更加准确来说这是一本 Thesaurus 词典,也就是同义词词典,会给出查阅单词的相近含义的单词,以便于联想学习。

总结

前三本字典是真正的搭配语词典,有着非常丰富的搭配语用法和解释,所以推荐可以日常对比使用。而后两本更加偏向于同义词活用,有时间再整理一下同义词词典吧。

reference


2018-12-14 english , learning

Using ${a:-b} 来赋值

看一些 shell 脚本的时候发现了如下的写法

VAR1=${VAR1:-VAR2}

这个语句允许当 VAR1 为空时用 VAR2 来赋值。

${parameter:-word}
    If parameter is unset or null, the expansion of word is substituted.
    Otherwise, the value of parameter is substituted.

这个在 Bash 中叫做 parameter expansion ,更多的内容可以参考 Bash Hacker’s Wiki

使用举例

当 variable 不存在时,会默认使用后者

$ echo "$VAR1"

$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
default value

当 variable 存在时,则使用前者

$ VAR1="has value"
$ echo "$VAR1"
has value

$ VAR1="${VAR1:-default value}"
$ echo "$VAR1"
has value

reference


2018-12-14 linux , bash , assignment

Linux 下安装 openssh server

一般服务器中会默认已经安装 SSH server,而个人版本的发行版,比如桌面版的 Ubuntu 或者我用的 Mint 可能默认没有安装,那么就需要自己安装配置。

SSH is program and protocol for securely logging into remote machines across a network. It allows you to run programs, and do a variety of tasks as if you were sitting at the machine. SSH is very similar to telnet except for it is with encryption to protect the transferred information and authentication.

安装

可以通过下面命令查看安装包

    sudo apt search ssh

或者 

    sudo apt search openssh

通过下面命令安装

    sudo apt install openssh-server

配置

    sudo vim /etc/ssh/sshd_config

来修改 ssh 默认的配置,可以通过修改 Port 来指定 ssh 默认监听端口 22

然后使用如下命令重启 ssh 服务

    sudo /etc/init.d/ssh restart

在其他电脑上可以使用 ssh name@address -p port 来连接。

openssh 和 ssh 包的区别

使用 apt search 的时候会发现,有 openssh 和 ssh 两个不同的 package

i A openssh-client                  - secure shell (SSH) client, for secure acce
p   openssh-server                  - secure shell (SSH) server, for secure acce
p   ssh                             - secure shell client and server (metapackag
v   ssh-client                      -                          
v   ssh-server                      -      

openssh 的包中又分为 server 和 client ,对于只需要安装 server 的机器来说只需要安装 server,客户端也单独安装就可以。而如果直接安装 ssh 的话,client 和 server 都会安装。使用 aptitude show ssh  可以查看 package 的具体信息。

reference


2018-12-12 linux , openssh , ssh

每天学习一个命令:gzip 压缩文件

gunzip 是个使用广泛的解压缩程序,它用于解开被 gzip 压缩过的文件,这些压缩文件预设最后的扩展名为”.gz”。 事实上 gunzip 就是 gzip 的硬连接,因此不论是压缩或解压缩,都可通过 gzip 指令单独完成。

命令格式

unzip  [-Z]  [-cflptTuvz[abjnoqsCDKLMUVWX$/:^]]  file[.zip] [file(s) ...]
   [-x xfile(s) ...] [-d exdir]

常用参数:

  • -c 将输出写到标准输出上,并保留原有文件
  • -d 把 .gz 文件解压出来
  • -l 查看当前压缩文件的信息。
  • -r 递归式地查找指定目录并压缩其中的所有文件或者是解压缩
  • -t 测试,检查压缩文件是否完整
  • -num 用指定的数字 num 调整压缩的速度,-1 或 –fast 表示最快压缩方法(低压缩比),-9 或 –best 表示最慢压缩方法(高压缩比)系统缺省值为 6
  • -v 对每一个压缩和解压的文件,显示文件名和压缩比。

使用实例

压缩

gzip file1

压缩直接使用 gzip 加上文件名,还可以指定压缩率默认是 6 ,最高是 9 最低是 1。

解压缩

gzip -dv file.gz

显示压缩包内容

gzip -l file.gz

可以显示压缩之后的大小 解压缩之后的大小 压缩率是多少,大概像下图这样。

compressed       uncompressed         ratio          uncompressed_name
  23124234          110229            60.4%          file.gz

2018-12-11 linux , gzip , tar , command

电子书

最近文章

  • 使用 Huginn 搭建自己的 IFTTT IFTTT, Zapier
  • notion 使用记录 很早就有人推荐 Notion,但是注册了用了一下,本以为就是一个在线的 Google Docs,可昨天在豆瓣看到一篇文章介绍比 Trello 更加智能的代替品,然后一看就是 Notion,于是就再来研究下 Notion。然后发现原来 Notion 可以是 Google Calendar, 可以是 Trello,可以是 Google Docs,可以是 todo list,可以是 Google Excel。甚至可以导入 word,markdown,html,csv。
  • Google Cloud Platform 使用向导 Google Cloud 提供 300 刀的初始优惠,而最近我的 Linode 节点越来越不稳定,时常撞墙,所以不得不再别人强烈推荐下注册了一下 GCP。这里就记录一下遇到的问题,其他具体的细节网上已经够多,就不再赘述。
  • html 转 pdf 命令行工具 wkhtmltopdf 最近因为用 HTML 写了一个文档,当想要输出时保存为 PDF,而 Chrome 自带的打印功能,本来就能够快速的保存为 PDF,但是却保留不了页面中的链接,所以找到了这个 wkhtmltopdf.
  • freemarker Java 模板引擎 FreeMarker is a free Java-based template engine, originally focusing on dynamic web page generation with MVC software architecture. However, it is a general purpose template engine, with no dependency on servlets or HTTP or HTML, and is thus often used for generating source code, configuration files or e-mails. by wikiPedia