Frida是个轻量级别的hook框架,核心是用C编写的,可以将JS注入到目标进程中,在进程中JS可以完全访问内存,挂钩函数,甚至调用进程内的本机函数来执行。

Frida安装

windows安装客户端

安装frida

pip3 install frida

安装frida-tools

pip3 install frida-tools

查看frida版本frida --version

比如14.1.3,下面下载服务端有用到

手机中安装Frida服务端

查看手机cpu

1
2
3
4
5
6
7
8
9
10
11
12
13
14
安装到mumu模拟器
找到mumu安装目录下的MuMu\emulator\nemu\vmonitor\bin目录

1,连接到模拟
adb connect 127.0.0.1:7555

2,查看连接的设备
adb devices

3,进入shell
adb shell

4,查看cpu版本
getprop ro.product.cpu.abi

下载服务端文件:https://github.com/frida/frida/releases

通过Frida的版本及手机CUP网民应该下载:frida-server-14.1.3-android-x86.xz

解压上传到手机里面

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
1、本地文件名修改为frida-serverx86后,上传到手机/data/local/tmp下面
adb push frida-serverx86 /data/local/tmp

2、端口转发
adb forward tcp:27042 tcp:27042
adb forward tcp:27043 tcp:27043

3、进入shell对frida赋权限并启动
root@x86:/ # su
root@x86:/ # cd /data/local/tmp
root@x86:/ # chmod 755 frida-serverx86
root@x86:/ # ./frida-serverx86

4、另起新窗口查看是否成功
frida-ps -U

新建hook脚本test.js

1
2
3
4
5
6
7
8
9
10
setImmediate(function() {
Interceptor.attach(Module.findExportByName("libc.so" , "open"), {
onEnter: function(args) {
console.log("open() called!")
},
onLeave:function(retval){

}
});
});

执行命令

frida -U -f com.android.browser -l test.js --no-pause

参考文献:

此文只是针对Fiddler抓取APP数据失败情况下的方案,主要想解决的是安卓手机APP抓包HTTPS报文通过MITM代理后证书不被信任的问题。网上搜索出这是使用了SSL Pinning技术,网上可以搜索到。

突破SSL pinning的方法最简单的就是使用Xposed+JustTrustMe,为了安全起见最好使用模拟器,比如我用的mumu模拟器。本文假设已经安装好了Fiddler和模拟器,下文主要是Xposed+JustTrustMe的安装及Fiddler配合他们抓APP数据过程。

Xposed安装

Xposed是一款特殊的Android应用,通过替换system\bin\下面的的app_process等文件来控制zygote进程,进而实现控制手机上所有的app进程;缺点就是不能hook应用的so中的函数。

官网地址:https://repo.xposed.info/module/de.robv.android.xposed.installer

打开官网下载页面下载并且安装到模拟器里面,地址如下:

官网地址

下载APK完成后安装到模拟器,,后需要刷入Xposed框架:

安装好的Xposed

安装Xposed框架

进行一段时间的安装后会提示安装成功,如下:

安装成功

注意:如果安装错误

如果安装错误

找到模拟器中的“设置”-“应用兼容”-“关闭”,然后重新安装Xposed框架

JustTrustMe安装

官网地址:https://github.com/Fuzion24/JustTrustMe/releases/tag/v.2

下载JustTrustMe.apk后安装到模拟器,错误提示不用管。然后打开Xposed Installer,在模块里面勾选JustTrustMe。

模块安装

确保Fiddler在模拟器里配置

设置代理

安装证书

然后就可以查看到https的数据请求了。

参考文献:

什么是Consul?

Consul是HashiCorp公司推出的开源工具,Consul由Go语言开发,部署起来非常容易,只需要极少的可执行程序和配置文件,具有绿色、轻量级的特点。Consul分布式的、高可用的、 可横向扩展的用于实现分布式系统的服务发现与配置。

Consul具有哪些特点?

与其他分布式服务注册与发现的方案相比,Consul的方案更“一站式”,内置了服务注册与发现框架、分布一致性协议实现、健康检查、Key/Value存储、多数据中心方案,不再需要依赖其他工具(比如ZooKeeper等),使用起来也较为简单。

  • 服务发现(Service Discovery):Consul提供了通过DNS或者HTTP接口的方式来注册服务和发现服务。一些外部的服务通过Consul很容易的找到它所依赖的服务。
  • 健康检查(Health Checking):Consul的Client可以提供任意数量的健康检查,既可以与给定的服务相关联(“webserver是否返回200 OK”),也可以与本地节点相关联(“内存利用率是否低于90%”)。操作员可以使用这些信息来监视集群的健康状况,服务发现组件可以使用这些信息将流量从不健康的主机路由出去。
  • Key/Value存储:应用程序可以根据自己的需要使用Consul提供的Key/Value存储。 Consul提供了简单易用的HTTP接口,结合其他工具可以实现动态配置、功能标记、领袖选举等等功能。
  • 安全服务通信:Consul可以为服务生成和分发TLS证书,以建立相互的TLS连接。意图可用于定义允许哪些服务通信。服务分割可以很容易地进行管理,其目的是可以实时更改的,而不是使用复杂的网络拓扑和静态防火墙规则。
  • 多数据中心:Consul支持开箱即用的多数据中心. 这意味着用户不需要担心需要建立额外的抽象层让业务扩展到多个区域。

Consul的几个概念

client
client表示consul的client模式,就是客户端模式。是consul节点的一种模式,这种模式下,所有注册到当前节点的服务会被转发到server,本身是不持久化这些信息。

server
server表示consul的server模式,表明这个consul是个server,这种模式下,功能和client都一样,唯一不同的是,它会把所有的信息持久化的本地,这样遇到故障,信息是可以被保留的。

server-leader
中间那个server下面有leader的字眼,表明这个server是它们的老大,它和其它server不一样的一点是,它需要负责同步注册的信息给其它的server,同时也要负责各个节点的健康监测。

其它信息
其它信息包括它们之间的通信方式,还有一些协议信息,算法。它们是用于保证节点之间的数据同步,实时性要求等等一系列集群问题的解决。这些有兴趣的自己看看官方文档。

主要参数说明

-advertise: 通知展现地址用来改变我们给集群中的其他节点展现的地址,默认情况下-bind地址就是展现地址,然而也存在一些路由地址是不能受约束的,这时候会激活一个不同的地址来供应,如果这个地址不能路由,这个路由将不能被加入集群

-bootstrap: 用来控制一个server是否在bootstrap模式,在一个datacenter中只能有一个server处于bootstrap模式,当一个server处于bootstrap模式时,可以自己选举为raft leader,在一个节点的模式下这种方式很重要,否则在集群中的一致性不能保证,不推荐在集群中应用这个标识

-bootstrap-expect: 在一个datacenter中期望提供的server节点数目,当该值提供的时候,consul一直等到达到指定sever数目的时候才会引导整个集群,该标记不能和bootstrap公用(推荐使用的方式)

-bind: 该地址用来在集群内部的通讯,集群内的所有节点到地址都必须是可达的,默认是0.0.0.0,这意味着Consulo会使用第一个可用的私有IP地址,Consul可以使用TCP和UDP并且可以使用共同的端口,如果存在防火墙,这两者协议必须是允许的。

-client: consul绑定在哪个client地址上,这个地址提供HTTP、DNS、RPC等服务,默认是127.0.0.1,只允许回路连接。RPC地址用于Consul命令,比如Consul members可以查询当前运行的Consul代理

-config-file: 明确的指定要加载哪个配置文件,文件下的所有配置会合并在一起进行加载

-config-dir: 配置文件目录,里面所有以.json结尾的文件都会被加载

-data-dir: 提供一个目录用来存放agent的状态,所有的agent允许都需要该目录,该目录必须是稳定的,系统重启后都继续存在

-dc: 该标记控制agent运行的datacenter的名称,默认是dc1

-encrypt: 指定secret key,使consul在通讯时进行加密,key可以通过consul keygen生成,同一个集群中的节点必须使用相同的key

-http-port: HTTP API侦听端口,默认端口8500,可以在环境变量中进行设置,非常有用,可以用于与Consul进行通讯

-join: 加入一个已经启动的agent的ip地址,可以多次指定多个agent的地址。如果consul不能加入任何指定的地址中,则agent会启动失败,默认agent启动时不会加入任何节点。

-retry-join: 和join类似,但是允许你在第一次失败后进行尝试。

