linux命令lib,linux命令连接oracle数据库

Linux 下 lib 文件缺失的通用解决办法

经常安装或者编译一些工具的时候会遇到类似 lib .so.* 等文件缺失的提示。一般我们可以通过百度谷歌寻找解决办法,但是除了这些办法,我们还可以自己寻找包名,然后安装。

成都创新互联公司是一家集网站建设,南芬企业网站建设,南芬品牌网站建设,网站定制,南芬网站建设报价,网络营销,网络优化,南芬网站推广为一体的创新建站企业,帮助传统企业提升企业形象加强企业竞争力。可充分满足这一群体相比中小企业更为丰富、高端、多元的互联网需求。同时我们时刻保持专业、时尚、前沿,时刻以成就客户成长自我,坚持不断学习、思考、沉淀、净化自己,让我们为更多的企业打造出实用型网站。

上面安装了一个软件,用于从仓库索引中找到相关的包信息。

软件安装完成需要使用一下命令索引。

例如我遇到的是 libGL.so.1 文件的缺失,于是搜索:

返回结果:

我猜是 libgl1-mesa-glx 和 primus-libs 这两个软件包没装,于是装上。问题解决。

如果还是不行,试一下安装该包的 i386 版本,例如:

Linux实用命令有哪些?

1选择

1.1一个文件的名字为rr.Z,可以用来解压缩的命令时()

tar

gzip

compress

uncompress

1.2可以结束进程命令()

kill

ctrl+c

shutdown

halt

1.3 Linux下对文件进行归档的命令为:(多选)

dd

tar

zip

unzip

1.4 Linux查当前目录下30天以前的文件并移动到/dev/null下的命令:(多选)

find.-mtime 30-type f xargs mv{}/dev/null;

find.-mtime+30-type xargs mv{}/dev/null;

find.-mtime+30-type f-exec mv{}/dev/null;

find.-mtime+30-type f-exec rm–rf{};

1.5 dstat与下面哪个命令类似

vmstat

sar

iotop

abc

1.6 rpm安装软件的参数

rpm-ivh

rpm-Ivh

rpm-Uvh

rpm-Iuvh

1.7 yum升级软件包选项

rpm-uvh

rpm-Uvh

1.8查看网络流量命令是?

iftop

nsload

ifstatd

以上命令全可以

1.9停止进程的命令,除了kill还有谁?

pkill

killa

allkill

以上命令都不正确

1.10服务器之间传文件的命令有?

wget

scp

ftp

以上命令都可以

1.11对文件进行归档的命令为

dd

cpio

gzip

tar

1.12在rpm命令中,安装新的rpm包软件使用的参数是()

-i

-v

-h

-e

1.13du命令中,使用友好的方式显示信息的参数是()

-h

-f

-a

-t

1.14将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现如此任务的tar命令格式___

tar zxvf/home/stud1/wang.tar.gz/home/wang

tar xcvf/home/stud1/wang/home/wang

tar zcv/home/stud1/wang/home/wang

tar zcvf/home/stud1/wang/home/wang.tar.gz

1.15终止一个前台进程可能用到的命令和操作()A:kill

B:CTRL+C

C:shutdown

D:halt

1.16关闭Linux系统(不重新启动)可使用命令()

A:Ctrl+Alt+Del

B:halt

C:shutdown-r now

D:reboot

1.17下列提法中,不属于ifconfig命令作用范围的是__

A:配置本地环回地址

B:配置网卡的IP地址

C:激活网络适配器

D:加载网卡到内核中

1.18有关归档和压缩命令,下面描述正确的是()

A:用uncompress命令解压缩由compress命令生成地后缀为.zip的压缩文件

B:upzip命令和gzip命令可以解压相同类型文件

C:tar归档其压缩的文件可以有gzip命令解压缩

D:tar命令归档后的文件也是一种压缩文件

1.19终止一共前台进程可能用到的命令和操作

kill

ctrl+c

shut down

halt

1.22为了将当前目录下的归档文档myftp,tar解压缩到/tmp目录下,用户可以使用命令

tar xvzf my

tar xvzf my

tar vzf my

tar xvzf my

1.23下面有关linux查看系统负载的命令,说法错误的是?

