命令行光标控制

在写命令行脚本的时候,为了监控脚本执行进度,往往需要输出一些数据,来确认脚本是否正在执行。而处理大数据文件时,大量的输出,又不容易看到输出日志,于是需要进行命令行光标控制,使光标固定到特定位置。需要 VT100 控制码定义终端显示。如下:

其中格式分下列两种:
  1.数字形式。
    \033[<数字>m
  2.控制字符形式。
    \033[字母

VT控制码归类有如下:

    \033[0m 关闭所有属性

    \033[1m 设置高亮度

    \033[4m 下划线

    \033[5m 闪烁

    \033[7m 反显

    \033[8m 消隐

    \033[30m —- \033[37m 设置前景色,0-7为 黑 红 绿 黄 蓝 紫 青 白

    \033[40m —- \033[47m 设置背景色,0-7为 黑 红 绿 黄 蓝 紫 青 白

    \033[nA 光标上移n行

    \033[nB 光标下移n行

    \033[nC 光标右移n行

    \033[nD 光标左移n行

    \033[y;xH 设置光标位置

    \033[2J 清屏

    \033[K 清除从光标到行尾的内容

    \033[s 保存光标位置

    \033[u 恢复光标位置

    \033[?25l 隐藏光标

    \033[?25h 显示光标

发表在 Shell | 留下评论

跨域访问设置方式

header('Access-Control-Allow-Origin: *');//允许跨域域名
header('Access-Control-Allow-Methods: GET, POST, PATCH, PUT, OPTIONS, DELETE');//允许跨域方式
header('Access-Control-Allow-Headers: *');//允许header
header('Access-Control-Expose-Headers: *');//某些header无法传递,须要指明header白名单(content-type 就在此列)
发表在 js, 前端, 设计模式, 运维 | 留下评论

js ISO-8859-1 转中文

fetch 获取的 header 内容如果是中文(多子节),则会转译成 ISO-8859-1 编码格式,需要转编码转换

var str = “ç\u0088±æ\u0088\u0091ä¸\u00ADå\u009B½”;
var utfstring =decodeURI(escape(str))//先编码再解码
//或者 utfstring =decodeURIComponent(escape(str)) 

decodeURIComponent 和 decodeURIComponent 区别具体看这里。encodeURI 自身无法产生能适用于HTTP GET 或 POST 请求的URI,例如对于 XMLHTTPRequests, 因为 “&”, “+”, 和 “=” 不会被编码,然而在 GET 和 POST 请求中它们是特殊字符。然而encodeURIComponent这个方法会对这些字符编码
参考

发表在 js, 前端 | 留下评论

fetch 下载流文件

前后端分离的项目,前端大部分使用fetch调用接口,遇到下载的时候,服务器接口一般直接返回流文件(链接本身就是一个文件)

const getExport = async (url) => {
    let options = _headerOptions('GET')
    let response = await fetch(config.apiHost+url,options)

    response.blob().then((blob) => {
        const a = window.document.createElement('a');
        const downUrl = window.URL.createObjectURL(blob);// 获取 blob 本地文件连接 (blob 为纯二进制对象,不能够直接保存到磁盘上)
        const filename = response.headers.get('Content-Disposition').split('filename=')[1].split('.');
        a.href = downUrl;
        a.download = `${decodeURI(escape(filename[0]))}.${filename[1]}`;
        a.click();
        window.URL.revokeObjectURL(downUrl);
    });

    return [];
}
发表在 js, 前端 | 留下评论

curl命令上传文件

curl 'http://xxxxxx' -F "theFile=/Users/xxxx/Downloads/1.jpg;filename=xxxx"

后台接收到的信息

var_dump($_FILE);
/*
array(1) {
  ["theFile"]=>
  array(6) {
    ["name"]=>
    string(7) "xxxx"
    ["tempName"]=>
    string(14) "/tmp/phpnk5HXI"
    ["tempResource"]=>
    array(0) {
    }
    ["type"]=>
    string(0) ""
    ["size"]=>
    int(36)
    ["error"]=>
    int(0)
  }
}
*/
发表在 Shell | 留下评论

使用 certbot 安装免费的安全证书

sudo apt-get install software-properties-common
sudo add-apt-repository ppa:certbot/certbot
sudo apt-get update
sudo apt-get install certbot python-certbot-nginx

certbot certonly --webroot -w /xxx -d www.ivhong.com -d ivhong.com -w /xxxx -d www.ivhui.com -d ivhui.com --agree-tos --email xxxx@163.com
--------------参数解释 :
* certonly  只获取证书
* --webroot  以webroot插件去获得证书
* -w  需配合--webroot参数一起使用,用来指定网站根目录
* -d   指定域名
* --agree-tos  用意ACME用户协议(如果省略此项,则在命令执行过程中会询问是否同意)
* --email 指定邮箱用来接收一些通知(如果省略此项,则在命令执行过程中会要求填写)
* (如果有多个域名,则按照一个 -w  /var/www/example  后接一个 -d example.com  的形式继续输入。)


#使用docker或类似webroot 不在本地的
certbot certonly --standalone -d www.ivhong.com -d ivhong.com  -d xxx -d xxx.com --agree-tos --email hong350@163.com

#自动更新shell,vim refreshssh.sh,写入下面内容

#!/bin/sh
/usr/bin/docker stop ivhong_nginx_1
/usr/bin/certbot renew --force-renew
cp -rf /etc/letsencrypt/live/www.ivhong.com /[docker nginx]/www.ivhong.com
/usr/bin/docker start ivhong_nginx_1

#添加crontab
35 3 * */2 * /root/refeshssh.sh

nginx 配置:

        listen 443 ssl;
        listen 80;
        server_name ivhui.com www.ivhui.com;
        index index.html index.htm index.php default.html default.htm default.php;
        root  /home/ivhong/www/ivhui/web;

#    ssl on;//这里如果是on的话,http访问网址将会出错
ssl_certificate /etc/letsencrypt/live/www.ivhong.com/fullchain.pem;
ssl_certificate_key /etc/letsencrypt/live/www.ivhong.com/privkey.pem;
ssl_session_timeout 5m;
 ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
 ssl_protocols TLSv1 TLSv1.1 TLSv1.2 TLSv1.3;
 ssl_prefer_server_ciphers on;

来源:https://blog.csdn.net/qq_35751770/article/details/78018613

发表在 运维 | 留下评论

php docker 安装扩展

在php docker 中有如下命令,方便使用
1. docker-php-source
源码文件目录控制命令

ocker-php-source [extract | delete]

extract : 创建并初始化 /usr/src/php目录
delete : 删除 /usr/src/php目录

2. docker-php-ext-install
扩展安装命令,需要源码目录存在

#
docker-php-ext-install [扩展目录名(比如redis)]

3 docker-php-ext-enable
启动扩展命令

docker-php-ext-enable [扩展目录名(比如redis)]

4. docker-php-ext-configure
安装扩展时,自定义扩展配置的命令,提供了一个自定义扩展的方法,比如说安装gd库,配置基础库路径

docker-php-ext-configure gd --with-freetype-dir=/usr/include/ --with-jpeg-dir=/usr/include/ 
docker-php-ext-install -j$(nproc) gd #nproc系统最大内核数,-j编译时的参数,作用是提高编译速度
发表在 docker | 留下评论

堆排序php

关于堆排序的理论网上有许多,就不多做解释,一般在非常大的数据集中,按排序获取前面一段排序结果,使用堆排序。
堆排序的时间复杂度为:O(nlogn);
空间复杂度为常数:O(1)

/**
 * 堆排序
 * @param array $ary 待排序输入
 * @param $func $大顶堆func 或者 $小顶堆func
 * @param int $num 结果数量,比如说获取最小前10个数,默认返回所有排序
 * @return array
 */
function mysort($ary, $func, $num = 0)
{
    $length = count($ary);
    $_ = 0;
    while ($_++ < $num) {
        if ($length == 1) {
            break;
        }
        for ($index = floor($length / 2) - 1; $index >= 0; $index--) {
            if ($length - 1 >= (2 * $index + 2)) {
                $func($ary[$index], $ary[2 * $index + 1], $ary[2 * $index + 2]);
            } else {
                $func($ary[$index], $ary[2 * $index + 1]);
            }
        }

        list($ary[0], $ary[$length-1]) = [$ary[$length-1], $ary[0]];
        $length--;
    }
    return $num < count($ary) ? array_slice($ary, -$num) : $ary;
}

$大顶堆func = function (&$a1, &$a2, &$a3 = null) {
    if ($a1 < $a2) {
        list($a2, $a1) = [$a1, $a2];
    }

    if (!is_null($a3)) {
        if ($a1 < $a3) {
            list($a1, $a3) = [$a3, $a1];
        }
    }
};

$小顶堆func = function (&$a1, &$a2, &$a3 = null) {
    if ($a1 > $a2) {
        list($a2, $a1) = [$a1, $a2];
    }

    if (!is_null($a3)) {
        if ($a1 > $a3) {
            list($a1, $a3) = [$a3, $a1];
        }
    }
};

$ary = [ 1, 0, 2,10,8,21,3,6,7,5,11,121,43,-1];
$res = mysort($ary, $小顶堆func, 7);
echo print_r($res);
发表在 php, php函数集 | 标签为 | 留下评论

OpenVPN 实现用户密码登录

1. server.conf中添加下面的设置

auth-user-pass-verify /opt/openvpn/checkpsw.sh via-env #密码验证脚本
script-security 3 
client-cert-not-required #不请求客户的CA证书,使用User/Pass验证,如果同时启用证书和密码认证,注释掉该行

username-as-common-name  #表示客户端认证时候需要用户名

2. 生成密码验证脚本
1)方法一:下载链接:http://openvpn.se/files/other/checkpsw.sh
2)方法二:checkpsw.sh 内容如下,自己创建到 /opt/openvpn/checkpsw.sh

#!/bin/sh

###########################################################

# checkpsw.sh (C) 2004 Mathias Sundman 

#

# This script will authenticate OpenVPN users against

# a plain text file. The passfile should simply contain

# one row per user with the username first followed by

# one or more space(s) or tab(s) and then the password.



PASSFILE="/opt/openvpn/psw-file"

LOG_FILE="/opt/openvpn/logs/openvpn-password.log"

TIME_STAMP=`date "+%Y-%m-%d %T"`



###########################################################



if [ ! -r "${PASSFILE}" ]; then

echo "${TIME_STAMP}: Could not open password file \"${PASSFILE}\" for reading." >> ${LOG_FILE}

exit 1

fi



CORRECT_PASSWORD=`awk '!/^;/&&!/^#/&&$1=="'${username}'"{print $2;exit}' ${PASSFILE}`



if [ "${CORRECT_PASSWORD}" = "" ]; then

echo "${TIME_STAMP}: User does not exist: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}

exit 1

fi



if [ "${password}" = "${CORRECT_PASSWORD}" ]; then

echo "${TIME_STAMP}: Successful authentication: username=\"${username}\"." >> ${LOG_FILE}

exit 0

fi



echo "${TIME_STAMP}: Incorrect password: username=\"${username}\", password=\"${password}\"." >> ${LOG_FILE}

exit 1

3. 创建账户密码文件

touch /opt/openvpn/logs/psw-file
chown nobody:nobody /opt/openvpn/psw-file 

psw-file文件内容是:

username1 pwd1
username2 pwd2

4.重启openvpn

5. 客户端配置添加配置

auth-user-pass

其他注意事项:
1. 没有密码访问日志没有日志
解决方案,权限不对,openvpn是用 nobody:nobody,日志文件使用nobody:nobody

服务器配置文件如下:
server_user_pwd_conf

发表在 VPN, 运维 | 标签为 , | 留下评论

阿里云配置OpenVPN

通过好些天的研究,终于把OpenVPN配置成功了。记录一下遇到的坑
1. 按照网上找的安装步骤一步一步安装,但是最终链接不上VPN。提示权限错误。
解放方案:
A. 配置中未加上 tls-auth ta.key 0,生成方式:openvpn –genkey –secret ta.key,客户端添加配置:tls-auth ta.key 1

B. 使用的客户端版本不对,使用Tunnelblick,openVPN的版本不对,改使用Viscosity,链接成功
同时命令行客户端的链接命令为:/usr/local/Cellar/openvpn/2.4.8/sbin/openvpn tdvpnuser.ovpn

2. 客户端报错:
WARNING: Split DNS is being used however no DNS domains are present. The DNS server/s for this connection may not be used. For more information please see: https://www.sparklabs.com/support/kb/article/warning-split-dns-is-being-used-however-no-dns-domains-are-present/
解决方案:DOS设置的不对,使用了阿里的DNS,添加配置: push “dhcp-option DNS 223.5.5.5″,

3. 连上VPN后,并没有使用VPN上网
解决方案:去掉配置注释:push “redirect-gateway def1 bypass-dhcp”

4. 链接上VPN只能ping通虚拟IP,不能ping通openvpn server上的物理网卡上的ip
解决方案:因为openvpen的路由设置错误,在配置中添加。 push “route 172.17.0.0 255.255.240.0”
因为物理网卡的网址的淹码是255.255.240.0,所以想了很长时间算出IP所在的网段(扔了好长时间的知识),IP网段设置好后,就可以ping通物理网卡的IP了

5. 不能上网,也不能ping通与openvpn server同网络的其他其他的ip
解决方案:添加路由规则:iptables -t nat -A POSTROUTING -s 10.8.0.0/24 -o eth0 -j MASQUERADE
iptables非常好的教程

下面分别是配置文件
server配置

client配置.ovpn

6. 如果需要多个用户使用同一个证书,打开 duplicate-cn 配置。

至于怎么生成的加密文件,请自行搜索,网上有很多教程

发表在 VPN, 运维 | 标签为 , | 留下评论