-retry-interval: 两次join之间的时间间隔,默认是30s

-retry-max: 尝试重复join的次数,默认是0,也就是无限次尝试

-log-level: consul agent启动后显示的日志信息级别。默认是info,可选:trace、debug、info、warn、err。跟踪 调试 详情 警告 错误,可以通过Consul monitor使用任何级别,也可以通过重启加载新的配置级别

-node: 节点在集群中的名称,在一个集群中必须是唯一的,默认是该节点的主机名(代表一个机器)

-pid-file: 提供一个路径来存放pid文件,可以使用该文件进行SIGINT/SIGHUP(关闭/更新)agent

-protocol: consul使用的协议版本 consul -v

-rejoin: 使consul忽略先前的离开,在再次启动后仍旧尝试加入集群中。

-server: 定义agent运行在server模式还是Client模式,提供时即为Server端,每个集群至少有一个server并且每台机器上不要超过5个dataceter.所有服务器采用一致性算法Raft保证数据一致,确保在故障的情况下的可用性。

-syslog: 开启系统日志功能,只在linux/osx上生效

-ui-dir: 提供存放web ui资源的路径,该目录必须是可读的

5个端口的作用

  • 8300:集群内数据的读写和复制,仅TCP
  • 8301:单个数据中心gossip协议(流言协议)同时使用TCP和UDP通信通讯
  • 8302:跨数据中心gossip协议(流言协议)同时使用TCP和UDP通信通讯
  • 8500:提供获取服务列表、注册服务、注销服务等HTTP接口,提供UI服务,仅TCP
  • 8600:采用DNS协议提供服务发现功能

Consul的反熵

这里首先介绍跟服务和健康检查紧密相关的两个部件:Agent和Catalog。

Agent

Agent存在于Consul的每一个节点中,负责维护注册到其上的服务和健康检查,以及执行这些健康检查,更新本地服务的健康信息。

Catalog

Catalog存在于Server 节点,聚合了各个Agent采集的信息,包括服务、健康检查、相关的节点,以及它们对应的状态,服务发现就是基于Catalog来做的。

然而Catalog中这些信息的字段要比Agent维护的少很多,因为Catelog只是一个视图,它没有关于服务、健康检查和节点的设置项信息。

当服务或健康检查在Agent注册后,信息就会通知到Catalog中;当Agent中根据健康检查的服务状态发生变化时,状态也会通知到Catalog中;当服务或健康检查从Agent中消失后,Catalog中也会移除相对应的信息。Agent负责注册到其上的服务及健康检查,Catalog负责聚合集群各个Agent的数据用于服务发现,Agent同步最新数据到Catalog,各个Agent的数据不断收敛到Catalog,从而实现集群的有序运作

知识点、问题点

  • 服务注册到节点后,其他节点为什么没有同步?

    ​ Consul与ZooKeeper、etcd有区别:ZooKeeper利用临时节点的机制,业务服务启动时创建临时节点,节点在服务就在,节点不存在服务就不存在;etcd利用TTL机制,业务服务启动时创建键值对,定时更新ttl,ttl过期则服务不可用。ZooKeeper和etcd的键值存储都是强一致性的,也就是说键值对会自动同步到多个节点,只要在某个节点上存在就可以认为对应的业务服务是可用的。Consul业务服务的可用状态是由注册到的Agent来维护的,Agent如果不能正常工作了,则无法确定服务的真实状态,并且Consul是相当稳定了,Agent挂掉的情况下大概率服务器的状态也可能是不好的,此时屏蔽掉此节点上的服务是合理的。Consul也确实是这样设计的,DNS接口会自动屏蔽挂掉节点上的服务,HTTP API也认为挂掉节点上的服务不是passing的。

    ​ 鉴于Consul健康检查的这种机制,同时避免单点故障,所有的业务服务应该部署多份,并注册到不同的Consul节点。部署多份可能会给你的设计带来一些挑战,因为调用方同时访问多个服务实例可能会由于会话不共享导致状态不一致,这个有许多成熟的解决方案,可以去查询,这里不做说明。

  • 如果节点挂了健康检查能不能转移到别的节点?

    上边提到健康检查是由服务注册到的Agent来处理的,那么如果这个Agent挂掉了,会不会有别的Agent来接管健康检查呢?答案是否定的。

    从问题产生的原因来看,在应用于生产环境之前,肯定需要对各种场景进行测试,没有问题才会上线,所以显而易见的问题可以屏蔽掉。

    因为分布式系统的状态同步是比较复杂的,同时不要忘了服务部署了多份,挂掉一个不应该影响系统的快速恢复,所以没必要去做这个接管。

  • 能不能直接注册到Server?(是否只有Server节点就够了?)

    首先Server的节点数量不是越多越好,3个或者5个是推荐的数量,数量越多数据同步的处理越慢(强一致性);然后每个节点可以注册的服务数量是有上限的,这个受限于软硬件的处理能力。所以如果你的服务只有10个左右,只有Server问题是不大的,但是这时候有没有必要使用Consul呢?因此正常使用Consul的时候还是要有Client才好,这也符合Consul的反熵设计。

参考文献:

SOA(Service Oriented Architecture)面向服务的架构,探索大概始于 2000 年,概念产生可能更早一些,它是一种架构风格,设计方法,其中包含多个服务, 服务之间通过相互依赖最终提供一系列的功能。一个服务 通常以独立的形式存在与操作系统进程中,各个服务之间 通过网络调用。也是指为了解决在inernet环境下业务集成的需要,通过连接能完成特定任务的独立功能实现的一种软件系统架构

ESB(企业服务总线),指的是传统中间件技术与XML、Web服务等技术结合的产物。是SOA技术架构落地的一个基本部件,现在我们说的SOA集成平台基本都需要有ESB组件,ESB最基本功能即是实现点对点集成到总线式集成的转换,在这个过程中实现了消息协议的转换和适配,数据传输,数据转换和映射,路由等基本功能。ESB提供了网络中最基本的连接中枢,是构筑企业神经系统的必要元素。简单来说ESB就是一根管道,用来连接各个服务节点。为了集成不同系统,不同协议的服务,ESB做了消息的转化解释和路由工作,让不同的服务互联互通。

企业服务总线(EnterpriseServiceBus,ESB)是构建基于面向服务体系结构(SOA)解决方案时所使用基础架构的关键部分,是由中间件技术实现并支持SOA的一组基础架构功能。

WebService是一个平台独立的,低耦合的,自包含的、基于可编程的web的应用程序,可使用开放的XML(标准通用标记语言下的一个子集)标准来描述、发布、发现、协调和配置这些应用程序,用于开发分布式的交互操作的应用程序。它一种分布式部署系统的一种模式,意思就是说分布式的部署系统可以采用WebService技术来写相关的接口。是一种技术方面的标准,真正的跨语言,跨平台,提供了标准的服务定义,服务注册,服务接入和访问的方式。

WebService是SOA的一种实现技术。WebService基于两种协议:soap和rest协议,XML,SOAP和WSDL就是构成WebService平台的三大技术。现阶段,我们能看到的大部分SOA系统好像都是 用WebService实现的。但一定要明确,那些把自己能提供的服务包装一下,对外提供一个ws接口,就声称自己是SOA,肯定是错误的,因为他的系统并不一定符合SOA架构。

有网友这么形容SOA,ESB,WebService的关系

SOA是方法论,就像建筑学一样,指导性质的;
ESB是建筑图纸,理顺整个建筑的架构;
Web S是具体的建筑材料,就好像预制板;

大家知道当初 ERP、CRM、OA 之类的信息系统都是一套套部署起来的,不同系统往往由不同的供应商分别开发的,技术差别也很大,各个系统孤零零的,企业于是有了应用集成和数据集成的需求,SOA 就出来了,各个系统对外提供粗粒度的服务供外部系统访问,所有的服务都集中在一个 ESB 上,曾经 SOA 和 SOA 治理是信息化领域的热门话题,然而这种集成方式开发代价大、通信效率低,且有单点故障的风险, 实际上在企业中并没有得到大规模应用。

微服务,Martin Fowler在2014年正式提出了“微服务”的概念,它出现在互联网相当成熟的时代,将功能分解到离散的各个服务当中,从而降低系统的耦合性,并提供更加灵活的服务支持。微服务架构是一种将单个应用程序作为一套小型服务开发的方法,每种应用程序都在自己的进程中运行,并与轻量级机制(通常是HTTP资源API)进行通信。这些服务是围绕业务功能构建的,可以通过全自动部署机制独立部署。这些服务的集中管理最少,可以用不同的编程语言编写,并使用不同的数据存储技术。