uptime命令主要用于获取主机运行时间和查询linux系统负载等信息

vmstat命令可以查看cpu负载

sar命令可以查看网络接口信息

free命令可以查看磁盘负载情况

1.24以下哪些方式/命令不可以查看某ip是否可达?

telnet

ping

tracert

top

1.25 tar命令用于解压的参数是?-v-x-c-f

1.26下面哪个命令不是用来查看网络故障?

telnet

ping

init

netstat

1.28为了知道谁在正注册到你的机器上,可以用命令:___

Who users finger ping

1.29查看本网段其他计算机的MAC地址,可先ping对方主机,然后;

arp-g

arp-n

arp-a

arp-d

1.3014日下午2点date+%y%m%d%H%M输出的时间是什么

201711141212

1711141212

2017111412

201711021212

1.31以下哪个命令可以得出1487进程的线程运行情况()

top-Hp 1487

top-Pp 1487

ps-mp 1487

sat-p 1487

1.32从/home/oracle下搜索一个日志文件alert.log,以下哪种方式可达到目的()

find/home./oracle-name alert.log

locate alert.log

find./-mtime 7 alert.log

find/home/oracle-exec alert.log

1.34以下哪些命令可以用来测试网络中特定主机的80端口是否可以访问()

Ping telnet netstat lsof

2填空

2.1测试网络中主机的连通性用什么命令

2.2如何查看numa是否关闭_**_

2.3将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现如此任务的tar命令格式_**

2.4某个进程使用端口7001,如何快速找到该进程的PID

2.5结束后台进程的命令是**_**

2.6将/home/studl/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此存到/home目录下,实现此任务的tar命令格式******__******

2.7 ping100个包的命令——

2.8 linux下,解压缩bz2格式文件的命令是**_**

2.9 linux下,查看网络连接状态的命令是**___**

2.10Linux查看文件系统的命令为__,显示目录或文件占用磁盘的命令为___

2.11通常我们测试网络连通性使用的ping命令,它是通过____协议进行工作的

2.12简述下列命令的各自作用

nslookup

dig

top

traceroute

2.13将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此问价保存到/home目录下,实现此任务的tar命令格****_****

2.14Linux系统查看进程数的命令___

2.15Linux系统查看系统内存的命令:____,**__**

2.16Linux系统查看cpu使用率的命令:____,**__**

2.17Linux系统查看硬盘空间使用率的命令:___

2.18Linux系统将某一文件下的所有.log文件进行打包压缩,命令为___

2.19Linux常用的性能监控命令是:_、_、_、_、_、_等

2.20假设output程序可能输出标准输出和标准错误,请写出一条命令把这两者都忽略__

2.21 rpm软件包安装命令**_**

3简答

3.1查看硬盘结构显示的命令?查看文档命令?编辑文档命令?

3.2配置网络环境的命令,手工修改IP,主机名,DNS和网关

3.3有压缩包a.tar.gz,如何解压该包?如何不解压该包,如何查看该包的内容?

3.4某进程abcd在系统中起了很多,数量难以统计,造成系统负荷较高,如何一条命令确保将此进程全部杀掉

3.5某日志路径是/data/logs/a.txt,如何跟踪该日志,以查看当时的运行状态?

3.6 dmesg命令显示的是哪方面信息

3.7寻找名称为mytest.log的文件

3.8写出du-sh与df-h的区别

3.9查看当前linux服务器是否监听80端口,如果监听,请找出其进程ID,并结束该进程。

3.10使用curl或者wget获取http服务的header信息。

3.11写出查看linux系统性能的命令,如cpu、内存、流量、io等

3.12解释下列命令的意思

dd if=/dev/random of=/dev/sda

3.13如何查看占用端口8080的进程

3.14查着占用内存最多的进程

3.15压缩和解压缩目录/opt/gjsy/所有文件命令

3.16Linxu系统下如何查看8080端口上运行的程序状态

3.17ps aux中的VSZ代表什么意思,RSS代表什么意思?

3.18PING是使用TCP/IP协议中的**_**协议

3.19写出网络故障排查常用的命令**__**

3.20写出你常用的网络抓包工具,软件名称**__**

3.21将/home/stud1/wang目录做归档压缩,压缩后生成wang.tar.gz文件,并将此文件保存到/home目录下,实现此任务的tar命令格式___

