Astrisk Blog

iOS Kiwi-BDD安装配置

• iOS

Kiwi和BDD

XCTest是Xcode自带的测试框架(Xcode5时加入的),是基于OCUnit的传统测试框架,在书写性和可读性上都不太好。在测试用例太多的时候,由于各个测试方法是割裂的,想在某个很长的测试文件中找到特定的某个测试并搞明白这个测试是在做什么并不是很容易的事情。所有的测试都是由断言完成的,而很多时候断言的意义并不是特别的明确,对于项目交付或者新的开发人员加入时,往往要花上很大成本来进行理解或者转换。另外,每一个测试的描述都被写在断言之后,夹杂在代码之中,难以寻找。使用XCTest测试另外一个问题是难以进行mock或者stub,而这在测试中是非常重要的一部分。

行为驱动开发(BDD)正是为了解决上述问题而生的,作为第二代敏捷方法,BDD提倡的是通过将测试语句转换为类似自然语言的描述,开发人员可以使用更符合大众语言的习惯来书写测试,这样不论在项目交接/交付,或者之后自己修改时,都可以顺利很多。如果说作为开发者的我们日常工作是写代码,那么BDD其实就是在讲故事。一个典型的BDD的测试用例包活完整的三段式上下文,测试大多可以翻译为Given..When..Then的格式,读起来轻松惬意。BDD在其他语言中也已经有一些框架,包括最早的Java的JBehave和赫赫有名的Ruby的RSpec和Cucumber。Kiwi是objc中BDD框架,同时Kiwi对Mock、Stub和异步的良好支持,使我们可以方便的写出漂亮优美的测试。

CocoaPods

如果已经安装CocoaPods 和 Command Line Tools,可以跳过此步骤。

$ [sudo] gem install cocoapods
$ pod setup

备注:CocoaPods 为Xcode Project 包依赖管理工具。具体资料请参考Cocoapods 官网:https://guides.cocoapods.org/

$: xcode-select install

下载完成后,界面step-by-step安装 备注:Command Line Tools 为Xcode的命令行工具,可以在Command Line Tools上,通过执行命令,可以完成编译、打包、测试、归档等。

DOCKER-DOCKERFILE最佳实践

• DOCKER-HACKATHON

Dockerfile提供简单的语法来构建images,如何编写优雅的Dcokerfile是有技巧的。

使用缓存

Dockerfile里的每条指令都会将结果提交形成新的镜像缓存,下一条指令会基于镜像环境(上一条指令提交的)构建,如果一个镜像存在相同的父镜像和指令(除ADD),Docker将会使用使用镜像缓存,而不是重新执行指令。

为了有效地利用缓存,需要Dockerfile尽可能的保持一致。如作者的Dockerfile前5行如下:

FROM ubuntu
MAINTAINER Michael Crosby <michael@crosbymichael.com>
RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

使用标签

除非是在做试验,否则构建镜像时都应该使用-t选项来指定新镜像的标签。使用标签提高了镜像的可读性,便于镜像的维护管理。

docker build -t="crosbymichael/sentry" .

公开端口

可移植性和可重复性是docker的两个核心概念。镜像可以放在任何主机尽可能多地运行。Dockerfile里可以定义私有端口和共用端口的映射,但是永远不能在Dockerfile里映射共用端口,由于绑定了公共端口,由于公共端口限制在同一时刻只能运行一个镜像。

# bad practices
# private and public mapping
EXPOSE 80:8080

# best practices
# private only
EXPOSE 80

如果镜像使用者需要关注容器私有端口映射哪个或哪些公共端口,可以在运行镜像时,通过-p选项指定,否者Docker会自动分配公共端口。

CMD和ENTRYPOINT语法

CMD和ENTRYPOINT指令都比较简单,但是这里都有个隐藏的坑,如果不注意,很有很能会踩到。这两个指令都有以下两种语法。

CMD /bin/echo
CMD ["/bin/echo"]

ENTRYPOINT /bin/echo
ENTRYPOINT ["/bin/echo"]

但使用数组语法时,命令运行结果跟预期完全一样。如果使用第一种语法,Docker会在命令前面加上/bin/sh -c,如果不了解Docker修改了CMD/ENTRYPOINT命令,可能出现些意想不到的结果,并且难于理解。

