0%

前言

现在物联网这么火,当然不能落伍,MQTT极有可能成为物联网应用最广的协议,因此需要一个MQTT测试环境就很有必要了

开发环境

系统: Ubuntu 16.04.3 LTS

代理服务器 :Apache-Apollo-1.7.1

准备工作

1. 安装Java环境

由于搭建Apollo环境变量需要有JAVA_HOME,这个时候需要安装JDK,具体安装参考《Ubuntu安装JDK1.8.0并配置环境变量

2. Apache-Apollo-1.7.1下载及解压

首先是下载Apache-Apollo,下载页面:http://www.apache.org/dyn/closer.cgi?path=activemq/activemq-apollo/1.7.1/apache-apollo-1.7.1-unix-distro.tar.gz

或者输入下面命令:

1
2
3
iotts@jacklu:~$ cd /home/iotts/
iotts@jacklu:~$ mkdir apache-apollo
wget http://mirror.bit.edu.cn/apache/activemq/activemq-apollo/1.7.1/apache-apollo-1.7.1-unix-distro.tar.gz

解压源码包:

1
tar -zxvf apache-apollo-1.7.1-unix-distro.tar.gz

配置

进入apache-apollo-1.7.1/bin目录

1
cd apache-apollo-1.7.1/bin/

输入./apollo可以查看帮助
1
2
3
4
5
6
7
8
9
10
iotts@jacklu:~/apache-apollo/apache-apollo-1.7.1/bin$ ./apollo
usage: apollo [--log <log_level>] <command> [<args>]

The most commonly used apollo commands are:
create creates a new broker instance
disk-benchmark Benchmarks your disk's speed
help Display help information
version Displays the broker version

See 'apollo help <command>' for more information on a specific command.

创建MQTT服务器

创建一个Broker示例:./apollo create iotts_broker。执行后就会在bin目录下创建 iotts_broker文件夹。(MQTT服务器都是叫Broker)

1
2
3
4
5
6
7
8
9
10
11
12
iotts@jacklu:~/apache-apollo/apache-apollo-1.7.1/bin$ ./apollo create iotts_broker
Creating apollo instance at: iotts_broker
Generating ssl keystore...

You can now start the broker by executing:

"/home/iotts/apache-apollo/apache-apollo-1.7.1/bin/iotts_broker/bin/apollo-broker" run

Or you can setup the broker as system service and run it in the background:

sudo ln -s "/home/iotts/apache-apollo/apache-apollo-1.7.1/bin/iotts_broker/bin/apollo-broker-service" /etc/init.d/
/etc/init.d/apollo-broker-service start

后面会有提示怎么启动服务器,以及创建一个service。

启动Apollo :

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
iotts@jacklu:~/apache-apollo/apache-apollo-1.7.1/bin$ iotts_broker/bin/apollo-broker run

_____ .__ .__
/ _ \ ______ ____ | | | | ____
/ /_\ \\____ \ / _ \| | | | / _ \
/ | \ |_> > <_> ) |_| |_( <_> )
\____|__ / __/ \____/|____/____/\____/
\/|__| Apache Apollo (1.7.1)


Loading configuration file '/home/iotts/apache-apollo/apache-apollo-1.7.1/bin/iotts_broker/etc/apollo.xml'.
INFO | OS : Linux 4.10.0-42-generic (Ubuntu 16.04.3 LTS)
INFO | JVM : Java HotSpot(TM) Server VM 1.8.0_151 (Oracle Corporation)
INFO | Apollo : 1.7.1 (at: /home/iotts/apache-apollo/apache-apollo-1.7.1)
INFO | OS is restricting the open file limit to: 100000
INFO | Accepting connections at: tcp://0.0.0.0:61613
INFO | Accepting connections at: tls://0.0.0.0:61614
INFO | Starting store: leveldb store at /home/iotts/apache-apollo/apache-apollo-1.7.1/bin/iotts_broker/data
INFO | Accepting connections at: ws://0.0.0.0:61623/
INFO | Accepting connections at: wss://0.0.0.0:61624/
INFO | virtual host startup is waiting on store startup
INFO | virtual host startup is no longer waiting. It waited a total of 1 seconds.
INFO | broker startup is waiting on start jetty webserver
INFO | Administration interface available at: https://127.0.0.1:61681/
INFO | Administration interface available at: http://127.0.0.1:61680/
INFO | broker startup is no longer waiting. It waited a total of 7 seconds.

查看打印信息即可知道MQTT要连接的端口和管理页面端口。

然后打开浏览器上,输入 http://127.0.0.1:61680/https://127.0.0.1:61681/
即可进入 Apollo Console 窗口。
微信截图_20180111233348.png

默认的登录id和密码是 admin 和 password
微信截图_20180111233514.png

开发环境

虚拟机 Ubuntu 16.04.3 LTS

JDK安装

通过终端在/usr/local目录下新建java文件夹,命令行:

1
sudo mkdir /usr/local/java

然后进入java目录,命令行:
1
cd /usr/local/java

到官网下载jdk,现在现在的话需要首先注册一下账号:
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html

不想注册的话可以在我的网盘下载

链接:https://pan.baidu.com/s/1AsQhDn8aAR_IvcaR0N1Miw
提取码:k9k2

下载源码包

解压源码包

解压压缩包,命令行:

1
sudo tar xvf jdk-8u151-linux-i586.tar.gz

然后可以把压缩包删除,命令行:

1
sudo rm jdk-8u151-linux-i586.tar.gz

设置JDK环境变量

这里采用全局设置方法,它是是所有用户的共用的环境变量

1
$sudo gedit ~/.bashrc

命令行下可以输入
1
vi ~/.bashrc

在.bashrc文件末尾输入
1
2
3
4
export JAVA_HOME=/usr/local/java/jdk1.8.0_151  
export JRE_HOME=${JAVA_HOME}/jre
export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib
export PATH=${JAVA_HOME}/bin:$PATH

$\color{red}{注意:}$在添加环境变量时中,等号两侧不要加入空格,不然会出现“不是有效的标识符”,因为source /etc/profile 时不能识别多余到空格,会理解为是路径一部分。然后保存。
命令行下输入以下命令生效
1
source ~/.bashrc

检验是否安装成功

重启终端,然后在终端输入如下命令

1
java -version

看看是否安装成功,成功则显示如下:
1
2
3
4
5
iotts@jacklu:~$ java -version
java version "1.8.0_151"
Java(TM) SE Runtime Environment (build 1.8.0_151-b12)
Java HotSpot(TM) Client VM (build 25.151-b12, mixed mode)
iotts@jacklu:~$

1.创建数据库

在MySql数据库中创建一个名为Sensor_server的数据库,如下图:
微信截图_20180111003012.png
在数据库中创建一个名为sensor_test的数据表,使用如下SQL语句:

1
2
3
4
5
6
7
8
9
10
11
12
13
CREATE TABLE IF NOT EXISTS `sensor_test` (
`id` int(11) NOT NULL,
`sen_id` int(11) NOT NULL,
`temp` int(11) NOT NULL,
`humi` int(11) NOT NULL,
`pm25` int(11) NOT NULL,
`pm10` int(11) NOT NULL,
`pm100` int(11) NOT NULL,
`co2` int(11) NOT NULL,
`ze08` int(11) NOT NULL,
`tvoc` int(11) NOT NULL,
`timeStamp` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
) ENGINE=MyISAM DEFAULT CHARSET=utf8mb4;

微信截图_20180111001007.png

2.创建PHP文件

2.1 创建数据库连接PHP文件

创建名为database.php 的文件,写入以下代码:

1
2
3
4
5
6
<?php
$connect=mysqli_connect('localhost','用户名(最好不用root)','数据库密码','sensor_server');

if(mysqli_connect_errno($connect)) printf("Failed to connect");
else printf("Success to Connect\r\n");
?>

2.2 创建数据库操作PHP文件

创建名为process.php 的文件,写入以下代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
<?php
header("Content-type:text/html;charset=utf-8");
date_default_timezone_set("Asia/Shanghai");
echo "当前时间是 " . date("H:i:s")."<br>";
include("database.php");
$sen_id=$_POST['sen_id'];
$pm25=$_POST['pm25'];
$pm10=$_POST['pm10'];
$co2=$_POST['co2'];
$tvoc=$_POST['tvoc'];
$pm100=$_POST['pm100'];
$ze08=$_POST['ze08'];
$temp=$_POST['temp'];
$humi=$_POST['humi'];
$id=$_POST['id'];
print_r($_POST);
mysqli_query($connect,"INSERT INTO sensor_test(pm25,pm10,pm100,co2,tvoc,temp,humi,ze08,id,sen_id) VALUES('$pm25','$pm10','$pm100','$co2','$tvoc','$temp','$humi','$ze08','$id','$sen_id')");

mysqli_close($connect);
?>

原文链接
注:以下全部代码的执行环境为VC++ 6.0

在程序中,可能需要为某些整数定义一个别名,我们可以利用预处理指令#define来完成这项工作,您的代码可能是:

1
2
3
4
5
6
7
#define MON  1
#define TUE 2
#define WED 3
#define THU 4
#define FRI 5
#define SAT 6
#define SUN 7

在此,我们定义一种新的数据类型,希望它能完成同样的工作。这种新的数据类型叫枚举型。

1. 定义一种新的数据类型 - 枚举型

以下代码定义了这种新的数据类型 - 枚举型

1
2
3
4
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};

(1) 枚举型是一个集合,集合中的元素(枚举成员)是一些命名的整型常量,元素之间用逗号,隔开。

(2) DAY是一个标识符,可以看成这个集合的名字,是一个可选项,即是可有可无的项。

(3) 第一个枚举成员的默认值为整型的0,后续枚举成员的值在前一个成员上加1。

(4) 可以人为设定枚举成员的值,从而自定义某个范围内的整数。

(5) 枚举型是预处理指令#define的替代。

(6) 类型定义以分号;结束。

2. 使用枚举类型对变量进行声明

新的数据类型定义完成后,它就可以使用了。我们已经见过最基本的数据类型,如:整型int, 单精度浮点型float, 双精度浮点型double, 字符型char, 短整型short等等。用这些基本数据类型声明变量通常是这样:

1
2
3
4
5
6
7
8
char     a; //变量a的类型均为字符型char
char letter;
int x,
y,
z; //变量x,y和z的类型均为整型int
int number;
double m, n;
double result; //变量result的类型为双精度浮点型double