3.22解释该命令的含义:nohup zcat test.gz|grep"x6game"~/log.txt

2/dev/null

3.23查看系统硬件负载工具或命令有哪些

3.24使用lsof命令查看占用80端口的进程

3.25如何使用CURL测试POST接口

3.26怎样在目录/home/user/training/下找到扩展名为txt的文件

3.27最常用的网络测试命令有什么?

3.28ping的测试结果中都包含哪些部分?

3.29如何找出占用22端口的进程及进程号?

3.30如何删除当前目录(包含字目录)下所有30天以前创建的文件名后缀为.log的文件

3.31以下一些Linux命令的作用分别是什么?

init 0

chkconfig--level 3 sendmail on

tar-czvf test.tar.gz./

chown-R

ln-s/data/log//var/log/sina_log

umount-f/data0

rpm-ivh baihui.rpm

rpm-qf/bin/ls

3.32LINUX常用命令pwd、top、df、ifconfig、cat分别代表什么含义?

3.33linux常用命令:关机、重启、编辑某文档文件、删除某文件、更改操作系统密码命令分别是什么?

3.34请使用命令:删除/backup目录下10天前的普通文件

3.35如何查看服务器当前连接ip的列表

3.36写出liunx系统中diff、chmod、grep、kill、tar五个常用命令的功能

3.37简述tar-cjvf/tmp/test.tar.gz/root命令中错误及错误原因

3.38Linux系统从A服务器测试B服务器一个tcp端口是否联通使用___

3.39写一个脚本查找最后创建时间使3天前,后缀是*.log的文件并删除

3.40linux如何根据进程ID查找启动程序的路径

3.41查看占用swap的进程id

3.42列出linux常见打包工具并写相应解压缩参数(至少三种)

3.43Linux中锁定一个文件用什么命令?他和md5sum有什么区别?

3.44如何在系统中查找所有所属用户为user1的文件

3.45查看某个文件或者文件夹占用磁盘空间大小的命令

3.46如何查看远程linux系统运行了多少时间?我的服务器内存,cpu,硬盘都是多少,系统版本,linux会优先将数据缓存到内存中,我的机器真实内存消耗实际上是多少

3.47查看服务器当前开启了哪些端口?如何查看某服务器是否存在IO压力

3.48如何查看某个文件system.log被哪些进程占用

扩展

1.21在退出unix系统账户之后还需要继续运行某个进程,那么可用()

awk sed crontab nohup screen

1.20使用trace命令的目的是()

可用的,十分成功的测试手段

非常基本的测试手段

把IP地址和DNS加入路由表中

在源到目标传输的过程中查找失散点

1.27哪个变量用来指定一个远程x应用程序将输出放到哪个x server上

TERM

DISPLAY

ECHO

OUTPUT

1.33P系列服务器被用做文件服务器,所有的用户文件存都放在一非rootvg的文件系统上,用什么方法可以快速备份和恢复这些数据和文件系统的定义()

tar

cpio

savefs

savevg

linux一个应用多个版本动态库命令

Linux 系统,也同样面临和Window一样的问题,如何控制动态库的多个版本问题。Window之前没有处理好,为此专门有个名词来形容这个问题 “Dll hell”,其严重影响软件的升级和维护。 Dll hell 是指windows 上动态库新版本覆盖旧版本,但是却不兼容老版本。常常发生在程序升级之后,动态库更新,原有程序运行不起来;或者装新软件,但是已有的软件运行不起来。 同样Linux操作系统,也有同样的问题,那么它是怎么解决的呢?

Linux 为解决这个问题,引入了一套机制,如果遵守这个机制来做,就可以避免这个问题。 但是这只事一个约定,不是强制的。但是建议遵守这个约定,否则同样也会出现 Linux 版的Dll hell 问题。 下面来介绍一个这个机制。 这个机制是通过文件名,来控制dll (shared library) 的版本。

Linux 上的Dll ,叫shared library,其有三个名字,分别有不同的目的。