来看下网上找到的对微服务架构的一些定义和阐述:

微服务可以在“自己的程序”中运行,并通过“轻量级设备与HTTP型API进行沟通”。关键在于该服务可以在自己的程序中运行。通过这一点我们就可以将服务公开与微服务架构(在现有系统中分布一个API)区分开来。在服务公开中,许多服务都可以被内部独立进程所限制。如果其中任何一个服务需要增加某种功能,那么就必须缩小进程范围。在微服务架构中,只需要在特定的某种服务中增加所需功能,而不影响整体进程。

微服务不需要像普通服务那样成为一种独立的功能或者独立的资源。定义中称,微服务是需要与业务能力相匹配,这种说法完全正确。不幸的是,仍然意味着,如果能力模型粒度的设计是错误的,那么,我们就必须付出很多代价。如果你阅读了Fowler的整篇文章,你会发现,其中的指导建议是非常实用的。在决定将所有组件组合到一起时,开发人员需要非常确信这些组件都会有所改变,并且规模也会发生变化。服务粒度越粗,就越难以符合规定原则。服务粒度越细,就越能够灵活地降低变化和负载所带来的影响。然而,利弊之间的权衡过程是非常复杂的,我们要在配置和资金模型的基础上考虑到基础设施的成本问题。

参考文献:

FineReport 是一款视觉化的产品输出工具,在我们的产品中最能体现出对整体和局部细节把握的就是我们的配色能力,而好的配色一眼就能看出各位是否具有深厚的设计功底。

作品赏鉴

首先,学习配色前要知道什么是好的配色,什么是坏的配色。

好看的配色
先看一下优秀的作品,让我们来刺激下神经吧。

1594706204834344.gif

1594706329645986.png1594706353502509.png

可以发现,配色真的非常重要,这些设计都是优秀的代名词。

不好看的配色
可以说,没有对比就没有伤害,下面这些是一些反面交材,在此就不做过多解读了,大家自行欣赏吧。

1594706617962945.png1594706650194623.png

1594706680615217.png

最后这张与上面的稍有不同,他的版式设计还是非常不错的,问题恰恰在于配色不当是的整个页面显得不太清爽大气。

因此,这里可以明显的看出来,即使你排版再好,配色出了错也是白搭。

看了以上内容,大家可以思考下,为什么有好有坏,各自缺点优点都在哪里。

色彩基础了解

配色一致都是视觉设计恒久不变的热门话题,是我们输出视觉产物的重要技能之一,通过色彩可以向用户传递不同层次的视觉信息,所以不同的色彩也都被人们赋予了不同的含义,比如:红色、橙色、黄色等暖色系列的颜色能表现出温暖、热闹;而蓝色、淡蓝色等冷色系列颜色,会给人一种凉爽、行冷的感觉。将色彩属性与设计作品有效的相互结合,往往能做到1+1>2的视觉效果。

色彩的特征

在设计中,色彩可以分为两大类,即有彩色和无彩色,无彩色大多指我们常说的黑、白、灰。有彩色则是除无彩色之外的颜色。下面说下有彩色的三大特征,即色相、饱和度、明度:
色相
色彩的首要特征,也就是色彩可呈现出来的质地面貌,比如我们常说的:红色、蓝色、绿色……


饱和度
色彩的鲜艳程度,也就是色彩的纯度,饱和度取决于该色中含色成分和消色成分(灰色)的比例,直观看就是我们常说的:天蓝色、淡蓝色、灰蓝色等等,就是对饱和度不同程度的体现:

(饱和度由高→低的变化)
明度
是眼睛对光源和物体表面的明暗程度的感觉,简单理解就是色彩的明亮程度,比如白天和黑夜:

(明度由亮→暗的变化)

在 Photoshop拾色器中分别对应:

1594707427323306.png

有彩色的三大特征:色相、饱和度、明度,三者相辅相成、共同作用,任何一种有彩色都必然存在着这样的特征关系。相信大家应该能明白三大特征分别代表什么了。

色彩之间的关系

在有彩色范围内,不同色相之间存在着一些可遵循的视觉关系,根据这些视觉关系,我们也能得到一些常见的色彩搭配方式,下面我们具体分析。

同类色
色相环间隔在30°以内的色相搭配,这类配色形式优点:舒服、统一、视觉比较柔和、容易把控。缺点是:冲击性很弱,运用不得当会单调、缺少视觉层次感。所以此类配色方式不易用于对抗、冲击力强的设计作品。

1594707537369729.png

案例展示:

1594707705318469.png

1594707728132529.png

案例中每一幅海报整体给人的视觉感受都很舒服、平缓、易于接受,这也是设计中用到最不容易出错的一种配色方式。

邻近色
色相环相隔90°的颜色称之为邻近色,这类配色方式优点:阳光、活泼、稳定、有一定视觉冲击力、视觉层次感丰富。

1594707764734953.png

案例展示:

1594707818897357.png1594707844631039.png

如图所示,整体视觉层次感丰富、有跳跃性,但同时也很舒服、和谐。

对比色

色相环间隔120°的颜色,这类配色形式优点:视觉冲击力强烈、富有跳跃性、突出、点缀能力强,比如:常用作画面中的点缀色,或与主体固有色成对比关系的背景色,用于突出主体。

缺点:大面积使用比较难把控。

1594707893175044.png

案例展示:

1594708014422867.png1594708040582526.png

如图所示,当对比色的面积较大时,给人的视觉冲击力是很强烈的。而当其中一个色相较少时,点缀、装饰的作用就显现出来,这部分颜色就是画面中容易出彩的部分。

互补色
色相环间隔180°的颜色称之为互补色,色相环上夹角呈现一条直线,互补色的颜色性质相差较大,将这两种颜色相互搭配,就会使这两种颜色都显得更加鲜明,也将视觉冲击力强度提升至峰值!这类配色形式优缺点和对比色很相似。只不过此类视觉冲击力更强也更难把控。

1594708189399731.png

案例展示:

1594708261960944.png1594708290872432.png

1594708306472270.png1594708329769742.png

色彩的色调

色彩是有色调的,色调可以理解为:通过改变明度与饱和度来调配色彩浓淡、强弱程度,叫做色调。简单理解就是决定色调的主要因素是明度和饱和度,而决定作品最终色调的因素是画面中视觉比例较大色彩的属性。那么了解色调对于我们对设计的理解有哪些帮助呢?下面我们列举几个例子:

浅白色调
泛指偏低饱和度、高明度的色相搭配。不同色相之间相互搭配所带来的视觉感受很缓和,即便是以互补色的形式搭配,视觉冲击力也明显减弱。色相固有的视觉属性表现力有所降低,这类色调的设计作品带给用户的视觉感受比较清纯、阳光、年轻、干净、舒服。

1594708450238451.png

案例展示:

1594708498445874.png1594708516996731.png

1594708559307715.png1594708572581681.png

此类色调的作品画面中依然需要重色进行搭配使用的,否则很容易给人一种轻浮、主体不突出的视觉感受。

亮色调

泛指偏高明度、高饱和度的色相搭配,相比而言色相固有视觉属性表现力较强,对比性较强的色相视觉冲击力也很强,这类色调的设计作品带给用户的视觉感受是:活泼、明亮、欲望。

1594708654270616.png

案例展示:

1594709648660571.png1594709669706768.png

如案例中所示,不管是同类色还是互补色的配色方式,都能将色彩本身的视觉属性发挥的淋淋尽致,这也是亮色调作品的一个特点。

暗色调

泛指低明度的配色搭配,相对前两者而言,暗色调给人的视觉感受更稳重、有品质感。

1594709732973065.png

案例展示:

1594709770291132.png1594709784499700.png

1594709802920655.png

当然暗色调还会形成另一种视觉感受,那就是:恐怖、阴森、残忍、尔虞我诈,比如:

1594709841595711.png 1594709859754044.png

暗色调的色相搭配形式,对于很多专题性、故事性、品牌调性强的作品能起到很好的加强、提升的作用。

不管是哪种色调方式,都不是仅限于某一色调范围内的颜色相互搭配,而是在确定主色调后结合其他属性的颜色相互结合使用。在此基础之上同样可以结合色彩搭配关系(同类色、邻近色……)进行配色。