既然枚举也是一种数据类型,那么它和基本数据类型一样也可以对变量进行声明。

方法一:枚举类型的定义和变量的声明分开

1
2
3
4
enum DAY
{
MON=1, TUE, WED, THU, FRI, SAT, SUN
};
1
2
3
4
enum DAY yesterday;
enum DAY today;
enum DAY tomorrow; //变量tomorrow的类型为枚举型enum DAY
enum DAY good_day, bad_day; //变量good_day和bad_day的类型均为枚举型enum DAY

方法二:类型定义与变量声明同时进行:

1
2
3
4
5
6
7
8
9
10
enum //跟第一个定义不同的是,此处的标号DAY省略,这是允许的。
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
} workday; //变量workday的类型为枚举型enum DAY
1
enum week { Mon=1, Tue, Wed, Thu, Fri Sat, Sun} days; //变量days的类型为枚举型enum week
1
enum BOOLEAN { false, true } end_flag, match_flag; //定义枚举类型并声明了两个枚举型变量

方法三:用typedef关键字将枚举类型定义成别名,并利用该别名进行变量声明:

1
2
3
4
5
6
7
8
9
10
typedef enum workday
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
} workday; //此处的workday为枚举型enum workday的别名
1
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday

enum workday中的workday可以省略:

1
2
3
4
5
6
7
8
9
10
typedef enum
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
} workday; //此处的workday为枚举型enum workday的别名
1
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday

也可以用这种方式:

1
2
3
4
5
6
7
8
9
10
typedef enum workday
{
saturday,
sunday = 0,
monday,
tuesday,
wednesday,
thursday,
friday
};
1
workday today, tomorrow; //变量today和tomorrow的类型为枚举型workday,也即enum workday

注意:同一个程序中不能定义同名的枚举类型,不同的枚举类型中也不能存在同名的命名常量。错误示例如下所示:

$\color{red}{错误声明一:}$存在同名的枚举类型

1
2
3
4
5
6
typedef enum
{
wednesday,
thursday,
friday
} workday;
1
2
3
4
5
6
typedef enum WEEK
{
saturday,
sunday = 0,
monday,
} workday;

$\color{red}{错误声明二:}$存在同名的枚举成员

1
2
3
4
5
6
7
8
9
10
11
12
13
typedef enum
{
wednesday,
thursday,
friday
} workday_1;

typedef enum WEEK
{
wednesday,
sunday = 0,
monday,
} workday_2;

3.使用枚举类型的变量

3.1 对枚举型的变量赋值。

实例将枚举类型的赋值与基本数据类型的赋值进行了对比:

方法一:先声明变量,再对变量赋值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include<stdio.h>

/* 定义枚举类型 */
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };

void main()
{
/* 使用基本数据类型声明变量,然后对变量赋值 */
int x, y, z;

x = 10;
y = 20;
z = 30;

/* 使用枚举类型声明变量,再对枚举型变量赋值 */
enum DAY yesterday, today, tomorrow;

yesterday = MON;
today = TUE;
tomorrow = WED;

printf("%d %d %d \n", yesterday, today, tomorrow);
}

方法二:声明变量的同时赋初值

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <stdio.h>

/* 定义枚举类型 */
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };

void main()
{
/* 使用基本数据类型声明变量同时对变量赋初值 */
int x=10, y=20, z=30;

/* 使用枚举类型声明变量同时对枚举型变量赋初值 */
enum DAY yesterday = MON,
today = TUE,
tomorrow = WED;

printf("%d %d %d \n", yesterday, today, tomorrow);
}

方法三:定义类型的同时声明变量,然后对变量赋值。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>

/* 定义枚举类型,同时声明该类型的三个变量,它们都为全局变量 */
enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN } yesterday, today, tomorrow;

/* 定义三个具有基本数据类型的变量,它们都为全局变量 */
int x, y, z;

void main()
{
/* 对基本数据类型的变量赋值 */
x = 10; y = 20; z = 30;

/* 对枚举型的变量赋值 */
yesterday = MON;
today = TUE;
tomorrow = WED;

printf("%d %d %d \n", x, y, z); //输出:10 20 30
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:1 2 3
}

方法四:类型定义,变量声明,赋初值同时进行。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <stdio.h>

/* 定义枚举类型,同时声明该类型的三个变量,并赋初值。它们都为全局变量 */
enum DAY
{
MON=1,
TUE,
WED,
THU,
FRI,
SAT,
SUN
}
yesterday = MON, today = TUE, tomorrow = WED;

/* 定义三个具有基本数据类型的变量,并赋初值。它们都为全局变量 */
int x = 10, y = 20, z = 30;

void main()
{
printf("%d %d %d \n", x, y, z); //输出:10 20 30
printf("%d %d %d \n", yesterday, today, tomorrow); //输出:1 2 3
}

3.2 对枚举型的变量赋整数值时,需要进行类型转换。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include <stdio.h>

enum DAY { MON=1, TUE, WED, THU, FRI, SAT, SUN };

void main()
{
enum DAY yesterday, today, tomorrow;

yesterday = TUE;
today = (enum DAY) (yesterday + 1); //类型转换
tomorrow = (enum DAY) 30; //类型转换
//tomorrow = 3; //错误

printf("%d %d %d \n", yesterday, today, tomorrow); //输出:2 3 30
}