第一个是共享库本身的文件名(real name),其通常包含版本号,常常是是这样: libmath.so.1.1.1234 。 lib是Linux 上的库的约定前缀,math 是共享库名字,so 是共享库的后缀名,1.1.1234的是共享库的版本号,其主版本号+小版本号+build号。主版本号,代表当前动态库的版本,如果动态库的接口有变化,那么这个版本号就要加1;后面的两个版本号(小版本号 和 build 号)是告诉你详细的信息,比如为一个hot-fix 而生成的一个版本,其小版本号加1,build号也应有变化。 这个文件名包含共享库的代码。

第二个是动态库的soname( Short for shared object name),其是应用程序加载dll 时候,其寻找共享库用的文件名。其格式为

lib + math+.so + ( major version number)

其只包含major version number,换句话说,也就是只要其接口没有变,应用程序都可以用,不管你其后minor build version or build version。

问题来了,程序运行时怎么通过soname 找个real name? Soname 存在哪里?如果与real name 关联起来?什么时候存的?

这就是接下来要介绍的第三个共享库的名字,link name,顾名思义,就是在编译过程,link 阶段用的文件名。 其将sonmae 和real name 关联起来。

第三个名字,共享库的连接名(link name),是专门为build 阶段连接而用的名字。这个名字就是lib + math +.so ,比如libmath.so。其是不带任何版本信息的。在共享库编译过程中,连接(link) 阶段,编译器将生成一个共享库及real name,同时将共享库的soname,写在共享库文件里的文件头里面。可以用命令 readelf -d sharelibrary 去查看。

《Linux下部分常用指令笔记》

一、创建linux维护用户

登录root用户

创建新用户

useradd 新用户名

设置用户密码

passwd 新用户密码

二、安装jdk和配置环境变量

建议在root用户下直接安装jdk,并直接配置环境变量,同时给非root用户设置读和执行权限

解压包

tar xvf jdk包名.tar

配置全局变量

编辑/etc/profile文件

vi /etc/profile

按I键,切换成编辑模式。

在文件未加入一下配置

export JAVA_HOME=jdk的解压文件目录

export JRE_HOME=jdk的解压文件目录/jre

export CLASSPATH=.:${JAVA_HOME}/lib:${ JRE_HOME}/lib:$CLASSPATH

export JAVA_PATH=${JAVA_HOME}/bin:${ JRE_HOME}/bin

export PATH=$PATH:${JAVA_PATH}

保存并退出

Esc   

:wq

重载配置文件使其生效

source /etc/profile

检查是否安装成功

Javac

Java version

权限修改

读4写2执行1,顺序所有者、组成员、其他用户

Chomd  755  jdk的解压文件目录

三、安装tomcat

安装tomcat和放入war包使用非root的维护用户

如果使用root安装的话记得设置权限。( chomd -r 外层文件目录 )

su - 用户名

1、解压包

tar  xvf  tomcat包名.tar

2、将war包放入tomcat/webapps目录下

3、Tomcat启动服务和停止服务

查看进程

ps -ef | grep java

启动应用

Tomcat bin目录下.startup.sh

停止应用

建议使用

Kill -9 进程号

注:解压出应用文件后,注意配置信息的修改

四、IBM MQ部署 (7.5之后的版本)

(以下是使用9.0版本的正确部署命令)

一、 卸载旧版本IBM MQ (可选)

因为部署环境没有安装过mq,卸载这部分命令我没有亲自测试过

设置环境

以用户身份登录到组mqm,找到mq的安装位置 /opt/mqm

source ./setmqenv -s

查看队列管理器的状态

dspmq -o installation

停止与要卸载的安装关联的所有正在运行的队列管理器

endmqm SXRECV

停止与队列管理器关联的所有侦听器。

endmqlsr -m SXRECV

查看系统上当前安装的软件包(组件)

sudo rpm -qa | grep MQSeries

列出软件包并一次性卸载

sudo rpm -qa | grep MQSeries | xargs rpm -ev

再将对应的用户及安装目录给删除

rm -rf /opt/mqm

userdel -r mqm

检查MQ license

license文件在安装目录中 /opt/mqm/lib 可以找到

amqtcert.lic - is a trial license

amqbcert.lic - is a beta license

amqpcert.lic - is the production license

——————————————————————————————————————

二、安装新版本ibm mq

解压,解压文件都在MQServer中

tar –xzvf IBM_MQ_9.1.5_LINUX_X86-64.tar.gz