使用CMD和ENTRYPOINT时,务必使用数组语法。

CMD和ENTRYPOINT结合更好

docker run 命令中的参数都会传递给ENTRYPOINT指令,而不用担心ENTRYPOINT指令会被覆盖(CMD指令会)。当把ENTRYPOINT和CMD指令结合起来使用,会更好。以下是Rethinkdb的 Dockerfile示例

#Dockerfile for Rethinkdb 
#http://www.rethinkdb.com/

FROM ubuntu

MAINTAINER Michael Crosby <michael@crosbymichael.com>

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

RUN apt-get install -y python-software-properties
RUN add-apt-repository ppa:rethinkdb/ppa
RUN apt-get update
RUN apt-get install -y rethinkdb

#Rethinkdb process
EXPOSE 28015
#Rethinkdb admin console
EXPOSE 8080

#Create the /rethinkdb_data dir structure
RUN /usr/bin/rethinkdb create

ENTRYPOINT ["/usr/bin/rethinkdb"]

CMD ["--help"]

在以上的示例中,把ENTRYPOINT和CMD结合使用,在docker run过程中传递的参数将被当作参数传递给ENTRYPOINT(“/usr/bin/rethinkdb”)。 同时还设置了默认的CMD参数–help。这样当运行docker run时,如果没有传递参数,将把CMD[”–help”]参数传递给ENTRYPOINT,给用户显示默认的帮助文档。

docker run crosbymichael/rethinkdb
Running 'rethinkdb' will create a new data directory or use an existing one,
  and serve as a RethinkDB cluster node.
File path options:
  -d [ --directory ] path           specify directory to store data and metadata
  --io-threads n                    how many simultaneous I/O operations can happen
                                    at the same time

Machine name options:
  -n [ --machine-name ] arg         the name for this machine (as will appear in
                                    the metadata).  If not specified, it will be
                                    randomly chosen from a short list of names.

Network options:
  --bind {all | addr}               add the address of a local interface to listen
                                    on when accepting connections; loopback
                                    addresses are enabled by default
  --cluster-port port               port for receiving connections from other nodes
  --driver-port port                port for rethinkdb protocol client drivers
  -o [ --port-offset ] offset       all ports used locally will have this value
                                    added
  -j [ --join ] host:port           host and port of a rethinkdb node to connect to
  .................
  