3.3 使用枚举型变量

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include<stdio.h>

enum
{
BELL = '\a',
BACKSPACE = '\b',
HTAB = '\t',
RETURN = '\r',
NEWLINE = '\n',
VTAB = '\v',
SPACE = ' '
};

enum BOOLEAN { FALSE = 0, TRUE } match_flag;

void main()
{
int index = 0;
int count_of_letter = 0;
int count_of_space = 0;

char str[] = "I'm Ely efod";

match_flag = FALSE;

for(; str[index] != '\0'; index++)
if( SPACE != str[index] )
count_of_letter++;
else
{
match_flag = (enum BOOLEAN) 1;
count_of_space++;
}

printf("%s %d times %c", match_flag ? "match" : "not match", count_of_space, NEWLINE);
printf("count of letters: %d %c%c", count_of_letter, NEWLINE, RETURN);
}

输出:

1
2
3
match 2 times
count of letters: 10
Press any key to continue

4. 枚举类型与sizeof运算符

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
#include <stdio.h>

enum escapes
{
BELL = '\a',
BACKSPACE = '\b',
HTAB = '\t',
RETURN = '\r',
NEWLINE = '\n',
VTAB = '\v',
SPACE = ' '
};

enum BOOLEAN { FALSE = 0, TRUE } match_flag;

void main()
{
printf("%d bytes \n", sizeof(enum escapes)); //4 bytes
printf("%d bytes \n", sizeof(escapes)); //4 bytes

printf("%d bytes \n", sizeof(enum BOOLEAN)); //4 bytes
printf("%d bytes \n", sizeof(BOOLEAN)); //4 bytes
printf("%d bytes \n", sizeof(match_flag)); //4 bytes

printf("%d bytes \n", sizeof(SPACE)); //4 bytes
printf("%d bytes \n", sizeof(NEWLINE)); //4 bytes
printf("%d bytes \n", sizeof(FALSE)); //4 bytes
printf("%d bytes \n", sizeof(0)); //4 bytes
}

5. 综合举例

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
#include<stdio.h>

enum Season
{
spring, summer=100, fall=96, winter
};

typedef enum
{
Monday, Tuesday, Wednesday, Thursday, Friday, Saturday, Sunday
}
Weekday;

void main()
{
/* Season */
printf("%d \n", spring); // 0
printf("%d, %c \n", summer, summer); // 100, d
printf("%d \n", fall+winter); // 193

Season mySeason=winter;
if(winter==mySeason)
printf("mySeason is winter \n"); // mySeason is winter

int x=100;
if(x==summer)
printf("x is equal to summer\n"); // x is equal to summer

printf("%d bytes\n", sizeof(spring)); // 4 bytes

/* Weekday */
printf("sizeof Weekday is: %d \n", sizeof(Weekday)); //sizeof Weekday is: 4

Weekday today = Saturday;
Weekday tomorrow;
if(today == Monday)
tomorrow = Tuesday;
else
tomorrow = (Weekday) (today + 1); //remember to convert from int to Weekday
}

ubuntu关机和重启命令

linux下常用的关机命令有:shutdown、halt、poweroff、init;重启命令有:reboot。下面本文就主要介绍一些常用的关机命令以及各种关机命令之间的区别和具体用法。

阅读全文 »

Linux下的压缩解压缩命令详解及实例

实例:压缩服务器上当前目录的内容为xxx.zip文件