进入MQServer文件夹中:

cd MQServer/

运行MQ许可证程序

./mqlicense.sh

安装WebSphere MQ for Linux服务器(Runtime、SDK 和 Server 软件包):

rpm -U MQSeriesRuntime-9.1.5-0.x86_64.rpm

rpm -U MQSeriesSDK-9.1.5-0.x86_64.rpm

rpm -U MQSeriesServer-9.1.5-0.x86_64.rpm

安装WebSphere MQ for Linux客户机:

rpm -U MQSeriesClient-9.0.0-0.x86_64.rpm

安装WebSphere MQ样本程序:

rpm -U MQSeriesSamples-9.0.0-0.x86_64.rpm

创建组和用户

安装过程创建了一个名为mqm的用户和一个同样名为 mqm 的组。设置一个密码来解锁。

passwd mqm

——————————————————————————————————————

三、 配置

(这部分队列管理器、通道、队列等根据实际情况自行配置)

切换用户:

su mqm

创建队列管理器

使用crtmqm命令来创建一个名为 SXRECV

的队列管理器。我们把它作为缺省队列,并且将不在创建时指定死信队列。然后使用strmqm命令启动队列管理器。

crtmqm -q  SXRECV

strmqm  SXRECV

——————

如果执行crtmqm命令时提示

-bash-3.2$ crtmqm

-bash: crtmqm: command not found

find / -name crtmqm

则需要配置mqm用户的环境变量,编辑如下文件,并添加下面的内容,如下:

第一种方法:相对第二种较安全仅对mqm用户有效

方法一:

(1) -bash-3.2$ vi /var/mqm/.bash_profile --有可能会在文件夹下看不到这个文件,通过编辑即可看到

PATH=$PATH:/opt/mqm/samp/bin:/opt/mqm/bin:bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/X11R6/bin

(2)执行“.”命令,使这个文件生效

-bash-3.2$ source  .bash_profile

(3)再次尝试实行crtmqm或是dspmqm命令,即可发现已经生效。

方法二:

( 1)

su  root

[if !supportLists](2)[endif]

vim /etc/profile

[if !supportLists](3)[endif] 在最后面加上:

PATH=$PATH:/opt/mqm/samp/bin:/opt/mqm/bin:bin:/usr/bin:/usr/sbin:/usr/local/bin:/usr/local/bin

( 4)关闭远程终端重新打开,无需重启服务器

——————

运行队列管理器

runmqsc SXRECV

创建通道和队列

DEFINE QLOCAL (XYDATA) REPLACE USAGE (NORMAL) DEFPSIST (YES) MAXDEPTH (300000) DESCR('兴业银行')

DEFINE QLOCAL (XYTRANS) REPLACE USAGE (XMITQ) DEFPSIST (YES) MAXDEPTH (300000) DESCR('兴业银行')

DEFINE QREMOTE (XYACK) REPLACE DEFPSIST (YES) RQMNAME (SXSEND)  RNAME (XYACK) XMITQ (XYTRANS) DESCR('XXXX')

DEFINE CHANNEL (XYDATA) CHLTYPE (RCVR) TRPTYPE (TCP) REPLACE DESCR('XXXX')

DEFINE CHANNEL (XYACK) CHLTYPE (SDR) CONNAME ('166.1.1.8(2214)') XMITQ (XYTRANS) TRPTYPE (TCP) DISCINT (0) CONVERT (NO) SHORTRTY (30) SHORTTMR (10) LONGRTY (999999999) LONGTMR (20) REPLACE DESCR('XXXX')

DEFINE CHANNEL (SVRCONN) CHLTYPE (SVRCONN) MCAUSER('mqm')

创建监听

DEFINE LISTENER (RECLISTENER) TRPTYPE (TCP) CONTROL(QMGR) PORT (2214)

启动监听

start LISTENER(RECLISTENER)

启动通道

start channel(SVRCONN)

start channel(XYDATA)

start channel(XYACK)

———————————————————————————————————————————————————

四、2035错误码 说明

如果程序连接mq报错2035,则需要对权限认证做设置,则进行以此操作

1、

ALTER QMGR CHLAUTH(DISABLED)

2、