docker run crosbymichael/rethinkdb --bind all
info: Running rethinkdb 1.7.1-0ubuntu1~precise (GCC 4.6.3)...
info: Running on Linux 3.2.0-45-virtual x86_64
info: Loading data from directory /rethinkdb_data
warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.
warn: Could not turn off filesystem caching for database file: "/rethinkdb_data/auth_metadata" (Is the file located on a filesystem that doesn't support direct I/O (e.g. some encrypted or journaled file systems)?) This can cause performance problems.
info: Listening for intracluster connections on port 29015
info: Listening for client driver connections on port 28015
info: Listening for administrative HTTP connections on port 8080
info: Listening on addresses: 127.0.0.1, 172.16.42.13
info: Server ready
info: Someone asked for the nonwhitelisted file /js/handlebars.runtime-1.0.0.beta.6.js, if this should be accessible add it to the whitelist.

UNITTEST-VS+NUNIT+DOTCOVER搭建UNITTEST环境

• UNITTESTS

工具安装

Visual Studio中执行Nuint用例,需要安装NUnit Test Adapter或dotCover(推荐使用)

新建单元测试项目

编写单元测试类和方法

执行、Debug、生成覆盖率

测试结果和代码覆盖率

iOS-AutoTest-XCTool安装使用

• iOS

HomeBrew

Homebrew作为OS X上强大的包管理器,为系统软件提供了非常方便的安装方式,独特式的解决了包的依赖问题,一键式编译,无参数困扰。Homebrew依赖于XCode,首先需要安装Xcode。同时Homebrew也依赖ruby,Mac已经自带ruby。

#安装Homebrew:
$:ruby -e "$(curl –fsSL https://raw.githubusercontent.com/Homebrew/install/master/install)"

#查看brew的帮助
$:brew help

#安装软件(git)
$:brew install git

#卸载软件(git)
$:brew uninstall git

#搜索软件(git)
$:brew search git

#显示已经安装软件列表
$:brew list

#更新软件,把所有的Formula目录更新,并且会对本机已经安装并有更新的软件用*标明。
$:brew update

#更新某具体软件(git)
$:brew upgrade git

#查看软件信息
$:brew [info | home] [FORMULA...]
#删除程序,和upgrade一样,单个软件删除和所有程序老版删除。
$:brew cleanup git
$:brew cleanup
#查看那些已安装的程序需要更新
$:brew outdated

程序安装路径及文件夹 Homebrew将本地的/usr/local初始化为git的工作树,并将目录所有者变更为当前所操作的用户,以后的操作将不需要sudo。

-bin 用于存放所安装程序的启动链接(相当于快捷方式) -Cellar 所以brew安装的程序,都将以[程序名/版本号]存放于本目录下 -etc brew安装程序的配置文件默认存放路径 -Library Homebrew 系统自身文件夹 +–Formula 程序的下载路径和编译参数及安装路径等配置文件存放地 +–Homebrew brew程序自身命令集

XCTool

XCTool是facebook开源的一个命令行工具,用来替代苹果的xcodebuild。主要有以下功能:

Xctool 安装,最简单的办法是在终端中通过homebrew安装xctool

$:brew update
$:brew install xctool

#检查安装是否成功
$:xctool version (终端显示xctool的版本)

Xctool 使用

在终端中进入项目目录,执行相应命令:

$: xctool [BASE OPTIONS] [ACTION [ACTION ARGUMENTS]] ...

ACTION:
    xctool [BASE OPTIONS] clean
    xctool [BASE OPTIONS] build
    xctool [BASE OPTIONS] build-tests [-only TARGET] [-skip-deps]
    xctool [BASE OPTIONS] run-tests [-test-sdk SDK] [-only SPEC] [-freshSimulator] [-freshInstall]
    xctool [BASE OPTIONS] test [-test-sdk SDK] [-only SPEC] [-skip-deps] [-freshSimulator] [-freshInstall]
    xctool [BASE OPTIONS] archive
Base Options:
    -help                    show help
    -workspace PATH          path to workspace
    -project PATH            path to project
    -scheme NAME             scheme to use for building or testing
    -find-target TARGET      Search for the workspace/project/scheme to build the target
    -find-target-path PATH   Path to search for -find-target.
    -find-target-exclude-pathColon-separated list of paths to exclude for -find-target.
    -sdk VERSION             sdk to use for building (e.g. 6.0, 6.1)
    -configuration NAME      configuration to use (e.g. Debug, Release)
    -jobs NUMBER             number of concurrent build operations to run
    -arch ARCH               arch to build for (e.g. i386, armv7)
    -toolchain PATH          path to toolchain
    -xcconfig PATH           path to an xcconfig
    -reporter TYPE[:FILE]    add reporter
    -showBuildSettings       display a list of build settings and values
    -version                 print version and exit
    SETTING=VALUE            Set the build 'setting' to 'value'
Options for 'build-tests' action:
    -only TARGET             build only a specific test TARGET
    -skip-deps               Only build the target, not its dependencies
Options for 'run-tests' action:
    -test-sdk SDK            SDK to test with
    -only SPEC               SPEC is TARGET[:Class/case[,Class2/case2]]
    -freshSimulator          Start fresh simulator for each application test target
    -freshInstall            Use clean install of TEST_HOST for every app test run
Options for 'test' action:
    -test-sdk SDK            SDK to test with
    -only SPEC               SPEC is TARGET[:Class/case[,Class2/case2]]
    -skip-deps               Only build the target, not its dependencies
    -freshSimulator          Start fresh simulator for each application test target
    -freshInstall            Use clean install of TEST_HOST for every app test run
$ xctool 
  -workspace YourWorkspace.xcworkspace 
  -scheme YourScheme 
   archive
build

iOS-AutoTest-Xcodebuild

• iOS

简介

Apple的命令行工具,可以通过命令行方式来编译、打包、执行测试。Xcodebuild 可以编译project中的一或多target。Xcodebuild 也支持编译指定workspace或project中scheme。

安装

$: xcode-select install

JAVASCRIPT AUTO TEST-JASMINE

• JAVASCRIPT

简介

Jasmine是一款针对javaScript代码的单元测试框架。它不依赖于其他框架;不依赖于DOM; BDD式语法,方便书写测试代码。

第一个简单的测试:

describe("A suite", function() {
  it("contains spec with an expectation", function() {
    expect(true).toBe(true);
  });
});

Unit、Jasmine基本概念对应关系

匹配函数: to*(arg)**

describe("Asynchronous specs", function() {
  var value;
beforeEach(function(done) {
    setTimeout(function() {
      value = 0;
      done();
    }, 1);
  });
it("should support async execution of test preparation and expectations", function(done) {
    value++;
    expect(value).toBeGreaterThan(0);
    done();
  });

info

JAVASCRIPT AUTO TEST-KARMA

• JAVASCRIPT

Introduction

Karma 是Google 开源的一个基于Node.js 的 JavaScript 测试执行过程管理工具(Test Runner)。 Karma 可以在不同的桌面或移动设备浏览器上,或在持续集成的服务器上测试 JavaScript 代码。Karma 支持 Chrome、ChromeCanary、 Safari、Firefox、 IE、Opera、 PhantomJS,知道如何捕获浏览器正使用的默认路径,这些路径可能在启动器配置文件被忽视(overridden)。Karma 就是一个可以和多重测试框架协作的测试执行过程管理工具,它有针对Jasmine、 Mocha 和AngularJS 的适配器,它也可以与 Jenkins 或 Travis 整合,用于执行持续集成测试。

DOCKER-Dockerfile详解(二)

• DOCKER-HACKATHON

在上一篇blog中,介绍了Dockerfile的用法等基础知识,这篇blog来详细看看Dockerfile中的指令。

FROM

FROM为Dockerfile中的第一条指令,是用来设置base image,Dockerfile定义的所有指令将基于FROM指定的base image进行构建。

语法

FROM <image>
FROM <image:tag>
FROM <image>@<digest>

备注:

RUN

RUN指令定义的命令会在image构建的过程中执行。RUN指令会在当前image的基础上新建一层执行命令,并提交结果,形成一个缓存层。同时该缓存层会被下一步的Dockerfile指令使用。

语法

RUN指令有两种格式,如下:

RUN <command>
RUN ["executable","param1","param2"]

Note: 如果不想使用’/bin/sh’,而其他指定shell,例如’/bin/bash’,可以使用数组格式的RUN命令。 RUN[“/bin/bash”,”-c”,”echo hello”]

Note:数组格式的RUN指令会被解析成JSON数组,所以在数组里面只能使用双引号(“”),而不能使用单引号(‘’)。

Note:在JSON数组里面转义字符是必须的,比如以下指令解析时会报语法错误,RUN[“c:\windows\system32\tasklist.exe”],

正确写法,应该是RUN [“c:\windows\system32\tasklist.exe”]

CMD

CMD指令跟RUN指令很相似,只不过RUN是在image被构建时执行并提交结果,而CMD指令是container启动时执行。如果在Dockerfile中定义多条CMD指令,只有最后一条CMD指令被运行。

CMD指令的语法,跟RUN指令一样

FROM ubuntu
CMD ["/usr/bin/wc","--help"]

备注:在运行container可以run后指定参数来覆盖默认的CMD指令;如果不希望被覆盖,可以把ENTRYPOINT和CMD指令结合使用。(ENTRYPOINT指令也是可以使用特定项来覆盖)

LABEL

LABEL指令是一个key-value对,LABEL指令会给image增加元数据。如果base image已经存在相同的LABEL,新的LABEL值会覆盖原有的值。

可以使用docker inspect命令来查看image的所有labels。

语法

LABEL <key>=<value> <key>=<value> <key>=<value> ...

示例

LABEL "com.example.vendor"="ACME Incorporated"
LABEL com.example.label-with-value="foo"
LABEL version="1.0"
LABEL description="This text illustrates \

that label-values can span multiple lines."

EXPOSE

EXPOSE指令通知Docker在container在运行时,监听指定的端口。仅定义EXPOSE指令并不会使特定端口暴露给主机。在docker run可以使用-p选项把EXPOSE监听的所有端口暴露给主机,可以-p 后指定暴露的端口。

语法

EXPOSE <port> [<port>...]

示例

# PORT
EXPOSE 8080
EXPOSE 22
EXPOSE 8009
EXPOSE 8005
EXPOSE 8443

ENV

ENV指令定义和设置变量,这些变量可以在Dockerfile的后续命令中使用。使用ENV定义的环境变量会被持久化下来,同时可以使用docker run –env =进行重新赋值。

语法

ENV <key> <value>
ENV <key>=<value> ...

示例

ENV myName="John Doe" myDog=Rex\ The\ Dog \
    myCat=fluffy

ENV myName John Doe
ENV myDog Rex The Dog
ENV myCat fluffy

ARG

ARG指令定义变量,在使用docker build时可以通过–build-arg = 标识对ARG变量进行赋值。比如在编写nodejs基础镜像的Dockerfile时,就可以把VERSION定义成ARG,在docker build时指定具体要构建的nodejs版本。

示例

FROM resin/rpi-raspbian
ARG NODE_VER
ADD ./${NODE_VER:-node-v5.9.1-linux-armv7l} /
RUN ln -s /${NODE_VER} /node
ENV PATH=/node/bin:$PATH
CMD ["node"]

在Dockerfile中指定了一个默认值,如果构建image未指定NODE_VER,就使用默认值。同时也可以在构建image时指定NODE_VER值,如下:

docker build --build-arg NODE_VER=node-v5.9.0-linux-armv7l .

ADD

ADD指令把文件,目录(可以是URL指定的网络上的目录,文件)拷贝到image文件系统的目标位置上。

备注:

COPY

COPY指令跟ADD指令相似,跟ADD不同的是,COPY仅支持本地文件的拷贝,不支持URL和解压。

VOLUME

VOLUME指令在container中创建一个挂载点,用来挂载主机或其他container的文件系统。

语法

VOLUME ["/data"]

示例

FROM ubuntu
RUN mkdir /myvol
RUN echo "hello world" > /myvol/greeting
VOLUME /myvol

在docker run 时可以把本地的donwload目录挂载到

docker run -it -v /home/Downloads:/myvol ubuntu64 /bin/bash
docker run -it -v /home/Downloads:/myvol:ro ubuntu64 /bin/bash

备注:

USER

USER指令用来指定运行Dockerfile定义的RUN,CMD,ENTRYPOINT指令定义命令的用户,可以使用用户名或UID。当服务不需要管理员权限时,可以通过该命令指定运行用户。并且可以在之前创建所需要的用户,例如: RUN groupadd -r postgres && useradd -r -g postgres postgres 。要临时获取管理员权限可以使用 gosu ,而不推荐 sudo

示例

USER apache

WORKDIR

WORKDIR指令用来设置运行RUN,CMD,ENTRYPOINT指令时所在的工作目录。如果WORKDIR设置的目录不存在,则会创建。WORKDIR指令在Dockerfile中可以多次设置。如果WORKDIR设置时使用的是相对路径,新的路径是相对于上一条WORKDIR指令设置的路径。

示例

WORKDIR /usr/local/sonarqube

ENTRYPOINT

ENTRYPOINT指令跟CMD指令很相似,都可以用来配置container启动后运行命令。不过这两个指令还是有些区别:

示例

# Dockerfile for Rethinkdb 
# http://www.rethinkdb.com/

FROM ubuntu

MAINTAINER Michael Crosby <michael@crosbymichael.com>

RUN echo "deb http://archive.ubuntu.com/ubuntu precise main universe" > /etc/apt/sources.list
RUN apt-get update
RUN apt-get upgrade -y

RUN apt-get install -y python-software-properties
RUN add-apt-repository ppa:rethinkdb/ppa
RUN apt-get update
RUN apt-get install -y rethinkdb

# Rethinkdb process
EXPOSE 28015
# Rethinkdb admin console
EXPOSE 8080

# Create the /rethinkdb_data dir structure
RUN /usr/bin/rethinkdb create

ENTRYPOINT ["/usr/bin/rethinkdb"]

CMD ["--help"]

DOCKER-Dockerfile详解(一)

• DOCKER-HACKATHON

构建docker image有两种方式:

  1. 用交互方式进入container,执行各自操作(更新,安装应用包,启动应用程序等)后,用exit退container,最后使用docker commit提交,生成目标docker image;

  2. 使用Dockerfile,通过在Dockerfile定义各种指令,然后通过docker build来构建docker image。

这两种方式本质上都是一样的,即在在base container中添加(更新)各种应用程序或脚本等操作,生成一个新的docker container,最后利用docker commit把docker container变成docker image。不过利用Dockerfile有利于管理维护和共享,所以基本上我们都使用Dockerfile来构建docker image。下面让我们来详细了解Dockerfile。

Usage

docker build根据Dockerfile和context构建docker image。build context是位于本地或网络上的文件,可以通过PATH或URL来指定context,PATH为本地文件系统的目录,URL为git repo位置。

context是以递归的方式处理的,所以如果指本地目录PATH,则会包含所有的子目录;同理,URL会包含所有git repo的子模块。

镜像的构建是在Docker daemon上执行,而不是通过CLI。构建的第一个阶段就是把完整的context(递归)发送给docker daemon。在大多数情况下,做好新建一个空目录做为context,把Dockerfile和仅构建所需的文件添加到构建目录中。

$ docker build  .

可以通过-f选项指定Dockerfile文件位置,-t选项指定repo和tag

$ docker build  -f /path/to/Dockerfile
$ docker build -t shykes/myapp .

Docker daemon从上而下一条条运行Dockerfile中的指令,如果指令运行成功,Docker daemon会提交构建结果,生成缓存。如果所有指令都运行成功,在构建结束前会生成一个最终的docker image,并输出相应的docker image id。同时Docker daemon会自动清理构建中使用的context。

每条指令都是独立运行(如果运行成功),会生成一个缓存的镜像。为了加速构建,docker会尽可能利用缓存的镜像。

Format

Dockerfile的格式如下:

# comment INSTRUCTION arguments

Dockerfile指令不是大小写敏感,但是约定指令是建议大写。第一条指令必须是以FROM 开头指定一个基础镜像,如下:

FROM ubuntu

ENTRYPOINT [“top”, “-b”]

CMD [“-c”]

Parser directives

Parser directive,即解析器指令,为可选项。解析器指令在构建过程中不会生成缓存层,也不会作为构建步骤在构建过程中显示。解析器指令作为一种特殊的注释。单个解析器指令只能被使用一次。

以下是支持的解析器指令

escape

escape指令是用来设置Dockerfile中的转移字符。如果没有设置,则使用默认的,默认的转移字符为 .

在window环境中,以下Dockerfile在构建时会出现问题。

FROM microsoft/nanoserver

COPY testfile.txt c:\

RUN dir c:\

使用escape指令把转移符设置成 ` ,可以解决以上问题,Dockerfile内容如下

# escape=`

FROM microsoft/nanoserver

COPY testfile.txt c:\

RUN dir c:\

Environment replacement

在Dockerfile中可以定义和使用环境变量。在Dockerfile中,环境变量可以使用$var和${var}两种方式表示,其中${var}主要用在不带空格的变量名上,如${var}_bar.

${var}语法还支持标准bash修饰语,如下

在Dockerfile中,支持环境变量的指令如下

.dockerignore

docker CLI把context发送给Docker daemon之前,会在根目录查找.dockerignore文件,并根据.dockerignore文件中定义的模式过滤排除匹配到的文件或目录。这个跟 .gitignore功能类似。这样可以避免使用ADD或COPY指令时,把大型或敏感的文件发送给Docker daemon。

.dockerignore以换行作为模式的分隔符,每行表示一种匹配模式,模式类似于Unix shell 的file globs。 如果.dockerignore文件中的一行,第一列是以#号开头,则这一行会被认为是注释,在CLI解析前,该行会被忽略。

如果需要排除例外,可以用!标识,例如!README.md,这样README.md文件会被包含在context中。

dockerignore示例

Rule Behavior
#comment Ignored
*/temp* 匹配所有目录下,以temp为前缀的目录或文件;如/somedir/temporary.txt;/somedir/tmp
*/*/temp* 匹配所有以根目录以下2级的以temp为前缀的目录和所有子目录下以temp为前缀的文件;例如:/somedir/subdir/temporary.txt
temp? 匹配根目录下,长度为5个字符,前缀为temp的目录和文件;例如/tempb,/tempb
!file !表示排除例外.例如!README.md把README.md文件排除(即不会被过滤)

VIM-全选删除

• VIM

VIM 全选删除快捷键

有时候需要全选,然后删除。在vim中使用快捷键能够很方便地执行。