配色技巧

有了这些对色彩的了解后,再去回顾之前的案例,我总结了好的配色在于:色彩精简、颜色温和。

差的配色不如人之处则是:色彩繁多**,滥用渐变。**

所以,把这几点整合在一起配色的要诀就是:精简色彩,少用渐变,色彩温和。

1594710613716328.png

精简色彩

用设计上知名的一句话表述就是:less is more,少即是多。不需要过多华丽的色彩更能体现专业度。

但其中需要注意的是底色、主色和强调色的相互配比,分别为70%、25%和5%,明度上也是由弱到强的关系。

1594710649741550.png

少用渐变

渐变用不好反而添烦恼,如果你非要使用渐变不可,我建议你使用近似色表现,更容易凸显质感而非廉价感。

1594710683307297.png

色彩温和

色彩上过于强烈容易产生视觉疲劳,用温和的颜色更会让人保持阅读欲望。

1594710706181549.png

配色大法好,你来瞧一瞧。

1594710754370271.png

除了了解配色方法以外,还要知道在一张页面上主要是底色+主色+强调色,三者的主要分布。

底色: 背景色/黑色/白色/暗色

主色: 文本的颜色/白色/黑色

强调色: 修饰对比的颜色/亮色近似色/LOGO色

1594712358141387.png

1594712370995770.png

配色工具集合

这里整理了一些常用的配色在线工具,供大家进行实践使用。

懒人专属

人懒点子多,于是有了下面这这样简单直观的配色网站。

ColorDrop
网址:https://colordrop.io/

1594714158218365.png

这纯粹是一个懒人网站。网站提供了437种扁平化的配色方案,对!就是437种!我数过。如果你不怕挑花眼的话通过这个网站你可以轻松的获取你想要的配色的RGB值与HEX(十六进制形式)值。

Color Hunt

网址:http://www.colorhunt.co/

1594714251433071.png

如果你所见,这个网站提供很简单直观的配色方案,这些配色方案并不是一成不变的,也不是由计算机生成的,而是用户不断提交的,网站只是负责展示,你可以对喜欢的配色点赞。很有特点的是网站对这些配色方案进行了一些非常有用的分类。按照最新、最热、最受欢迎、随机。这样你就可以轻松选出时下最流行的配色。

配色表
网址:http://tool.c7sky.com/webcolor/

1594714325893319.png

正如这个网页的名字一样:配色表。这是一个很普通的配色表。这个配色表最大的特色是对颜色按照所给人的印象进行了分类:比如优雅、稳重、自然等。这使得在某些场合下使用这个配色表更加贴切与实用。

复古型

这里列举的都是一些传统色相关的配色网站,对于一些复古的设计更有帮助。

中国传统色
网址:http://zhongguose.com/

1594714451260365.png

这个网站很多人都知道,主要以中国传统色为主。主要提供一些很经典的传统色,比如胭脂色、朱砂色、鸭蛋青等,而且是根据中科院的一些资料制作的,所以这的颜色都是很正点的,用在与古风相关的设计中最合适不过了。

日本传统色
网址:http://nipponcolors.com/

1594714523940302.png

与上面的网站类似,这个网站提供日本传统的颜色。用在一些日系的设计中也是很有感觉的。比起上面的网站,这个网站还提供了随机展示颜色的功能(见上图),每隔一定的时间就会换一种颜色,对于厌烦一个一个查看颜色的人还是有些用的。

渐变型

渐变有时候也是极好的。只要你肯拿来用。

coolHue

网址:https://webkul.github.io/coolhue/

1594714605869584.png

这个渐变色网站是非常轻量的渐变色网站。网站提供了60种常用的渐变色,你不仅可以从网站获取渐变色的值你还能直接获得制作好的渐变色的图片,直接拿来做背景实在是再合适不过了。

itmeo
网址:https://webgradients.com/

1594714927400399.png

这个网站与上面的功能类似,但是却提供了多达180种渐变色配色方案。这个网站同样也是提供渐变值与渐变图片,而且质量比上一个网站要好点,用来作渐变配色再合适不过了。

折腾型

总有动手能力强的喜欢自己亲自去做配色,那这两个工具就适合你。

Color Schema Design
网址:http://www.peise.net/tools/web/

1594715036721479.png

这个网站提供了六种配色模式:单色、互补色、三角形搭配、矩形搭配、类似色搭配、类似色搭配互补色。同时还提供对比度调节,饱和度/明度调节等参数调节,最厉害的是可以直接预览应用配色后的网站的样子,很直观高效。而且网站提供的仪表盘操作也很有专业的感觉。对于哪些有想法,喜欢自己动手实现的童鞋来讲是在合适不过了。

色轮

网址:http://dwz.cn/gome002

1594715227841012.png

这是有Adobe出一款配色工具,提供七种配色规则。虽然界面上操作很简单,但是对于颜色的调节上功能一点都不差。非常靠谱。同时除了支持常见的RGB值、HEX值还支持CMYK值、LAB值、HSB值。可谓非常专业。

取巧型

当然,只要你足够懒,还是有投机取巧的方法的,就比如下面这些。

Colours
网址:http://webcolourdata.com/

1594715328651365.png

如果你想分析一个网站的配色,这个工具就很适合你。你只需要把你想要分析的网站的链接丢进这个网站他便可帮你快速高效的分析出网站的配色方案。而且分析的结果会有三种不同的图示来表示,很靠谱很专业。如果你想模仿一个网站的配色,这个工具是一个不错的选择。

ColorFavs
网址:http://www.colorfavs.com/

1594715425115977.png

同样的一个懒人配色网站,可以通过你上传的图片或者网络的图片来分析图片的配色构成。并且你可以查看别人的分析结果。对于借助图片来配色的情况可谓是很有帮助的,能省下不少的功夫。

原文地址:色彩与配色基础

简介

curl 是常用的命令行工具,用来请求 Web 服务器。它的名字就是客户端(client)的 URL 工具的意思。

它的功能非常强大,命令行参数多达几十种。如果熟练的话,完全可以取代 Postman 这一类的图形界面工具。

本文介绍它的主要命令行参数,作为日常的参考,方便查阅。内容主要翻译自《curl cookbook》。为了节约篇幅,下面的例子不包括运行时的输出,初学者可以先看我以前写的《curl 初学者教程》

不带有任何参数时,curl 就是发出 GET 请求。

$ curl https://www.example.com

上面命令向www.example.com发出 GET 请求,服务器返回的内容会在命令行输出。

-A

-A参数指定客户端的用户代理标头,即User-Agent。curl 的默认用户代理字符串是curl/[version]

$ curl -A 'Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/76.0.3809.100 Safari/537.36' https://google.com

上面命令将User-Agent改成 Chrome 浏览器。

$ curl -A '' https://google.com

上面命令会移除User-Agent标头。

也可以通过-H参数直接指定标头,更改User-Agent

$ curl -H 'User-Agent: php/1.0' https://google.com

-b

-b参数用来向服务器发送 Cookie。

$ curl -b 'foo=bar' https://google.com

上面命令会生成一个标头Cookie: foo=bar,向服务器发送一个名为foo、值为bar的 Cookie。

$ curl -b 'foo1=bar;foo2=bar2' https://google.com

上面命令发送两个 Cookie。

$ curl -b cookies.txt https://www.google.com

上面命令读取本地文件cookies.txt,里面是服务器设置的 Cookie(参见-c参数),将其发送到服务器。

-c

-c参数将服务器设置的 Cookie 写入一个文件。

$ curl -c cookies.txt https://www.google.com

上面命令将服务器的 HTTP 回应所设置 Cookie 写入文本文件cookies.txt

-d

-d参数用于发送 POST 请求的数据体。

$ curl -d'login=emma&password=123'-X POST https://google.com/login
# 或者
$ curl -d 'login=emma'-d 'password=123'-X POST  https://google.com/login

使用-d参数以后,HTTP 请求会自动加上标头Content-Type : application/x-www-form-urlencoded。并且会自动将请求转为 POST 方法,因此可以省略-X POST

-d参数可以读取本地文本文件的数据,向服务器发送。

$ curl -d '@data.txt' https://google.com/login

上面命令读取data.txt文件的内容,作为数据体向服务器发送。

–data-urlencode

--data-urlencode参数等同于-d,发送 POST 请求的数据体,区别在于会自动将发送的数据进行 URL 编码。

$ curl --data-urlencode 'comment=hello world' https://google.com/login

上面代码中,发送的数据hello world之间有一个空格,需要进行 URL 编码。

-e

-e参数用来设置 HTTP 的标头Referer,表示请求的来源。

curl -e '[https://google.com](https://google.com)?q=example' https://www.example.com

上面命令将Referer标头设为https://google.com?q=example

-H参数可以通过直接添加标头Referer,达到同样效果。

curl -H 'Referer: [https://google.com](https://google.com)?q=example' https://www.example.com

-F

-F参数用来向服务器上传二进制文件。

$ curl -F '[file=@photo.png](mailto:file=@photo.png)' https://google.com/profile

上面命令会给 HTTP 请求加上标头Content-Type: multipart/form-data,然后将文件photo.png作为file字段上传。

-F参数可以指定 MIME 类型。

$ curl -F '[file=@photo.png](mailto:file=@photo.png);type=image/png' https://google.com/profile

上面命令指定 MIME 类型为image/png,否则 curl 会把 MIME 类型设为application/octet-stream

-F参数也可以指定文件名。

$ curl -F '[file=@photo.png](mailto:file=@photo.png);filename=me.png' https://google.com/profile

上面命令中,原始文件名为photo.png,但是服务器接收到的文件名为me.png

-G

-G参数用来构造 URL 的查询字符串。

$ curl -G -d 'q=kitties'-d 'count=20' https://google.com/search

上面命令会发出一个 GET 请求,实际请求的 URL 为https://google.com/search?q=kitties&count=20。如果省略--G,会发出一个 POST 请求。

如果数据需要 URL 编码,可以结合--data--urlencode参数。

$ curl -G --data-urlencode 'comment=hello world' https://www.example.com

-H

-H参数添加 HTTP 请求的标头。

$ curl -H 'Accept-Language: en-US' https://google.com

上面命令添加 HTTP 标头Accept-Language: en-US

$ curl -H 'Accept-Language: en-US'-H 'Secret-Message: xyzzy' https://google.com

上面命令添加两个 HTTP 标头。

$ curl -d '{"login": "emma", "pass": "123"}'-H 'Content-Type: application/json' https://google.com/login

上面命令添加 HTTP 请求的标头是Content-Type: application/json,然后用-d参数发送 JSON 数据。

-i

-i参数打印出服务器回应的 HTTP 标头。

$ curl -i https://www.example.com

上面命令收到服务器回应后,先输出服务器回应的标头,然后空一行,再输出网页的源码。

-I

-I参数向服务器发出 HEAD 请求,然会将服务器返回的 HTTP 标头打印出来。

$ curl -I https://www.example.com

上面命令输出服务器对 HEAD 请求的回应。

--head参数等同于-I

$ curl --head https://www.example.com

-k

-k参数指定跳过 SSL 检测。

$ curl -k https://www.example.com

上面命令不会检查服务器的 SSL 证书是否正确。

-L

-L参数会让 HTTP 请求跟随服务器的重定向。curl 默认不跟随重定向。

$ curl -L -d 'tweet=hi' https://api.twitter.com/tweet

–limit-rate

--limit-rate用来限制 HTTP 请求和回应的带宽,模拟慢网速的环境。

$ curl --limit-rate 200k https://google.com

上面命令将带宽限制在每秒 200K 字节。

-o

-o参数将服务器的回应保存成文件,等同于wget命令。

$ curl -o example.html https://www.example.com

上面命令将www.example.com保存成example.html

-O

-O参数将服务器回应保存成文件,并将 URL 的最后部分当作文件名。

$ curl -O https://www.example.com/foo/bar.html

上面命令将服务器回应保存成文件,文件名为bar.html

-s

-s参数将不输出错误和进度信息。

$ curl -s https://www.example.com

上面命令一旦发生错误,不会显示错误信息。不发生错误的话,会正常显示运行结果。

如果想让 curl 不产生任何输出,可以使用下面的命令。

$ curl -s -o /dev/null https://google.com

-S

-S参数指定只输出错误信息,通常与-s一起使用。

$ curl -s -o /dev/null https://google.com

上面命令没有任何输出,除非发生错误。

-u

-u参数用来设置服务器认证的用户名和密码。

$ curl -u 'bob:12345' https://google.com/login

上面命令设置用户名为bob,密码为12345,然后将其转为 HTTP 标头Authorization: Basic Ym9iOjEyMzQ1

curl 能够识别 URL 里面的用户名和密码。

$ curl https://bob:12345@google.com/login

上面命令能够识别 URL 里面的用户名和密码,将其转为上个例子里面的 HTTP 标头。

$ curl -u 'bob' https://google.com/login

上面命令只设置了用户名,执行后,curl 会提示用户输入密码。

-v

-v参数输出通信的整个过程,用于调试。

$ curl -v https://www.example.com

--trace参数也可以用于调试,还会输出原始的二进制数据。

$ curl --trace - https://www.example.com

-x

-x参数指定 HTTP 请求的代理。

$ curl -x socks5://james:[cats@myproxy](mailto:cats@myproxy).com:8080 https://www.example.com

上面命令指定 HTTP 请求通过myproxy.com:8080的 socks5 代理发出。

如果没有指定代理协议,默认为 HTTP。

$ curl -x james:[cats@myproxy](mailto:cats@myproxy).com:8080 https://www.example.com

上面命令中,请求的代理使用 HTTP 协议。

-X

-X参数指定 HTTP 请求的方法。

$ curl -X POST https://www.example.com

上面命令对https://www.example.com发出 POST 请求。

参考链接

(完)

作者: 阮一峰
原文地址:curl 的用法指南

CGI

早期的Web服务器,只能响应浏览器发来的HTTP静态资源的请求,并将存储在服务器中的静态资源返回给浏览器。随着Web技术的发展,逐渐出现了动态技术,但是Web服务器并不能够直接运行动态脚本,为了解决Web服务器与外部应用程序(CGI程序)之间数据互通,于是出现了CGI(Common Gateway Interface)通用网关接口。简单理解,可以认为CGI是Web服务器和运行其上的应用程序进行“交流”的一种约定。

Web系统结构

CGI是Web服务器和一个独立的进程之间的协议,它会把HTTP请求RequestHeader头设置成进程的环境变量,HTTP请求的Body正文设置成进程的标准输入,进程的标准输出设置为HTTP响应Response,包含Header头和Body正文。

CGI

CGI 程序

CGI只是一个接口规范或协议,它的实现则与具体的编程语言相关。在2000年以前,CGI通用网关接口盛行,那个时候,Perl是编写CGI的主流语言,以至于一般的CGI程序都是Perl程序。

CGI程序

通过CGI接口,Web服务器就能够获取客户端传递的数据,并转交给服务器端的CGI程序处理,然后返回结果给客户端。简单来说,CGI实际上是一个接口标准。而通常所说的CGI指代其实是CGI程序,也就是实现了CGI接口标准的程序,只要编程语言具有标准输入、标准输出和环境变量,就可以用来编写CGI程序。

CGI程序通过标准输入(STDIN)和标准输出(STDOUT)进行数据的输入输出,此外CGI程序还通过环境变量来得到输入,操作系统提供了许多环境变量,它们定义了程序的执行环境,应用程序可以存取它们。Web服务器和CGI接口又另外设置了一些环境变量,用来向CGI程序传递一些重要的参数。CGI的GET方法还通过环境变量QUERY_STRING向CGI程序传递Form表单中的数据。

CGI工作概要

对于一个CGI程序,主要的工作是从环境变量和标准输入中读取数据,然后处理数据,最后向标准输出中输出数据。

  • 环境变量

环境变量中存储的叫做Request Meta-Variables,也就是诸如QUERY_STRINGPATH_INFO之类的,这些都是由Web服务器通过环境变量传递给CGI程序的,CGI程序也是从环境变量中读取的。

  • 标准输出

中存放的往往是用户通过PUTSPOST提交的数据,这些数据也是由Web服务器传递过来的。

为了处理动态请求,Web服务器会根据请求的内容,Fork创建一个新进程来运行外部C程序或Perl脚本等,这个进程会把处理完的数据返回给Web服务器,然后Web服务器把内容发送给用户,Fork创建出来的进程也会随之退出。如果下次用户请求为动态脚本,那么Web服务器会再次Fork创建一个新进程,如此周而复始的运行。

CGI

以Nginx接收HTTP请求为例,Nginx接收一个HTTP请求后Fork创建出一个进程,将HTTP请求带来的参数作为输入,执行完程序处理后输出,最终会摧毁这个Fork出来的进程,并将输出返回给客户端。这种方式虽然简单,但是需要不断地Fork进程和销毁进程。

CGI协议

CGI程序的工作原理

Web服务器一般只用来处理静态文件请求,一旦碰到动态脚本请求,Web服务器主进程就会Fork创建出一个新的进程来启动CGI程序,也就是将动态脚本交给CGI程序来处理。启动CGI程序需要一个过程,如读取配置文件、加载扩展等。当CGI程序启动后会去解析动态脚本,然后将结果返回给Web服务器,最后由Web服务器将结果返回给客户端,之前Fork出来的进程也随之关闭。这样,每次用户请求动态脚本,Web服务器都要重新Fork创建一个新进程去启动CGI程序,由CGI程序来处理动态脚本,处理完成后进程随之关闭,其效率是非常低下的。

CGI程序工作原理

PHP-CGI

CGI是一个协议,PHP语言对CGI接口规范的实现也就是PHP-CGI,也就是PHP的解释器。随着技术的发展,PHP-CGI的性能问题逐渐暴露,不是那么尽如人意。PHP在运行的时候是依赖配置文件php.ini的,所以每当PHP-CGI开始工作的时候,它完全是一个新进程,需要重新加载PHP配置文件并初始化,这就造成了很大的资源和时间的浪费。

PHP-CGI

每当客户端请求CGI时,Web服务器就会请求操作系统生成一个新的CGI解释器进程php-cgi.exe,CGI的一个进程处理完一个请求后退出,下一个请求来时在先操作系统申请创建新进程。在访问量较少没有并发的情况下这样做是没有问题的,一旦出现访问量增大,并发出现时这种方式就不再合适了,于是便出现了FastCGI。

Web服务器内置模块

后来出现了一种比较高效的方式:Web服务器内置模块。例如,Apache的mod_php模块,将PHP解释器做成模块加载到Apache服务器中。这样,Apache服务器在启动的时候,就会同时启动PHP模块。当客户端请求PHP文件时,Apache就不用再Fork创建出一个新进程来启动PHP解释器,而是直接将PHP文件交给运行中的PHP模块处理。显然这种方式下,效率会比较高。由于在Apache服务器启动时,才会读取PHP的配置文件,加载PHP模块。在Apache运行过程中,不会在重新读取PHP配置文件。所以,每次修改PHP的配置文件php.ini后,必须重启Apache,新的PHP配置文件才会生效。

FastCGI

FastCGI是Web服务器与处理程序之间通信的一种协议,是CGI的改进版本。由于CGI程序反复加载CGI而造成性能低下,如果CGI程序保持在内存中并接收FastCGI进程管理器调度,则可以提供良好的性能、伸缩性、Fail-Over特性等。

FastCGI就是常驻型的CGI,可以一直运行。在请求到达时不会耗费时间去Fork创建一个进程来处理。FastCGI是语言无关的、可伸缩架构的CGI开放扩展,它将CGI解释器进程保持在内存中,因此获得较高的性能。

FastCGI的工作流程

1.Web服务器启动时载入FastCGI进程管理,如IIS的ISAPI、Apache的Module…

  1. FastCGI进程管理器自身初始化,并启动多个CGI解释器进程php-cgi并等待Web服务器的连接。
  2. 当客户端请求到达Web服务器时,FastCGI进程管理器选择并连接一个CGI解释器,Web服务器将CGI环境变量和标准输入发送到FastCGI子进程PHP-CGI。
  3. FastCGI子进程完成处理后将标准输出和错误信息,从同一连接返回给Web服务器。当FastCGI子进程关闭连接时请求便处理完毕。FastCGI子进程接着等待并处理来自FastCGI进程管理器(运行在Web服务器中)的下一个连接。在CGI模式中,PHP-CGI在此便退出了。

PHP-FPM

FastCGI是一个协议,PHP-FPM实现了这个协议。FastCGI是CGI的改进版,它是一个常驻内存的CGI服务。常用的PHP-FPM就是在这种模式下运行的,PHP-FPM负责Fork多个进程,每个进程都运行着PHP解释器。

PHP-FPM

在Nginx+PHP-FPM的组合中,Nginx负责接收HTTP请求并将请求封装好交给PHP-FPM,PHP-FPM将请求按照一定的规则交给一个子进程去处理,这个子进程中的PHP解释器会加载PHP代码,也是因为这个原因,传统的PHP只能作为Web服务器。我们发现,Nginx+PHP-FPM的组合和Reactor+Worker子进程的组合非常类似。

PHP的解释器PHP-CGI只是一个CGI程序,它本身只能解析请求并返回结果,不会对进程进行管理,所以就出现了一些能够调度PHP-CGI进程的程序。PHP-FPM是PHP对FastCGI的一种具体实现,是fast-cgi进程管理工具。PHP-FPM启动后会创建多个CGI子进程,然后主进程负责管理子进程,同时对外提供一个socket,那么Web服务器当要转发一个动态请求时,只需要按照FastCGI协议要求的格式将数据发往socket即可。PHP-FPM创建的子进程去争夺socket连接,谁抢到谁处理并将结果返回给Web服务器。当其中一个子进程异常退出时,PHP-FPM主进程会去监控,一旦发现CGI子进程就会又启动一个。

CGI、FastCGI、PHP-FPM

Swoole

以Swoole作为HTTP服务器为例,首先Swoole内部实现了HTTP服务器,也就不需要使用Nginx作为HTTP服务器,当然Swoole并不是为了取代Nginx,实际上Swoole当前实现的HTTP的功能非常有限,比如说只支持GET和POST,所以往往Swoole前面还要运行一个Nginx作为前端的代理服务器。

Swoole是常驻内存的,这一点和PHP-FPM不同,PHP-FPM中常驻的是PHP解释器,PHP解释器会重复加载PHP代码并初始化环境。而Swoole只是在启动的时候加载。如此一来性能自然会提高,这一点在开发中体现的比较明显,例如在PHP-FPM下修改PHP代码是会即时生效的,而在Swoole中式需要重启Swoole的服务器才能使代码生效。

原文地址:CGI是什么

Git 版本管理时,往往需要撤销某些操作。

本文介绍几种最主要的情况,给出详细的解释。更多的命令可以参考《常用 Git 命令清单》一文。

一、撤销提交

一种常见的场景是,提交代码以后,你突然意识到这个提交有问题,应该撤销掉,这时执行下面的命令就可以了。

$ git revert HEAD

上面命令的原理是,在当前提交后面,新增一次提交,抵消掉上一次提交导致的所有变化。它不会改变过去的历史,所以是首选方式,没有任何丢失代码的风险。

git revert 命令只能抵消上一个提交,如果想抵消多个提交,必须在命令行依次指定这些提交。比如,抵消前两个提交,要像下面这样写。

$ git revert [倒数第一个提交] [倒数第二个提交]

git revert命令还有两个参数。

  • --no-edit:执行时不打开默认编辑器,直接使用 Git 自动生成的提交信息。
  • --no-commit:只抵消暂存区和工作区的文件变化,不产生新的提交。

二、丢弃提交

如果希望以前的提交在历史中彻底消失,而不是被抵消掉,可以使用git reset命令,丢弃掉某个提交之后的所有提交。

$ git reset [last good SHA]

git reset的原理是,让最新提交的指针回到以前某个时点,该时点之后的提交都从历史中消失。

默认情况下,git reset不改变工作区的文件(但会改变暂存区),--hard参数可以让工作区里面的文件也回到以前的状态。

$ git reset --hard [last good SHA]

执行git reset命令之后,如果想找回那些丢弃掉的提交,可以使用git reflog命令,具体做法参考这里。不过,这种做法有时效性,时间长了可能找不回来。

三、替换上一次提交

提交以后,发现提交信息写错了,这时可以使用git commit命令的--amend参数,可以修改上一次的提交信息。

$ git commit --amend -m "Fixes bug #42"

它的原理是产生一个新的提交对象,替换掉上一次提交产生的提交对象。

这时如果暂存区有发生变化的文件,会一起提交到仓库。所以,--amend不仅可以修改提交信息,还可以整个把上一次提交替换掉。

四、撤销工作区的文件修改

如果工作区的某个文件被改乱了,但还没有提交,可以用git checkout命令找回本次修改之前的文件。

$ git checkout -- [filename]

它的原理是先找暂存区,如果该文件有暂存的版本,则恢复该版本,否则恢复上一次提交的版本。

注意,工作区的文件变化一旦被撤销,就无法找回了。

五、从暂存区撤销文件

如果不小心把一个文件添加到暂存区,可以用下面的命令撤销。

$ git rm --cached [filename]

上面的命令不影响已经提交的内容。

六、撤销当前分支的变化

你在当前分支上做了几次提交,突然发现放错了分支,这几个提交本应该放到另一个分支。

# 新建一个 feature 分支,指向当前最新的提交
# 注意,这时依然停留在当前分支
$ git branch feature

# 切换到这几次提交之前的状态
$ git reset --hard [当前分支此前的最后一次提交]

# 切换到 feature 分支
$ git checkout feature

上面的操作等于是撤销当前分支的变化,将这些变化放到一个新建的分支。

(完)

作者: 阮一峰

转发:如何撤销 Git 操作?

我每天使用 Git ,但是很多命令记不住。

一般来说,日常使用只要记住下图6个命令,就可以了。但是熟练使用,恐怕要记住60~100个命令。

下面是我整理的常用 Git 命令清单。几个专用名词的译名如下。

  • Workspace:工作区
  • Index / Stage:暂存区
  • Repository:仓库区(或本地仓库)
  • Remote:远程仓库

一、新建代码库

# 在当前目录新建一个Git代码库
$ git init

# 新建一个目录,将其初始化为Git代码库
$ git init [project-name]

# 下载一个项目和它的整个代码历史
$ git clone [url]

二、配置

Git的设置文件为.gitconfig,它可以在用户主目录下(全局配置),也可以在项目目录下(项目配置)。

# 显示当前的Git配置
$ git config --list

# 编辑Git配置文件
$ git config -e [--global]

# 设置提交代码时的用户信息
$ git config [--global] user.name "[name]"
$ git config [--global] user.email "[email address]"

三、增加/删除文件

# 添加指定文件到暂存区
$ git add [file1] [file2] ...

# 添加指定目录到暂存区,包括子目录
$ git add [dir]

# 添加当前目录的所有文件到暂存区
$ git add .

# 添加每个变化前,都会要求确认
# 对于同一个文件的多处变化,可以实现分次提交
$ git add -p

# 删除工作区文件,并且将这次删除放入暂存区
$ git rm [file1] [file2] ...

# 停止追踪指定文件,但该文件会保留在工作区
$ git rm --cached [file]

# 改名文件,并且将这个改名放入暂存区
$ git mv [file-original] [file-renamed]

四、代码提交

# 提交暂存区到仓库区
$ git commit -m [message]

# 提交暂存区的指定文件到仓库区
$ git commit [file1] [file2] ... -m [message]

# 提交工作区自上次commit之后的变化,直接到仓库区
$ git commit -a

# 提交时显示所有diff信息
$ git commit -v

# 使用一次新的commit,替代上一次提交
# 如果代码没有任何新变化,则用来改写上一次commit的提交信息
$ git commit --amend -m [message]

# 重做上一次commit,并包括指定文件的新变化
$ git commit --amend [file1] [file2] ...

五、分支

# 列出所有本地分支
$ git branch

# 列出所有远程分支
$ git branch -r

# 列出所有本地分支和远程分支
$ git branch -a

# 新建一个分支,但依然停留在当前分支
$ git branch [branch-name]

# 新建一个分支,并切换到该分支
$ git checkout -b [branch]

# 新建一个分支,指向指定commit
$ git branch [branch] [commit]

# 新建一个分支,与指定的远程分支建立追踪关系
$ git branch --track [branch] [remote-branch]

# 切换到指定分支,并更新工作区
$ git checkout [branch-name]

# 切换到上一个分支
$ git checkout -

# 建立追踪关系,在现有分支与指定的远程分支之间
$ git branch --set-upstream [branch] [remote-branch]

# 合并指定分支到当前分支
$ git merge [branch]

# 选择一个commit,合并进当前分支
$ git cherry-pick [commit]

# 删除分支
$ git branch -d [branch-name]

# 删除远程分支
$ git push origin --delete [branch-name]
$ git branch -dr [remote/branch]

六、标签

# 列出所有tag
$ git tag

# 新建一个tag在当前commit
$ git tag [tag]

# 新建一个tag在指定commit
$ git tag [tag] [commit]

# 删除本地tag
$ git tag -d [tag]

# 删除远程tag
$ git push origin :refs/tags/[tagName]

# 查看tag信息
$ git show [tag]

# 提交指定tag
$ git push [remote] [tag]

# 提交所有tag
$ git push [remote] --tags

# 新建一个分支,指向某个tag
$ git checkout -b [branch] [tag]

七、查看信息

# 显示有变更的文件
$ git status

# 显示当前分支的版本历史
$ git log

# 显示commit历史,以及每次commit发生变更的文件
$ git log --stat

# 搜索提交历史,根据关键词
$ git log -S [keyword]

# 显示某个commit之后的所有变动,每个commit占据一行
$ git log [tag] HEAD --pretty=format:%s

# 显示某个commit之后的所有变动,其"提交说明"必须符合搜索条件
$ git log [tag] HEAD --grep feature

# 显示某个文件的版本历史,包括文件改名
$ git log --follow [file]
$ git whatchanged [file]

# 显示指定文件相关的每一次diff
$ git log -p [file]

# 显示过去5次提交
$ git log -5 --pretty --oneline

# 显示所有提交过的用户,按提交次数排序
$ git shortlog -sn

# 显示指定文件是什么人在什么时间修改过
$ git blame [file]

# 显示暂存区和工作区的差异
$ git diff

# 显示暂存区和上一个commit的差异
$ git diff --cached [file]

# 显示工作区与当前分支最新commit之间的差异
$ git diff HEAD

# 显示两次提交之间的差异
$ git diff [first-branch]...[second-branch]

# 显示今天你写了多少行代码
$ git diff --shortstat "@{0 day ago}"

# 显示某次提交的元数据和内容变化
$ git show [commit]

# 显示某次提交发生变化的文件
$ git show --name-only [commit]

# 显示某次提交时,某个文件的内容
$ git show [commit]:[filename]

# 显示当前分支的最近几次提交
$ git reflog

八、远程同步

# 下载远程仓库的所有变动
$ git fetch [remote]

# 显示所有远程仓库
$ git remote -v

# 显示某个远程仓库的信息
$ git remote show [remote]

# 增加一个新的远程仓库,并命名
$ git remote add [shortname] [url]

# 取回远程仓库的变化,并与本地分支合并
$ git pull [remote] [branch]

# 上传本地指定分支到远程仓库
$ git push [remote] [branch]

# 强行推送当前分支到远程仓库,即使有冲突
$ git push [remote] --force

# 推送所有分支到远程仓库
$ git push [remote] --all

九、撤销

# 恢复暂存区的指定文件到工作区
$ git checkout [file]

# 恢复某个commit的指定文件到暂存区和工作区
$ git checkout [commit] [file]

# 恢复暂存区的所有文件到工作区
$ git checkout .

# 重置暂存区的指定文件,与上一次commit保持一致,但工作区不变
$ git reset [file]

# 重置暂存区与工作区,与上一次commit保持一致
$ git reset --hard

# 重置当前分支的指针为指定commit,同时重置暂存区,但工作区不变
$ git reset [commit]

# 重置当前分支的HEAD为指定commit,同时重置暂存区和工作区,与指定commit一致
$ git reset --hard [commit]

# 重置当前HEAD为指定commit,但保持暂存区和工作区不变
$ git reset --keep [commit]

# 新建一个commit,用来撤销指定commit
# 后者的所有变化都将被前者抵消,并且应用到当前分支
$ git revert [commit]

# 暂时将未提交的变化移除,稍后再移入
$ git stash
$ git stash pop

十、其他

# 生成一个可供发布的压缩包
$ git archive

(完)

作者: 阮一峰

转发:常用 Git 命令清单

crontab:定时任务的守护进程,精确到分,设计秒的我们一般写脚本 –>相当于闹钟

1
2
3
4
日志文件:     ll /var/log/cron*
编辑文件: vim /etc/crontab
进程:ps -ef | grep crond ==> /etc/init.d/crond restart
作用:定时备份,实时备份

常见命令参数

1
2
3
4
5
6
7
8
usage:     crontab [-u user] file
crontab [-u user] [ -e | -l | -r ]
(default operation is replace, per 1003.2)
-e (edit user's crontab)
-l (list user's crontab)
-r (delete user's crontab)
-i (prompt before deleting user's crontab)
-s (selinux context)

定时任务分类

Linux下的任务调度分为两类,系统任务调度和用户任务调度。
系统任务调度:系统周期性所要执行的工作,比如写缓存数据到硬盘、日志清理等。
在/etc/crontab文件,这个就是系统任务调度的配置文件。
用户任务调度:用户定期要执行的工作,比如用户数据备份、定时邮件提醒等。
用户可以使用 crontab 工具来定制自己的计划任务。
在crontab 文件都被保存在/var/spool/cron目录中。其文件名与用户名一致

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
1.系统定时任务:例如清理系统日志,清理系统缓存         -->不过多的关注
查询系统定时处理任务的路径:
路径1:
cd /etc/logrotate.d/-->可以写定时任务
less syslog
路径2:
cat /etc/crontab -->不推荐使用,但是可以看格式
路径3:
ls /etc/ | grep cron*
anacrontab
cron.d -->同路径2 ,可以写定时任务
cron.daily
cron.deny -->控制普通用户使用定时任务crontab
cron.hourly
cron.monthly
crontab
cron.weekly
2.用户的定时任务 -->关注重点

crontab文件内容分析

cat /etc/crontab

image

前四行是用来配置crond任务运行的环境变量

第一行SHELL变量指定了系统要使用哪个shell,这里是bash

第二行PATH变量指定了系统执行命令的路径

第三行MAILTO变量指定了crond的任务执行信息将通过电子邮件发送给root用户

如果MAILTO变量的值为空,则表示不发送任务执行信息给用户

第四行的HOME变量指定了在执行命令或者脚本时使用的主目录。

星号(*):代表所有可能的值,如month字段为星号,则表示在满足其它字段的制约条件后每月都执行该命令操作。

逗号(,):可以用逗号隔开的值指定一个列表范围,例如,“1,2,5,7,8,9”

中杠(-):可以用整数之间的中杠表示一个整数范围,例如“2-6”表示“2,3,4,5,6”

正斜线(/):可以用正斜线指定时间的间隔频率,例如“0-23/2”表示每两小时执行一次。

小 结:
数字的表示最好用2为阿拉伯数字显示
周和日最好不要同时用
定时任务要加注解
可以定向到日志文件或者空文件
定时任务一定是绝对路径,且目录必须存在才能出结果
crontab 服务一定要开启运行

crontab日志路径

1
2
3
4

# 【日志是按照天排列的】
ll /var/log/cron*
/var/log/cron只会记录是否执行了某些计划的脚本,但是具体执行是否正确以及脚本执行过程中的一些信息则linux会每次都发邮件到该用户下。

1
less /var/spool/mail/root

常用的命令展示

安装crontab:

1
yum install crontabs

crontab服务操作说明:

1
2
3
4
/sbin/service crond start //启动服务
/sbin/service crond stop //关闭服务
/sbin/service crond restart //重启服务
/sbin/service crond reload //重新载入配置

查看crontab服务状态:

1
service crond status

手动启动crontab服务:

1
service crond status

查看crontab服务是否已设置为开机启动,执行命令:

1
2
方法一: 界面启动    ntsysv
方法二: 加入开机自动启动: chkconfig –level 35 crond on

crontab -l查看定时任务列表

编辑定时任务

1
2
3
crontab –e

==》vim /var/spool/cron/root

每隔2分钟输出时间到文件

1
*/2 * * * * echo `date` >> $HOME>test.txt

crontab -r 删除定时任务

1
2
3
==> 从/var/spool/cron目录中删除用户的crontab文件
==> 如果不指定用户,则默认删除当前用户的crontab文件
crontab –i 在删除用户的crontab文件时给确认提示

备份crontab文件

1
crontab -l > $HOME``/mycron`

恢复丢失的crontab文件

1
2
如果不小心误删了crontab文件,假设你在自己的$ H O M E目录下还有一个备份,那么可以将其拷贝到/var/spool/cron/<username>,其中<username>是用户名。如果由于权限问题无法完成拷贝,可以用:`</div><div class="line number2 index1 alt1">`crontab <filename> 其中,<filename>是你在$ H O M E目录中副本的文件名。
有些crontab的变体有些怪异,所以在使用crontab命令时要格外小心。如果遗漏了任何选项,crontab可能会打开一个空文件,或者看起来像是个空文件。这时敲delete键退出,不要按<Ctrl-D>,否则你将丢失crontab文件。

每小时执行/etc/cron.hourly目录内的脚本

1
0 * * * * root run-parts /etc/cron.hourly

每隔2分钟同步一次互联网时间

1
echo "*/2 * * * * /usr/bin/ntpstat time.windows.com >/dev/null 2>&1" >> /var/spool/cron/root

每天3-5,17-20每隔30分钟执行一次脚本

1
echo "*/30 [3-5],[17-20] * * * /bin/sh /home/omc/h.sh >/dev/null 2>&1" >> /var/spool/cron/root

当天23点,第二天0点到凌晨7点 每隔1分钟执行一次脚本

1
* 23,00-07/1 * * * /bin/sh /home/omc.h.sh

每年的4月份每周的周一到周三的11点执行脚本

1
00 11 *     4 1-3 /bin/sh /home/omc/h.sh

crontab的注意事项

  1. 注意环境变量问题

在crontab文件中定义多个调度任务时,需要特别注意的一个问题就是环境变量的设置

1
2
3
4
5
6
7
8
9
10
# 脚本中涉及文件路径时写全局路径;
# 脚本执行要用到java或其他环境变量时,通过source命令引入环境变量,如:
cat start_cbp.sh
#!/bin/sh
source /etc/profile
export RUN_CONF=/home/d139/conf/platform/cbp/cbp_jboss.conf
/usr/local/jboss-4.0.5/bin/run.sh -c mev &

# 当手动执行脚本OK,但是crontab死活不执行时。可以尝试在crontab中直接引入环境变量解决问题。
0 * * * * . /etc/profile;/bin/sh /var/www/java/audit_no_count/bin/restart_audit.sh
  1. 系统级任务调度与用户级任务调度
1
root用户的任务调度操作可以通过“crontab –uroot –e”来设置,也可以将调度任务直接写入/etc/crontab文件,需要注意的是,如果要定义一个定时重启系统的任务,就必须将任务放到/etc/crontab文件,即使在root用户下创建一个定时重启系统的任务也是无效的。`

3.其他注意事项

1
2
3
当crontab突然失效时,可以尝试/etc/init.d/crond restart解决问题。或者查看日志看某个job有没有执行/报错tail -f /var/log/cron。
千万别乱运行crontab -r。它从Crontab目录(/var/spool/cron)中删除用户的Crontab文件。删除了该用户的所有crontab都没了。
在crontab中%是有特殊含义的,表示换行的意思。如果要用的话必须进行转义\%,如经常用的date ‘+%Y%m%d’在crontab里是不会执行的,应该换成date ‘+\%Y\%m\%d’
  1. 生产调试定时任务
1
2
3
4
1.增加执行任务的频率调试
2.调整系统时间调试任务,提前5分钟 -->不用于生产环境
3.通过脚本日志输出调试定时 任务
4.注意一些任务命令带来的问题 -->确保命令的正确性

5.crontab箴言

1
2
3
4
5
6
7
8
9
10
11
1.环境变量问题,例如crontab不能识别Java的环境变量
crontab执行shell时,只能识别为数不多的环境变量,普通的环境变量是无法识别的,所以在编写shell时,最好使用export重新声明变量,确保脚本执行。
2.命令的执行最好用脚本
3.脚本权限加/bin/sh,规范路径/server/scripts
4.时间变量用反斜线转义,最好用脚本
5.定时任务添加注释
6.>/dev/null 2>&1 ==>&>/dev/null,别随意打印日志文件
7.定时任务里面的程序脚本尽量用全路径
8.避免不必要的程序以及命令输出
9.定时任务之前添加注释
10.打包到文件目录的上一级

作者:小a玖拾柒

出处:http://www.cnblogs.com/ftl1012/

-------------------------------------------

个性签名: 所有的事情到最後都是好的,如果不好,那說明事情還沒有到最後~

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