ALTER CHL(通道名) CHLTYPE(SVRCONN) MCAUSER('mqm')

3、

ALTER AUTHINFO(SYSTEM.DEFAULT.AUTHINFO.IDPWOS) AUTHTYPE(IDPWOS) CHCKCLNT(OPTIONAL)

或者直接将连接认证选项置为空,将其完全关闭,指令如下:

ALTER QMGR CONNAUTH('')

在执行完上述两条命令中的任一条后,都需要刷新连接认证的缓存,指令如下:

REFRESH SECURITY TYPE(CONNAUTH)

五、mq操作命令

一、MQ的启动与停止

1、MQ的启动

strmqm QMgrName

如果启动默认队列管理器,strmqm后可以忽略队列管理器名称。

2、MQ的关闭

endmqm -i QMgrName

停止mq

二、MQ运行状态查看与常用操作

1、 查看队列管理器运行状态

su mqm

执行如下命令检查队列管理器运行状态:dspmq显示结果中QMNAME表示MQ队列管理器的名称,STATUS表示当前运行状态。运行状态有如下几种:Starting正在启动Running正在运行Ending正在停止Ended normally已经正常终止Ended immediately已经立即终止Ended preemtively已经强制终止Ended unexpectively异常终止

注意:停止MQ后必须使用dspmq命令进行状态检查

2、查看通道运行状态与启停通道

runmqsc

dis chl(*);查看所有通道定义

dis chs(*);查看所有通道状态,如果没有查询到通道状态,或报错AMQ8420: Channel Status not found,请启动通道

dis chs(ChannelName); 查看通道ChannelName的状态

通道状态有如下几种:

STARTING正在启动BINDING正在绑定INITIALIZING正在初始化RUNNING正常STOPPING 正在停止RETRYING重试PAUSED等待STOPPED已停止REQUESTING请求

start chl(ChannelName);启动通道

stop chl(ChannelName);停止通道

* 重置通道

reset channel(ChannelName); 重置通道序号。当本地与其他MQ队列管理器的通道无法正常启动的情况,检查日志发现是通道序号不一致,此时就需要先停止发送方通道,清空队列深度并在发送方和接收方进行通道计数的重置,重置后启动通道即可恢复通讯。

注意:重置成功mq序列号一般相同或相差1

3、查看通道监听状态与启停监听

runmqsc

dis listner(*);查看通道监听定义

dis lsstatu(listnerName);查看监听状态

start lstr(listnerName); 启动监听

stop lstr(listnerName); 停止监听 

4、查看队列深度

runmqsc

dis q(*);查看所有各类队列的属性

dis qlocal(QName);查看所有本地队列的属性

队列深度属性为:CURDEPTH

查看队列深度display ql('队列名')  curdepth

*清空队列深度

清空队列深度

clear ql(‘队列名’)

三、MQ发送和接收消息

su mqm

发送消息

amqsput  队列名  队列管理器

获取消息

amqsget  队列名  队列管理器

可通过配合查看队列深度命令,完成mq的联调

六、其他维护中常用linux命令

1、测试端口连接

telnet ip port

2、查看已启动的端口

netstat -an | grep 端口号

3、查看应用进程

ps -ef |grep java

4、修改权限

chomd  XXX(对应的权限)  文件目录

5、修改文件或目录下所有文件所有者和组

Chomd -R 用户名:组名  文件目录

6、查看目录内容

ls 或者ls -l (简写ll)

7、查看文件输出

cat 目录/文件名

或者

Vi 目录/文件名 按i可进入编辑

按 G 到文档末尾

按 gg 到文件首行

不保存退出

Esc   :q!

保存退出

Esc   :wq

vi 进入文档文档后查找关键字

Esc 进入命令行

/关键字

按n向下继续查找

按N向上继续查找

8、杀进程

Kill -9 进程号

9、复制

cp -r 源目录  目标目录

10、移动

mv  -i 源文件或目录 目标文件或目录

11、删除

rm -R 文件目录

12、 切换工作目录

cd  相对路径或绝对路径

~也表示为 home 目录 的意思, . 则是表示目前所在的目录, .. 则表示目前目录位置的上一层目录。


标题名称:linux命令lib,linux命令连接oracle数据库
网址分享:http://scyanting.com/article/hsshig.html