1
zip -r xxx.zip ./*

解压zip文件到当前目录
1
unzip filename.zip

另:有些服务器没有安装zip包执行不了zip命令,但基本上都可以用tar命令的,实例如下:

1
tar -zcvf /home/zdzlibs.tar.gz /home/zdz/java/zdzlibs/

linux zip命令

zip -r myfile.zip ./*
将当前目录下的所有文件和文件夹全部压缩成myfile.zip文件,-r表示递归压缩子目录下所有文件.

2.unzip
unzip -o -d /home/sunny myfile.zip
把myfile.zip文件解压到 /home/sunny/
-o:不提示的情况下覆盖文件;
-d:-d /home/sunny 指明将文件解压缩到/home/sunny目录下;

3.其他
zip -d myfile.zip smart.txt
删除压缩文件中smart.txt文件
zip -m myfile.zip ./rpm_info.txt

向压缩文件中myfile.zip中添加rpm_info.txt文件

要使用 zip 来压缩文件,在 shell 提示下键入下面的命令:

zip -r filename.zip filesdir

在这个例子里,filename.zip 代表你创建的文件,filesdir 代表你想放置新 zip 文件的目录。-r 选项指定你想递归地(recursively)包括所有包括在 filesdir 目录中的文件。

要抽取 zip 文件的内容,键入以下命令:

unzip filename.zip

你可以使用 zip 命令同时处理多个文件和目录,方法是将它们逐一列出,并用空格间隔:

zip -r filename.zip file1 file2 file3 /usr/work/school

上面的命令把 file1、file2、 file3、以及 /usr/work/school 目录的内容(假设这个目录存在)压缩起来,然后放入 filename.zip 文件中。

tar 命令详解

  -c: 建立压缩档案

  -x:解压

  -t:查看内容

  -r:向压缩归档文件末尾追加文件

  -u:更新原压缩包中的文件

  这五个是独立的命令,压缩解压都要用到其中一个,可以和别的命令连用但只能用其中一个。下面的参数是根据需要在压缩或解压档案时可选的。

  -c: 建立压缩档案

  -x:解压

  -t:查看内容

  -r:向压缩归档文件末尾追加文件

  -u:更新原压缩包中的文件

  下面的参数-f是必须的

  -f: 使用档案名字,切记,这个参数是最后一个参数,后面只能接档案名。

  # tar -cf all.tar *.jpg

  这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。

  # tar -rf all.tar *.gif

  这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。

  # tar -uf all.tar logo.gif

  这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。

  # tar -tf all.tar

  这条命令是列出all.tar包中所有文件,-t是列出文件的意思

  # tar -xf all.tar

  这条命令是解出all.tar包中所有文件,-t是解开的意思

  压缩

  tar –cvf jpg.tar *.jpg //将目录里所有jpg文件打包成tar.jpg

  tar –czf jpg.tar.gz *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用gzip压缩,生成一个gzip压缩过的包,命名为jpg.tar.gz

  tar –cjf jpg.tar.bz2 *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用bzip2压缩,生成一个bzip2压缩过的包,命名为jpg.tar.bz2

  tar –cZf jpg.tar.Z *.jpg //将目录里所有jpg文件打包成jpg.tar后,并且将其用compress压缩,生成一个umcompress压缩过的包,命名为jpg.tar.Z

  rar a jpg.rar *.jpg //rar格式的压缩,需要先下载rar for linux

  zip jpg.zip *.jpg //zip格式的压缩,需要先下载zip for linux

  解压

  tar –xvf file.tar //解压 tar包

  tar -xzvf file.tar.gz //解压tar.gz

  tar -xjvf file.tar.bz2 //解压 tar.bz2

  tar –xZvf file.tar.Z //解压tar.Z

  unrar e file.rar //解压rar

  unzip file.zip //解压zip

  总结

  1、*.tar 用 tar –xvf 解压

  2、*.gz 用 gzip -d或者gunzip 解压

  3、.tar.gz和.tgz 用 tar –xzf 解压

  4、*.bz2 用 bzip2 -d或者用bunzip2 解压

  5、*.tar.bz2用tar –xjf 解压

  6、*.Z 用 uncompress 解压

  7、*.tar.Z 用tar –xZf 解压

  8、*.rar 用 unrar e解压

  9、*.zip 用 unzip 解压

  Linux中tar命令详解(转载的资料)

  2008年04月17日 星期四 15:37

  tar命令

  tar 可以为文件和目录创建档案。利用tar,用户可以为某一特定文件创建档案(备份文件),也可以在档案中改变文件,或者向档案中加入新的文件。tar最初被 用来在磁带上创建档案,现在,用户可以在任何设备上创建档案,如软盘。利用tar命令,可以把一大堆的文件和目录全部打包成一个文件,这对于备份文件或将 几个文件组合成为一个文件以便于网络传输是非常有用的。Linux上的tar是GNU版本的。

  语法:tar [主选项+辅选项] 文件或者目录

  使用该命令时,主选项是必须要有的,它告诉tar要做什么事情,辅选项是辅助使用的,可以选用。

  主选项:

  c 创建新的档案文件。如果用户想备份一个目录或是一些文件,就要选择这个选项。

  r 把要存档的文件追加到档案文件的未尾。例如用户已经作好备份文件,又发现还有一个目录或是一些文件忘记备份了,这时可以使用该选项,将忘记的目录或文件追加到备份文件中。

  t 列出档案文件的内容,查看已经备份了哪些文件。

  u 更新文件。就是说,用新增的文件取代原备份文件,如果在备份文件中找不到要更新的文件,则把它追加到备份文件的最后。

  x 从档案文件中释放文件。

  辅助选项:

  b 该选项是为磁带机设定的。其后跟一数字,用来说明区块的大小,系统预设值为20(20*512 bytes)。

  f 使用档案文件或设备,这个选项通常是必选的。

  k 保存已经存在的文件。例如我们把某个文件还原,在还原的过程中,遇到相同的文件,不会进行覆盖。

  m 在还原文件时,把所有文件的修改时间设定为现在。

  M 创建多卷的档案文件,以便在几个磁盘中存放。

  v 详细报告tar处理的文件信息。如无此选项,tar不报告文件信息。

  w 每一步都要求确认。

  z 用gzip来压缩/解压缩文件,加上该选项后可以将档案文件进行压缩,但还原时也一定要使用该选项进行解压缩。

  Linux下的压缩文件剖析

  对于刚刚接触Linux的人来说,一定会给Linux下一大堆各式各样的文件名给搞晕。别个不说,单单就压缩文件为例,我们知道在Windows下最常见 的压缩文件就只有两种,一是,zip,另一个是.rap。可是Linux就不同了,它有.gz、.tar.gz、tgz、bz2、.Z、.tar等众多的 压缩文件名,此外windows下的.zip和.rar也可以在Linux下使用,不过在Linux使用.zip和.rar的人就太少了。本文就来对这些 常见的压缩文件进行一番小结,希望你下次遇到这些文件时不至于被搞晕。

  在具体总结各类压缩文件之前呢,首先要弄清两个概念:打包和压缩。打包是指将一大堆文件或目录什么的变成一个总的文件,压缩则是将一个大的文件通过一些压 缩算法变成一个小文件。为什么要区分这两个概念呢?其实这源于Linux中的很多压缩程序只能针对一个文件进行压缩,这样当你想要压缩一大堆文件时,你就 得先借助另它的工具将这一大堆文件先打成一个包,然后再就原来的压缩程序进行压缩。

  Linux下最常用的打包程序就是tar了,使用tar程序打出来的包我们常称为tar包,tar包文件的命令通常都是以.tar结尾的。生成tar包后,就可以用其它的程序来进行压缩了,所以首先就来讲讲tar命令的基本用法:

  tar命令的选项有很多(用man tar可以查看到),但常用的就那么几个选项,下面来举例说明一下:

  # tar -cf all.tar *.jpg

  这条命令是将所有.jpg的文件打成一个名为all.tar的包。-c是表示产生新的包,-f指定包的文件名。

  # tar -rf all.tar *.gif

  这条命令是将所有.gif的文件增加到all.tar的包里面去。-r是表示增加文件的意思。

  # tar -uf all.tar logo.gif

  这条命令是更新原来tar包all.tar中logo.gif文件,-u是表示更新文件的意思。

  # tar -tf all.tar

  这条命令是列出all.tar包中所有文件,-t是列出文件的意思

  # tar -xf all.tar

  这条命令是解出all.tar包中所有文件,-t是解开的意思

  以上就是tar的最基本的用法。为了方便用户在打包解包的同时可以压缩或解压文件,tar提供了一种特殊的功能。这就是tar可以在打包或解包的同时调用其它的压缩程序,比如调用gzip、bzip2等。

  1) tar调用gzip

  gzip是GNU组织开发的一个压缩程序,.gz结尾的文件就是gzip压缩的结果。与gzip相对的解压程序是gunzip。tar中使用-z这个参数来调用gzip。下面来举例说明一下:

  # tar -czf all.tar.gz *.jpg

  这条命令是将所有.jpg的文件打成一个tar包,并且将其用gzip压缩,生成一个gzip压缩过的包,包名为all.tar.gz

  # tar -xzf all.tar.gz

  这条命令是将上面产生的包解开。

  2) tar调用bzip2

  bzip2是一个压缩能力更强的压缩程序,.bz2结尾的文件就是bzip2压缩的结果。与bzip2相对的解压程序是bunzip2。tar中使用-j这个参数来调用gzip。下面来举例说明一下:

  # tar -cjf all.tar.bz2 *.jpg

  这条命令是将所有.jpg的文件打成一个tar包,并且将其用bzip2压缩,生成一个bzip2压缩过的包,包名为all.tar.bz2

  # tar -xjf all.tar.bz2

  这条命令是将上面产生的包解开。

  3)tar调用compress

  compress也是一个压缩程序,但是好象使用compress的人不如gzip和bzip2的人多。.Z结尾的文件就是bzip2压缩的结果。与 compress相对的解压程序是uncompress。tar中使用-Z这个参数来调用gzip。下面来举例说明一下:

  # tar -cZf all.tar.Z *.jpg

  这条命令是将所有.jpg的文件打成一个tar包,并且将其用compress压缩,生成一个uncompress压缩过的包,包名为all.tar.Z

  # tar -xZf all.tar.Z

  这条命令是将上面产生的包解开

  有了上面的知识,你应该可以解开多种压缩文件了,下面对于tar系列的压缩文件作一个小结:

  1)对于.tar结尾的文件

  tar -xf all.tar

  2)对于.gz结尾的文件

  gzip -d all.gz

  gunzip all.gz

  3)对于.tgz或.tar.gz结尾的文件

  tar -xzf all.tar.gz

  tar -xzf all.tgz

  4)对于.bz2结尾的文件

  bzip2 -d all.bz2

  bunzip2 all.bz2

  5)对于tar.bz2结尾的文件

  tar -xjf all.tar.bz2

  6)对于.Z结尾的文件

  uncompress all.Z

  7)对于.tar.Z结尾的文件

  tar -xZf all.tar.z

  另外对于Window下的常见压缩文件.zip和.rar,Linux也有相应的方法来解压它们:

  1)对于.zip

  linux下提供了zip和unzip程序,zip是压缩程序,unzip是解压程序。它们的参数选项很多,这里只做简单介绍,依旧举例说明一下其用法:

  # zip all.zip *.jpg

  这条命令是将所有.jpg的文件压缩成一个zip包

  # unzip all.zip

  这条命令是将all.zip中的所有文件解压出来

  2)对于.rar

  要在linux下处理.rar文件,需要安装RAR for Linux,可以从网上下载,但要记住,RAR for Linux

  不是免费的;然后安装:

  # tar -xzpvf rarlinux-3.2.0.tar.gz

  # cd rar

  # make

  这样就安装好了,安装后就有了rar和unrar这两个程序,rar是压缩程序,unrar是解压程序。它们的参数选项很多,这里只做简单介绍,依旧举例说明一下其用法:

  # rar a all *.jpg

  这条命令是将所有.jpg的文件压缩成一个rar包,名为all.rar,该程序会将.rar 扩展名将自动附加到包名后。

  # unrar e all.rar

  这条命令是将all.rar中的所有文件解压出来

  到此为至,我们已经介绍过linux下的tar、gzip、gunzip、bzip2、bunzip2、compress、uncompress、 zip、unzip、rar、unrar等程式,你应该已经能够使用它们对.tar、.gz、.tar.gz、.tgz、.bz2、.tar.bz2、. Z、.tar.Z、.zip、.rar这10种压缩文件进行解压了,以后应该不需要为下载了一个软件而不知道如何在Linux下解开而烦恼了。而且以上方 法对于Unix也基本有效。

  本文介绍了linux下的压缩程式tar、gzip、gunzip、bzip2、bunzip2、 compress、uncompress、zip、unzip、rar、unrar等程式,以及如何使用它们对.tar、.gz、.tar.gz、. tgz、.bz2、.tar.bz2、.Z、.tar.Z、.zip、.rar这10种压缩文件进行操作

要查看Ubuntu操作系统的位数是32位还是64位,可以通过以下命令来查看:

查看long的位数,返回32或64

可以在终端terminal下输入命令:

1
getconf LONG_BIT

输出结果
1
32

2018-01-16 20-46-51屏幕截图.png
也可以输入:
1
uname -a

输出结果:
1
Linux jacklu 4.13.0-26-generic #29~16.04.2-Ubuntu SMP Tue Jan 9 21:38:24 UTC 2018 i686 i686 i686 GNU/Linux

2018-01-16 20-47-17屏幕截图.png

查看Ubuntu版本:

方法一

在终端中执行下列指令:

1
cat /etc/issue

可以查看当前正在运行的 Ubuntu 的版本号。其输出结果类似下面的内容:
1
Ubuntu 16.04.3 LTS \n \l

2018-01-16 20-48-47屏幕截图.png

方法二

使用 lsb_release 命令也可以查看 Ubuntu 的版本号,与方法一相比,内容更为详细。执行指令如下:

1
sudo lsb_release -a

将输出结果:
1
2
3
4
5
No LSB modules are available.
Distributor ID: Ubuntu
Description: Ubuntu 16.04.3 LTS
Release: 16.04
Codename: xenial

2018-01-16 20-48-27屏幕截图.png

原文链接
1.首先确认服务器出于安全的状态,也就是没有人能够任意地连接MySQL数据库。
因为在重新设置MySQL的root密码的期间,MySQL数据库完全出于没有密码保护的
状态下,其他的用户也可以任意地登录和修改MySQL的信息。可以采用将MySQL对
外的端口封闭,并且停止Apache以及所有的用户进程的方法实现服务器的准安全
状态。最安全的状态是到服务器的Console上面操作,并且拔掉网线。

2.修改MySQL的登录设置:

1
# vim /etc/my.cnf 

[mysqld]的段中加上一句:
1
skip-grant-tables 

例如:
1
2
3
4
[mysqld] 
datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock
skip-grant-tables

保存并且退出vi。

3.重新启动mysqld

1
2
3
# service mysqld restart 
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]

4.登录并修改MySQL的root密码
1
2
3
4
5
6
7
8
9
10
11
12
# mysql 
Welcome to the MySQL monitor. Commands end with ; or \g.
Your MySQL connection id is 3 to server version: 3.23.56
Type 'help;' or '\h' for help. Type '\c' to clear the buffer.
mysql> USE mysql ;
Database changed
mysql> UPDATE user SET Password = password ( 'new-password' ) WHERE User = 'root' ;
Query OK, 0 rows affected (0.00 sec)
Rows matched: 2 Changed: 0 Warnings: 0
mysql> flush privileges ;
Query OK, 0 rows affected (0.01 sec)
mysql> quit

5.将MySQL的登录设置修改回来
1
# vim /etc/my.cnf 

将刚才在[mysqld]的段中加上的skip-grant-tables删除
保存并且退出vim

6.重新启动mysqld

1
2
3
# service mysqld restart 
Stopping MySQL: [ OK ]
Starting MySQL: [ OK ]

今天在写一篇博客的时候,遇到使用MathJax公式下标出现问题,然后在网上找到解决办法

出现问题的原因

hexo默认使用hexo-renderer-marked引擎去渲染网页,它会把利用Markdown语法写的文本去转换为相应的html标签。在利用Markdown写MathJax公式的时候,经常会用到下划线_表示下标,但是下划线_会被hexo的默认引擎hexo-renderer-marked渲染成html中的<em>标签,表示斜体,这样一来,我们写的MathJax公式就被错误渲染了,也就没办法正确显示出来。

解决方法

从上面的分析,我们可以知道问题或许出在hexo的渲染引擎上,如果渲染引擎不把公式中的一些特殊字符渲染成html标签,也就避免了这个问题。当然已经有人意识到了这个问题,并且对原先的渲染引擎进行了改进,生成了新的hexo-renderer-kramed引擎,这里是它的Github页面,所以我们只需要卸载默认引擎,并安装这个新的渲染引擎即可。

1
2
npm uninstall hexo-renderer-marked --save
npm install hexo-renderer-kramed --save

当我把渲染引擎更换之后,发现大部分公式都正确渲染了,而从网上其他人的叙述中,也同样提到了这个问题,即是行间公式都没有问题,但是个别行内公式还会出现渲染出错,从网上找到了一个方法,解决了这一问题。
定位到你的博客根目录,找到../node_modules/kramed/lib/rules/inline.js文件,
进行部分修改:

1
2
3
4
//escape: /^\\([\\`*{}\[\]()#$+\-.!_>])/,      第11行,将其修改为
escape: /^\\([`*\[\]()#$+\-.!_>])/,
//em: /^\b_((?:__|[\s\S])+?)_\b|^\*((?:\*\*|[\s\S])+?)\*(?!\*)/, 第20行,将其修改为
em: /^\*((?:\*\*|[\s\S])+?)\*(?!\*)/,

它取消了该渲染引擎对 \,{,} 的转义,然后再
1
2
hexo clean
hexo g

重新部署,即可解决问题。

另外需要注意一点,对于需要用到MathJax公式的文章,要在Front-matter中打开MathJax开关,例如:

1
2
3
4
5
6
---
date: 2017/8/3 18:20:00
tags: hexo
mathjax: true
title: hexo博客MathJax公式渲染
---

MathJax公式语法

LaTeX语法
下面呢,我整理总结了一番比较常用的MathJax公式语法,同时也可以用来测试一下渲染效果。

>添加公式的方法

1.行内公式

$行内公式$

2.行间公式

$$行间公式$$

>常用的MathJax公式语法

符号 释义 测试用例 最终效果
^{} 上标 x^{y^z}=(1+e^x)^{-2xy^w} $x^{y^z}=(1+e^x)^{-2xy^w}$
_{} 下标 CO_2 $CO_2$
\frac{分子}{分母} or 分子 \over 分母 分数 f(x,y,z)=3y^2z(3+\frac{7x+5}{1+y^2}) $f(x,y,z)=3y^2z(3+\frac{7x+5}{1+y^2})$
\sqrt[根指数,省略时为2]{被开方数} 开方 \sqrt{2}、\sqrt[3]{9} $\sqrt{2}$ $\sqrt[3]{9}$
\ldots 与文本底线对齐的省略号 x_1x_2{\ldots}x_n $x_1x_2{\ldots}x_n$
\cdots 与文本中线对齐的省略号 x_1x_2{\cdots}x_n $x_1x_2{\cdots}x_n$
\int_积分下限^积分上限(被积表达式) 积分 \int_1^n{x^2}dx $\int_1^n{x^2}dx$
\sum_{下标表达式}^{上标表达式} {累加表达式} 累加 \sum_{i=1}^n \frac{1}{i^2} $\sum_{i=1}^n \frac{1}{i^2}$
\, or ; or \quad or \qquad 不同宽度的空格 a , b \mid a ; b \mid a \quad b \mid a $\qquad b a,b∣a;b∣ab∣aba,b∣a;b∣ab∣ab$
\color{颜色}{文字} 更改文字颜色 \color{red}{红色} $\color{red}{红色}$

上面的一些基本语法使用了行内公式, 渲染效果没有问题,下面再利用行间公式写一些较为复杂的公式。

分段函数

分段函数格式为

1
f(x)=\begin{cases}语句1\\语句2\\...\end{cases}

\text{文字}中仍可以使用$公式$去插入其他公式,所以可以将其结合分段函数一起使用。

实例:
md文本

1
2
3
4
5
6
 $$ 
f(n)=\begin{cases}
n/2, & \text{如果$ x<=2 $}\\
3n+1, & \text{如果$ x>2 $}
\end{cases}
$$

最终效果:

大括号和小括号

()、[]、{}表示的即是符号本身,使用{}来表示{}。但是如果要显示大号的括号时,需要使用\left和\right命令。

实例:

正常括号
md文本

1
2
3
 $$
f([\frac{1+\{x,y\}}{(\frac{x}{y}+\frac{y}{x})(u+1)}+a]^{3\2})
$$

最终效果

大括号
md文本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    $$
f\left(
\left[
\frac{
1+\left\{x,y\right\}
}{
\left(
\frac{x}{y}+\frac{y}{x}
\right)
\left(u+1\right)
}+a
\right]^{3\2}
\right)
$$

最终效果

添加删除线

使用删除线功能必须使用行间公式,删除线分为片段删除线和整段删除线,样式比较多,在这里我只列举一种比较常用的水平删除线,它属于整段删除线的一种。

整段删除线使用\require{enclose}来显示,声明整段删除线后,使用\enclose{删除线效果}{字符}来实现删除线效果,而水平删除线效果用关键字horizontalstrike。

实例:

md文本

1
2
3
4
5
6
$$
\require{enclose}\begin{array}{}
\enclose{horizontalstrike}{x+y}\\
\enclose{horizontalstrike}{x*y}\\
\end{array}
$$

最终效果

对齐

\begin{align}用于开头,\end{align}用于结尾,对齐的位置用&开始,用\\结束
输入:

1
2
3
4
5
6
$$
\begin{align}
f(x) &=a+b+a\\
& = 2a+b
\end{align}
$$

输出:

减法器有两种:一种是先对输入信号实现反相,然后再做加法运算;另一种是直接利用差分电路实现

1.输入信号实现反相实现减法器

543cf225x7ca35edcb97b&690.jpg

2.差分电路实现减法器

543cf225x72dd2aab7ff5&690.jpg
我使用差分减法器比较多,主要用于电流、电压的测量
其计算输出电压的公式如下:

若令R1=R2,R3=R4,上式可简化为: