在 Ubuntu 下明明非常好用的 sudo snap install electronic-wechat
到了 Mint 下竟然就不管用了,出现了如下错误
cannot perform readlinkat() on the mount namespace file descriptor of the init process: Permission denied
无奈只能寻求另外的方法,手动编译安装果然可以。看 electronic-wechat
的 GitHub 代码知道该项目使用 electron。
安装 nodejs ,然后安装
git clone https://github.com/geeeeeeeeek/electronic-wechat.git
npm install
npm run build:linux
然后在桌面上右击创建一个图标,名字,执行路径都填写清楚,然后就可以快速启动 electronic wechat 了。
在之前的文章 Android 抓包 中介绍过 Mac 下 Charles 进行客户端的抓包,那篇文章中最后介绍其他工具的时候提到了 mitmproxy 这样一款命令行工具,最近使用来看,也是非常强大的工具。这里就简单记录一下。
mitmproxy 是用 Python 和 C 开发的一款支持 HTTP(S) 的中间人代理软件(man-in-the-middle proxy),不同于 Fiddler2,burpsuite 等类似功能工具,mitmproxy 可在终端下运行并且可以用来拦截、修改、重放和保存 HTTP/HTTPS 请求。mitmproxy 可以辅助 WEB 及客户端调试、开发和测试,是一个渗透测试的工具。
sudo apt-get install python3-pip python3-dev libffi-dev libssl-dev libtiff5-dev libjpeg8-dev zlib1g-dev libwebp-dev
sudo pip3 install mitmproxy # or pip3 install --user mitmproxy
或者从源里面拉,但是可能不是最新版本
sudo apt install mitmproxy
我从源里面拉的版本为 0.15 版,而 pip3 安装的为 1.02 版本,相差版本足有一年。
或者熟悉 Docker 可以使用官方打包好的镜像
mitmproxy 实现原理:
mitmproxy 工作步骤:
如果遇到 iOS 11 以上,访问网页时出现 This Connection is Not private
在确保证书安装的前提下,需要到 Settings > General > About > Certificate Trust Setting 开启证书信任。
官方提供的安装方式:http://mitmproxy.org/doc/certinstall.html
在完成 mitmproxy 的安装之后,mitm 提供的三个命令
可以使用 mitmproxy -h
来查看 mitmproxy 的参数及使用方法。常用的几个命令参数:
-p PORT, --port PORT
设置 mitmproxy 的代理端口-T, --transparent
设置透明代理--socks
设置 SOCKS5 代理-s "script.py --bar", --script "script.py --bar"
来执行脚本,通过双引号来添加参数-t FILTER
过滤参数在 mitmproxy 命令模式下,在终端显示请求流,可以通过 Shift + ? 来开启帮助查看当前页面可用的命令。
基本快捷键
b 保存请求 / 返回头
C 将请求内容导出到粘贴板,按 C 之后会有选择导出哪一部分
d 删除 flow 请求
E 将 flow 导出到文件
w 保存所有 flow 或者该 flow
W 保存该 flow
L 加载保存的 Flow
m 添加 / 取消 Mark 标记,会在请求列表该请求前添加红色圆圈
z 清空 flow list 和 eventlog
/ 在详情界面,可以使用 / 来搜索,大小写敏感
i 开启 interception pattern 拦截请求
移动
j, k 上下
h, l 左右
g, G go to beginning, end
space 下一页
pg up/down 上一页 / 下一页
ctrl+b/ctrl+f 上一页 / 下一页
arrows 箭头 上下左右
全局快捷键
q 退出,或者后退
Q 不提示直接退出
同样在 mitmproxy 中不同界面中使用 ? 可以获取不同的帮助,在请求详细信息中 m 快捷键的作用就完全不同 m 在响应结果中,输入 m 可以选择 body 的呈现方式,比如 json,xml 等 e 编辑请求、响应 a 发送编辑后的请求、响应。
因此在熟悉使用 ?
之后,多次使用并熟悉快捷键即可。就如同在 Linux 下要熟悉使用 man 命令一样,在不懂地方请教 Google 一样,应该是习惯性动作。多次反复之后就会变得非常数量。
使用 s 参数制定 inline 脚本
mitmproxy -s script.py
比如将指定 url 的请求指向新的地址
用于调试 Android 或者 iOS 客户端,打包比较复杂的时候,强行将客户端请求从线上地址指向本地调试地址。可以使用 mitmproxy scripting API
mitmproxy 提供的事件驱动接口。
加上将线上地址,指向本地 8085 端口,文件为 redirect_request.py
#!/usr/bin/env python
# -*- coding: UTF-8 -*-
def request(flow):
if flow.request.pretty_host == 'api.github.com':
flow.request.host = '127.0.0.1'
flow.request.port = 8085
则使用 mitmweb -s redirect_request.py
来调用此脚本,则通过 mitm 的请求都会指向本地 http://127.0.0.1:8085。
更多的脚本可以参考
一个完整的 HTTP flow 会依次触发 requestheaders
, request
, responseheaders
和 response
。
添加参数 --socks
可以使用 mitmproxy 的 SOCK5 代理
透明代理是指将网络流量直接重定向到网络端口,不需要客户端做任何设置。这个特性使得透明代理非常适合不能对客户端进行配置的时候,比如说 Android 应用等等。
对于 Openwrt 的路由器,在无线接口配置中一定要注意查看,“禁止客户端之间的通信”这个选项不启用。或者在 /etc/config/wireless
配置中, wifi-iface
配置中
option isolate 0
为关闭状态,否则无法让无线局域网中的设备之间通信。
主要是
sudo apt-get install libnss3-tools
certutil -d sql:$HOME/.pki/nssdb -A -t C -n mitmproxy -i ~/.mitmproxy/mitmproxy-ca-cert.pem
From: github
最近屏幕摔碎了一次,维修过程中无奈抹掉了所有数据,于是只能从头开始开搞。这里只是简单的记录一下,以免哪一天又有同样的悲剧发生,当然不可能再有下次了。
对于 Nexus 机型来说,Google 都提供了原厂镜像,一加同样也是,可以从官网下载 ,不过亲身经历一加官网的好多链接都挂掉了,直接从 xda 找反而要方便许多。官网的链接使用迅雷下载还遭遇了掉包,所以对于刷机包,一定要验证 md5,一定一定。
刷 Oxygen OS (氧 OS) , 有很多方法,如果使用的 stock recovery ,可以使用 adb sideload full-rom.zip
来刷入(官网有详细教程)。
而如果安装了 TWRP 或者 twrp-3.0.2-0_blu_spark_v11-op3.img
等等第三方的 recovery , 可以直接在 recovery 中 install ROM。虽然间隔遇到了一些问题,在使用 recovery 刷机的时候遇到 “this package is for OnePlus 3 devices this is one plus 3”,这样奇怪的错误。但是最后找原因还是因为 recovery 的关系,使用 TWRP 3.0.2 及以前的版本即可,或者 blu spark 的版本都可以完美解决。
使用下面地址给出的 superSu, systemless 可以完美 root。
https://forum.xda-developers.com/oneplus-3/how-to/oneplus-3-how-to-unlock-bootloader-t3398733
xda 终究是一切的开端,很多内容都是从这边开始,然后被无数人复制粘贴搬运到互联网的各个角落。因此,遇到任何刷机或者 root,或者 Android 相关的任何折腾的问题,用英语关键词来这里搜索有的时候比直接在 Google 搜索要灵得多。这有的时候就像是要查找某一款产品的型号或者功能时,直接在 jd.com 或者 淘宝搜索要来的快得多。或者垂直搜索领域确实值得深入发展一下,感觉这也是 Google 越来越担心亚马逊存在的原因之一吧。
在 root 之后,开机进入,就会发现一加默认的 DPI 实在感人,远看像老人机,每一个图标都老大老大。Oxygen OS 默认的 DPI 是 480,实际使用感受设置在 420 到 440 最佳。基本上 Launcher 中一行 5 个 图标,原始设置一行只能放下 4 个图标。
一加 3 修改 DPI ,可以有很多方法,最最简单的方法就是下载 Le DPI Changer 这个应用,直接在应用中修改(记得上一次可以修改成功,但是这一次差点将系统搞坏,这里要注意,修改 build.prop 文件一定要备份,否则有可能遇到无法开机的情况。幸亏这一次在系统中找到了 build.prop 的备份,在 recovery 中恢复了之前的设置)。
另外一种情况就是,直接修改 /system/build.prop
系统目录下的 build.prop 文件,直接修改文件内容。
ro.sf.lcd_density=420
同样也可以利用 BuildProp Editor 应用来修改,开启应用,右上角设置,中添加,键为 ro.sf.lcd_density
,值为 420 的条目。重启手机便可以生效。记住修改 build.prop 文件,以及任何系统文件一定要备份系统,或者可以在 recovery 中能够恢复修改的内容,否则有可能无法开机。建议使用 BuildProp Editor 这个应用来修改。
从 Play Store 中下载 Magisk Manager,安装打开,保证 ROOT,此时从 Magisk 中更新组件,重启,即可。
下文中的 boot.img 不要轻易刷入,其他未经验证的 boot.img 也不要轻易刷入。
在安装好 Magisk 之后,从 Magisk 中可以选择安装 Xposed ,然后参照之前整理过的文章 我使用的 Xposed Module 安装一遍。还很快。
如果不想使用 Systemless 的 Xposed ,可以使用官网的地址,直接从 recovery 中刷入。
一直使用的 ElementalX 的 kernel ,直接从 Play Store 上下载 ElementalX Manager,在应用中安装即可,应用会自动选择相应的版本。
原厂给我刷了 Android 7.0 的系统,在开机的时候除了解锁 bootloader 的提醒之外,还多了这个提醒,猜测可能是 Android 7.0 导致的,在刷完 Oxygen OS 3.2.8 (Android 6.0.1) 之后,这个提示就消失了。
在原本的 Xposed 列表中我曾经写过, Adblocker 这样一款广告去除 Module,但是这个 module 莫名其妙被 Xposed 仓库和 xda 移除,没有任何消息。有人说是因为有木马导致的,但是我更加觉得是因为去广告有用,得罪了不少人才导致下架的。
更多的细节可以参考下面的文章:
不过还是能从 Coolapk.com 来下载到下架版本。个人感觉还是能够屏蔽很多广告的。
至此所有系统级别设置都已经完成。附上一张桌面
为了解决 Linux Mint/Ubuntu 下安装 Dropbox 的问题,而认识了 proxychains。proxychains 是 Linux 下的代理工具,他允许其他程序通过其代理上网,支持 HTTP, SOCKS4 和 SOCKS5 类型的代理服务器,并可配置多个代理方式。
一直使用的 Dropbox 因为其被屏蔽,所以安装及使用必须通过代理,而 Shadowsocks 作为天然的 socks5 代理成为了最佳选择,在安装 Dropbox(Linux) 之后,设置中可以设置 Socks5 代理。于是剩下的问题便是,如何安装 Dropbox 了。在 Dropbox 官网下载的安装程序会自动下载相关组件,但是因为没有走代理,几乎在直连的情况下无法成功。所以在解决这个问题的时候知道了 proxychains。在了解其作用之后,发现也可以利用其特性来达到在 Linux 终端下让任何命令走代理的目的。
安装 proxychains 可以有很多方法,最简单的方式就是使用 apt
sudo apt install proxychains
如果想要使用最新版,也可以自己手动编译源码
# 安装
git clone https://github.com/rofl0r/proxychains-ng.git
./configure --prefix=/usr --sysconfdir=/etc
make
sudo make install
sudo make install-config
在安装完成之后,一般在 /etc/proxychains.conf
处会有默认配置文件,编辑该文件
sudo vim /etc/proxychains.conf
socks5 127.0.0.1 1080
# 开启本地 socks5 代理
然后使用
proxychains dropbox start -i
就可以启动 Dropbox 安装程序。安装成功之后使用设置中内置的代理即可。
或者使用
proxychains wget https://www.google.com
使用 curl ip.gs
来验证是否成功
$ curl ip.gs
当前 IP:124.xxx.xxx.xxx 来自:中国北京北京 电信
$ proxychains curl ip.gs
ProxyChains-3.1 (http://proxychains.sf.net)
|DNS-request| ip.gs
|S-chain|-<>-127.0.0.1:1080-<><>-4.2.2.2:53-<><>-OK
|DNS-response| ip.gs is 45.116.12.10
|S-chain|-<>-127.0.0.1:1080-<><>-45.116.12.10:80-<><>-OK
当前 IP:106.xxx.xxx.xxx 来自:日本东京都东京linode.com kddi.com
来现在任何内容
在配置完 proxychains 之后,在终端如果任何命令无法连接成功时,在其前加上 proxychains
就可以走代理方式来执行该命令。
在网上查阅的时候同样发现还有其他类似的工具,比如 polipo,这是一个 socks5 转 http 的代理,设置之后可以使用 export http_proxy=http://localhost:port
来让终端走代理。
polipo 的使用也非常简单
sudo apt-get install polipo
然后再修改其配置
sudo vim /etc/polipo/config
放置以下配置:
logSyslog = true
logFile = /var/log/polipo/polipo.log
proxy:socksParentProxy = "localhost:1080"
socksProxyType = socks5
启用 polipo
sudo /etc/init.d/polipo start
默认端口为 8123 使用即可。
不过需要注意的是 Polipo 作者已经在 GitHub 宣布项目不再更新。推荐还是使用 proxychains。
早之前曾经写过过一篇文章 总结 adb 的常用命令,这次刷机也复习了一些命令,这里再补充一下刷机中必不可少的 fastboot 命令。
就像之前 adb 中说过的那样, adb 用来向开机的 Android 设备发送指令,而 fastboot 则是向开机的 Android bootloader 来发送指令,因此在刷机过程中,如果手机重启进入 bootloader 基本之后使用的 命令都离不开 fastboot。比如在安装第三方 recovery 时,要用到 fastboot flash recovery recovery.img
这样的指令。虽然不能依靠此命令来刷入 ROM,但是 fastboot 也能够做一些 adb 命令无法实现的功能。
安装
sudo apt-get install android-tools-fastboot
常用的命令如下:
adb devices
adb reboot bootloader
fastboot devices
fastboot oem device-info
结果:
❯ fastboot oem device-info
...
(bootloader) Verity mode: true
(bootloader) Device unlocked: true
(bootloader) Device critical unlocked: true
(bootloader) Charger screen enabled: false
OKAY [ 0.006s]
finished. total time: 0.007s
关于 bootloader 部分可以参考 之前的文章
adb 和 fastboot 两个工具都是跟随着 Android SDK 分发的,但是由于这两个工具需求过高,Google 单独提供了两个工具集的下载。
在下载之后,需要将文件路径添加到系统环境变量中,以便于在各个路径下访问。
假设加压后的路径为 ~/Android/Sdk/platform-tools/
, 那需要在 ~/.bashrc 或者 ~/.zshrc 中配置。
export PATH="$PATH:/home/einverne/Android/Sdk/platform-tools"
WIndows 同理,在系统配置环境变量。
然后在终端下使用 adb devices
,就能够查看连接的设备。同样在 bootloader 下,也可以使用 fastboot devices
来查看连接设备,如果未出现已经 USB 连接的设备,查看驱动是否安装完好即可。
fastboot devices
用当前目录下的 boot.img 启动手机,在手机 boot 分区损坏的情况下可以用这个正常进入系统
fastboot boot boot.img
同理可以使用
fastboot boot recovery.img
来启动 recovery 模式
和手机上现有的系统完全无关,只要 PC 的 boot.img 或者 recovery.img 是可以正常工作的就可以。
刷机的人经常会遇到下面一些场景。
将当前目录下的 boot.img 刷入手机的 boot 分区:
fastboot flash boot boot.img
将当前目录下的 recovery.img 刷入系统的 recovery 分区:
fastboot flash recovery recovery.img
将当前目录下的 system.img 刷入系统的 system 分区:
fastboot flash system system.img
同理,刷入 data 分区
fastboot flash userdata userdata.img
清理分区的命令,慎用!!!
fastboot erase system
fastboot erase cache
fastboot erase config
fastboot erase data
fastboot erase logs
fastboot erase factory
最后重启手机
fastboot reboot
本文介绍 Android 反编译工具,只介绍工具名字及工具简单使用,详细开来再具体讲吧。本文主要包含工具的作用,工作的简单用法,以及反编译的基本步骤。
反编译 Android APK 主要需要依靠如下几个工具:
apktool
:A tool for reverse engineering Android apk files 查看 APK 包中的 AndroidManifest.xml
等 XML 资源文件
dex2jar
:Tools to work with android .dex and java .class files 将 APK 包中的 Dalvik 字节码文件(.dex)转换为 .jar 文件JD-GUI
:Java Decompiler is a tools to decompile and analyze Java 5 “byte code” and the later versions 查看 .jar 文件的 Java 源码
相关项目及工具地址后文贴出。
Apktook 是一个反编译(reverse engineering) 工具,可以用来反编译Android APK。几乎可以将APK中的 resources.arsc
, classes.dex
和 9.png
以及 XMLs 等等源文件反编译得到。
安装需要:
地址: https://ibotpeaches.github.io/Apktool/
各平台的安装指南,如果使用 Linux 可以使用如下简易步骤:
apktool
,并移动到 /usr/local/bin/
目录下ia32-libs
,使用 apt search ia32
,然后 apt install ia32-libs
安装,可跳过apktool.jar
apktool.jar
和 apktool
移动到 /usr/local/bin/
目录中,需要 root 权限chmod +x /usr/local/bin/apktool
apktool
apktool d xxx.apk
Apktool 其实还可以用来做另外一件事情,就是汉化,或者将语言包替换之后,重新打包,此时需要使用 apktool b xxx.apk
来重新打包 APK。
dex2jar 能够将 dex 转换为 jar
地址:https://github.com/pxb1988/dex2jar
JD GUI 用来反编译源文件jar包,查看源代码
总的来说 apktool 可以让你轻松的拿到应用的资源文件,包括图片,xml等,而 dex2jar 和 JD GUI 可以反编译源代码,看到一些基础的代码结构。
后来 Google 搞了一个 ClassyShark,看起来不错,不过还没来得及尝试
还有一个 不错的 smali 查看插件看起来也不错,还未尝试
https://github.com/JesusFreke/smali
另外有一个 MAC 专属的一键反编译工具,可以一试:
https://github.com/Jermic/Android-Crack-Tool
又一个查看 dex 到 jar 的反编译工具:
我们都知道 HBase 的基本结构由 rowkey,column, timestamp 组成。列存储数据不同于关系型数据库,MySQL 一旦建表,需要修改表结构时则需要执行对应的修改语句,而 HBase 在建完表之后,对于列的增加则不需要修改建表语句,但这并不意味着 HBase 的建表就可以随意建。
首先来看看 HBase 的结构
通过以上 Row, Column Family, Column Qualifier, TimeStamp 可以唯一确定一个基本存储单元 Cell。
并没有关系型数据库到列存储数据库一对一的设计迁移,在关系型数据库中,设计的重点是描述实体和其他实体之间的关系,查询和索引可以在之后设计。
而在 HBase 中,遵循着查询优先的设计模式,所有可能的查询都需要在设计中体现,因此 Schema 的设计方式也因此而来。考虑查询的方式,然后设计 Schema,这样可以使得数据能够快速被查询到。另外需要注意 HBase 被设计用来在大数据集群中使用,当预计数据量能够到达一个层级的时候再考虑使用。
rowkey 是 Table 的”主键”,设计时需要确保唯一性,数据按照 rowkey 大小顺序存储,rowkey 不是 schema 的一部分,但需要仔细设计:
[startKey, endKey)
的顺序读,吞吐量很高。rowKey 设计热点问题,rowKey 要尽量随机,不要出现连续 rowKey。
建议 HBase 设计为高表,不宜使用过多列族。
列和列族名字不宜太长,HBase 会在内存中对列和列族做索引和缓存。
我们知道如果使用 Nginx 可以使用 Virtual HOST 来 HOST 多个域名下的网站到同一台机器,那么如果使用 Docker 架设了一个 WordPress,还想用 Docker 架设一个新的网站,那么该怎么办呢?
有一种解决办法就是使用 Nginx 转发请求,比如一个网站监听了 81 端口,一个网站监听了 82 端口,那么使用 Nginx 的代理功能,将对应的流量转发给对应的服务器处理即可。因此 nginx-proxy 这个镜像的作用就如上面所述,让我们将不同的流量转发给不同的 Docker 容器进行处理。
有两种方式可以启动 nginx-proxy
容器,一种是通过 docker 命令,另一种是使用 docker-compose
。不过用这两种方式之前,先创建一个 Docker network,将多个容器关联起来
docker network create nginx-proxy
然后创建容器
docker run -d -p 80:80 --name nginx-proxy --net nginx-proxy -v /var/run/docker.sock:/tmp/docker.sock jwilder/nginx-proxy
或者创建 docker-compose.yml
:
version: "3"
services:
nginx-proxy:
image: jwilder/nginx-proxy
container_name: nginx-proxy
ports:
- "80:80"
volumes:
- /var/run/docker.sock:/tmp/docker.sock:ro
networks:
default:
external:
name: nginx-proxy
然后在同目录下 docker-compose up -d
Nginx Proxy Manager 的管理面板在 81 端口,默认的用户名和密码是 admin@example.com
和 changeme
。
nginx-proxy 对外暴露 80 端口,并且监听 80 端口,允许 80 端口的流量流入。而 /var/run/docker.sock:/tmp/docker.sock
这一行则表示着允许该容器访问宿主机器的 Docker socket,这也就意味着有新容器加入,或者新容器关闭时都会通知到 nginx-proxy。
这样每一次添加容器,nginx-proxy 就会通过 socket 来接收到事件,自动创建对应的配置文件,然后重启 nginx 来生效。nginx-proxy
会寻找带有 VIRTUAL_HOST
环境变量的容器,然后依照配置进行。
另外 --net nginx-proxy
和 docker compose 中 networks 块的配置,让所有的容器通过 Docker network 进行通讯。
比如增加一个 WordPress 容器
docker run -d --name blog --expose 80 --net nginx-proxy -e VIRTUAL_HOST=blog.DOMAIN.TLD wordpress
--expose 80
会允许流量从 80 端口流入--net nginx-proxy
保证 Docker 使用同一个网络-e VIRTUAL_HOST=blog.DOMAIN.TLD
开启 nginx-proxy
创建对应的配置文件将流量转发给 WordPress 容器如果使用 Docker compose
version: "3"
services:
db_node_domain:
image: mysql:5.7
volumes:
- db_data:/var/lib/mysql
restart: always
environment:
MYSQL_ROOT_PASSWORD: PASSWORD
MYSQL_DATABASE: wordpress
MYSQL_USER: wordpress
MYSQL_PASSWORD: PASSWORD
container_name: wordpress_db
wordpress:
depends_on:
- db_node_domain
image: wordpress:latest
expose:
- 80
restart: always
environment:
VIRTUAL_HOST: blog.DOMAIN.TLD
WORDPRESS_DB_HOST: db_node_domain:3306
WORDPRESS_DB_USER: wordpress
WORDPRESS_DB_PASSWORD: PASSWORD
container_name: wordpress
volumes:
db_data:
networks:
default:
external:
name: nginx-proxy
不过这里需要注意的是会创建一个数据库容器,一个 WordPress app 容器。
如果想要支持 SSL,那么 nginx-proxy
有一个对应的项目 letsencrypt-nginx-proxy-companion,他可以自动创建和续签 Let’s Encrypt 的证书。
Busybox 将很多 UNIX 下的工具集打包到一个可执行文件中,特别适合小容量的嵌入式设备,Android 等等。最近也是因为在 Android 用到才接触到。
实际的命令列表按编译时的设置决定,在有 Busybox 的系统上执行 busybox --list
即可看到一个完整的列表。
127|:/ $ busybox
BusyBox v1.30.1-osm0sis (2019-02-28 18:48:08 AST) multi-call binary.BusyBox is copyrighted by many authors between 1998-2015.
Licensed under GPLv2. See source distribution for detailed
copyright notices.
Usage: busybox [function [arguments]...]
or: busybox --list[-full]
or: busybox --show SCRIPT
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, arch, arp, arping, ash, awk,
base64, basename, bbconfig, beep, blkdiscard, blkid,
blockdev, brctl, bunzip2, bzcat, bzip2, cal, cat, chat,
chattr, chgrp, chmod, chown, chroot, chrt, chvt, cksum,
clear, cmp, comm, conspy, cp, cpio, crond, crontab,
cttyhack, cut, date, dc, dd, deallocvt, depmod, devmem, df,
dhcprelay, diff, dirname, dmesg, dnsd, dnsdomainname,
dos2unix, du, dumpkmap, dumpleases, echo, ed, egrep, eject,
env, ether-wake, expand, expr, factor, fakeidentd, false,
fatattr, fbset, fbsplash, fdflush, fdformat, fdisk,
fgconsole, fgrep, find, findfs, flock, fold, free,
freeramdisk, fsck, fsck.minix, fsfreeze, fstrim, fsync,
ftpd, ftpget, ftpput, fuser, getopt, grep, groups, gunzip,
gzip, hd, hdparm, head, hexdump, hexedit, hostname, httpd,
hush, hwclock, id, ifconfig, ifdown, ifenslave, ifplugd,
ifup, inetd, inotifyd, insmod, install, ionice, iostat, ip,
ipaddr, ipcalc, ipcrm, ipcs, iplink, ipneigh, iproute,
iprule, iptunnel, kbd_mode, kill, killall, killall5, klogd,
less, link, ln, loadfont, loadkmap, logread, losetup, ls,
lsattr, lsmod, lsof, lspci, lsscsi, lsusb, lzcat, lzma,
lzop, lzopcat, makedevs, makemime, man, md5sum, 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,
nl, nmeter, nohup, nologin, nslookup, nuke, od, openvt,
partprobe, paste, 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, resume,
rev, rfkill, rm, rmdir, rmmod, route, rtcwake, run-init,
run-parts, rx, script, scriptreplay, sed, sendmail, seq,
setconsole, setfattr, setfont, setkeycodes, setlogcons,
setpriv, setserial, setsid, setuidgid, sh, sha1sum,
sha256sum, sha3sum, sha512sum, showkey, shred, shuf,
slattach, sleep, smemcap, sort, split, ssl_client,
start-stop-daemon, stat, strings, stty, sum, svc, svok,
swapoff, swapon, switch_root, sync, sysctl, syslogd, tac,
tail, tar, tc, tcpsvd, tee, telnet, telnetd, test, tftp,
tftpd, time, timeout, top, touch, tr, traceroute,
traceroute6, true, truncate, tty, ttysize, tunctl, tune2fs,
ubiattach, ubidetach, ubimkvol, ubirename, ubirmvol,
ubirsvol, ubiupdatevol, udhcpc, udhcpc6, udhcpd, udpsvd,
uevent, umount, uname, uncompress, unexpand, uniq,
unix2dos, unlink, unlzma, unlzop, unxz, unzip, uptime,
usleep, uudecode, uuencode, vconfig, vi, volname, watch,
watchdog, wc, wget, which, whoami, whois, xargs, xxd, xz,
xzcat, yes, zcat, zcip
:/ $
HBase Shell 是 HBase 提供的一个简单方便的命令行工具,用它可以直接操作 HBase,对 HBase 进行各种设置。 HBase Shell 提供的命令可以对对 HBase 数据进行增删改查。在上一篇 HBase 介绍 中对 HBase 做了简答的介绍,也初识了一些命令行。
根据官方的解释 Apache HBase Shell 是 (J)Ruby 下的 IRB(Interactive Ruby Shell),任何在 IRB 下的命令,在 HBase Shell 下都可以使用。1
可以在启动 HBase 之后,通过 ./bin/hbase shell
来进入 HBase Shell。
status
查询服务器状态
version
查询 HBase 版本
whoami
查看连接用户
列举数据库中所有表
list
create 命令
create 'table_name', 'cf1', 'cf2'
其中的 cf1 和 cf2 为列族名 1,列族名 2,列族需要在见表时确定,列则不需要, Column Family 是 Schema 的一部分,设计时就需要考虑。
在删除表之前需要使用 disable 命令,让表失效。在修改表结构时,也需要先执行此命令
disable "table_name'
删除表使用 drop 命令
drop 'table_name'
exists 'table_name'
会显示表是否存在:
hbase(main):002:0> exists 'test'
Table test does exist
0 row(s) in 0.2650 seconds
describe 命令查看表结构,显示 HBase 表 schema,以及 column family 设计
describe 'table_name'
enable 命令,和 disable 命令对应
enable 'table_name'
alter 修改表的结构,新增列族,删除列族。在修改之前要先 disable ,修改完成后再 enable
新增列族
alter 'table_name', '列族'
删除列族
alter 'table_name', {name=>‘列族’, METHOD=>'delete'}
举例:
hbase(main):049:0> alter 'test','cf2'
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 1.7520 seconds
hbase(main):050:0> describe 'test'
DESCRIPTION ENABLED
'test', {NAME => 'cf', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3', COMPRESSION => ' false
NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCODE_ON_DI
SK => 'true', BLOCKCACHE => 'true'}, {NAME => 'cf2', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', COM
PRESSION => 'NONE', VERSIONS => '3', TTL => '2147483647', MIN_VERSIONS => '0', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', ENCO
DE_ON_DISK => 'true', IN_MEMORY => 'false', BLOCKCACHE => 'true'}
1 row(s) in 0.1680 seconds
hbase(main):052:0> alter 'test', {NAME => 'cf2', METHOD => 'delete'}
Updating all regions with the new schema...
1/1 regions updated.
Done.
0 row(s) in 1.5880 seconds
hbase(main):053:0> describe 'test'
DESCRIPTION ENABLED
'test', {NAME => 'cf', DATA_BLOCK_ENCODING => 'NONE', BLOOMFILTER => 'NONE', REPLICATION_SCOPE => '0', VERSIONS => '3', COMPRESSION => ' false
NONE', MIN_VERSIONS => '0', TTL => '2147483647', KEEP_DELETED_CELLS => 'false', BLOCKSIZE => '65536', IN_MEMORY => 'false', ENCODE_ON_DI
SK => 'true', BLOCKCACHE => 'true'}
1 row(s) in 0.2010 seconds
通常情况下列族不能被重命名,如果需要修改列族名字,通常用命令创建一个期望的列族名字,然后将数据复制过去,然后再删除旧列族。
使用 put 命令插入数据
插入数据,对于同一个 rowkey,如果执行两次 put,则认为是更新操作
put 'table_name', 'rowkey', '列族名 1: 列名 1', 'value'
put 't1', 'r1', 'c1', 'value', ts1
一般情况下 ts1(时间戳) 可以省略, Column 可以动态扩展,每行可以有不同的 Column。
增加指定表、行的值
incr
计算表的行数,count 一般比较耗时,使用
count 'table_name'
查询所有 rowkey
count 'table_name', { INTERVAL => 1 }
get 命令获取数据,HBase 的 shell 操作,大概顺序就是命令后接表名,rowkey,列名然后在后面用花括号加上其他过滤条件。
获取指定 rowkey 的指定列族指定列的数据,每个 Column 可以有任意数量的 Values,按照 Timestamp 倒序自动排序,可以使用 scan 'table_name', {VERSIONS => 10}
来验证,详细请查看 scan 命令
get 'table_name', 'rowkey', '列族名:列名'
获取指定 rowkey 的指定列族所有的数据
get 'table_name', 'rowkey', '列族名'
获取指定 rowkey 的所有数据
get 'table_name', 'rowkey'
获取指定时间戳的数据
get 'table_name', 'rowkey', {COLUMN=>'列族名:列', TIMESTAMP=>1373737746997}
获取多个版本值,查询默认返回最新的值
get 'table_name', 'rowkey', {COLUMN => '列族名:列名', VERSIONS => 2}
HBase 按照 rowkey 字典序 (1, 100, 102, 20) 自动排序,每行包含任意数量 Column,每列按照 列名 Column Key 排序。如果有列族 cf,其中有列 cf:a, cf:b, cf:c, 则按照字典序排序。
每个数据由 TabelName+RowKey+Column+Timestamp=>Value 唯一确定。
delete 命令删除表中数据,delete 命令只能用来删除某一列。
删除指定 rowkey 的指定列族的列名数据
delete 'table_name', 'rowkey', '列族名:列名'
删除指定 rowkey 指定列族的数据
delete 'table_name', 'rowkey', '列族名‘
使用 deleteall 命令来删除 rowkey 所有 column 的 Value,删除整行数据
deleteall 'table_name', ’rowkey'
使用 scan 命令全表扫描
hbase(main):043:0> scan 'test', {VERSIONS => 12}
ROW COLUMN+CELL
rowkey1 column=cf:a, timestamp=1487295285291, value=value 3
rowkey1 column=cf:a, timestamp=1487294839168, value=value 2
rowkey1 column=cf:a, timestamp=1487294704187, value=value 1
删除全表数据,这个命令也是 disable,drop,create 命令组合而成。
truncate 'table_name'
shell 命令,把所有的 hbase shell 命令写到一个文件内,类似与 Linux shell 脚本顺序执行所有命令,可以使用如下方法执行。
hbase shell test.hbaseshell
下面是比较完整的一个列表:
官方 reference