-
Permanent link to “微信浏览器内H5活动页调起小程序, 服务器端开发备忘” -
「新路由3 (new wifi3)…
半年多前配过一次,磕磕绊绊的,勉强配好了能用。这次老朋友又买了一台类似的机器,我以为会很快搞定,结果又陆续整了好几个小时。为避免下次折腾的时候浪费时间,简要记录一下折腾过程。 用到的软件 shadowsocks-libev-local kcptun-client 几个要点 需要下载的软件只有这俩,一开始没有下载 shadowsocks-libev-local而是尝试用机器里已经下载好的 shadowsocksR-local 代替,未成功(并不一定是ssR的锅.... 下载了kcptun,也配置了使用 kcptun,但kcptun服务一直不启动的原因是kcptun客户端的程序名字与系统中设置的不一致。安装好的客户端名字叫 kcptun-c 但默认配置的名字不是这个,务必要到「自动更新」那一页改一下配置。 「全局配置」页配置: TCP节点:SS+Kcptun: 节点名 UDP节眯:与TCP节点相同 Socks5节点:与TCP节点相同 DNS服务器(UDP): 默认 DNS模式: DNS2SOCKS + 使用Socks5节点解析 DNS地址:8.8.4.4 (Google DNS) DNS劫持: 选中 默认代理模式: GFW列表 (重要...尤其远程调试的时候,别瞎选全局...配不好的情况下一开代理,网会断,波及远程桌面! 本机代理模式: GFW列表 「节点页」配置: 服务器: 127.0.0.1 使用ipv6: 不选中 端口: kcptun 客户端打算用的端口 加密方式: ss服务器用到的加密方式 连接超时: 300 (默认值不用改 tcp快速打开: false (默认值不用改 插件: 无 使用kcptun: checkbox要勾中(废话 kcptun服务器: 你的kcptun服务器IP或域名 使用ipv6: 不选中 kcptun参数配置: 把kcptun服务器配置的那堆参数照抄过来(只要端口参数之外的参数,一定要拿掉 -r -l 这两参数哦! 回头看看也没什么.....就这么点事儿,整了几个小时。如果第一次整完就写篇备忘记录....哈,亡羊补牢,犹未晚,我这不就写了么!
-
Vue.js Event…
Two articles explain well this subject. One is in Chinese, the other is in English. 中文 English
-
-
PHP array_merge…
If you've got LINQ available to you, you can use Union, Except, Intersect, and Distinct: array1.Union(array2).Distinct().ToList() array2.Except(array1) array1.Except(array2) array1.Intersect(array2) Reference
-
MySQL: Delete All…
You want to add a unique index to a table, and unfortunately, there are already many duplicate rows in it. Manually find and delete these rows is time-wasting and error-prone. So why won't we just write one SQL statement and quickly resolve it? First try, I wrote the following statement, and it won't work: DELETE FROM PromotionSkus A WHERE A.SkuId IN (SELECT SkuId FROM PromotionSkus B GROUP BY B.SkuId HAVING COUNT(B.SkuId) > 1) AND A.Id NOT IN (SELECT MIN(Id) FROM PromotionSkus C GROUP BY C.SkuId HAVING COUNT(C.SkuId) > 1); AND this one below works! DELETE FROM PromotionSkus A WHERE A.Id NOT IN (SELECT Id FROM (SELECT MIN(Id) AS Id, COUNT(SkuId) AS Total FROM PromotionSkus GROUP BY SkuId HAVING Total > 1) AS B) AND A.SkuId IN (SELECT SkuId FROM (SELECT SkuId FROM PromotionSkus GROUP BY SkuId HAVING COUNT(SkuId) > 1) AS C); The reason is well explained in this brilliant article. Another mysql tip: using mysqldump export a table with one line one row. mysqldump --databases…
-
.NET Core 3.1…
Present enums as string. Modify your StartUp.cs, add the highlight part below: services.AddMemoryCache().AddMvcCore().AddJsonOptions(opts => { opts.JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter()); }) .AddDataAnnotationsLocalization(); Enable XML Comments Manually add the two lines in PropertyGroup below to the .csproj file: <PropertyGroup> <GenerateDocumentationFile>true</GenerateDocumentationFile> <NoWarn>$(NoWarn);1591</NoWarn> </PropertyGroup> 2. Add the options in the code below services.AddSwaggerGen(options => { options.IncludeXmlComments(Path.Combine(AppDomain.CurrentDomain.BaseDirectory, $"{AppDomain.CurrentDomain.FriendlyName}.xml"), true); });
-
SQLSugar: How to…
await Db.Queryable<Entity>().Where(_ => _.SampleFieldName== sampleFieldValue) .GroupBy("AnothterFieldNameInStringFormat") .Select<ResultModel>("AnotherFieldNameInStringFormat, Count(AnotherFieldNameInStringFormat) Total") .ToListAsync();
-
Elasticsearch Nest…
这与 Nest 默认的字段名映射规则有关。C# 项目字段名往往是 CamelCase,然而 Nest API在创建索引时,默认会将 CamelCase 的字段名,转换为 camelCase 的字段名。当然,查询的时候,它也会精确的按照 camelCase 字段名映射数据。如果你只用 Nest,其实是不会有任何问题的。毕竟 AutoMapper 对字段名大小写是很宽容的。 当我们引入 Logstash 动态更新索引之后,不和谐的一幕出现了。凡是 Logstash 更新的过数据,查询的时候会返回搜索结果,但所有字段的值都是null。这是因为Logstash在更新索引的时候,没有做 CamelCase => camelCase 的字段名转换。 了解了问题产生的原因,解决起来也就容易了。幸运的是,Nest有一个配置参数,可以设置为索引时不做字段名转换。直接上代码 public static void AddElasticsearch( this IServiceCollection services, string connectionUrl, string connectionIndex) { var defaultIndex = connectionIndex; var settings = new ConnectionSettings(new Uri(connectionUrl)) .DefaultIndex(defaultIndex); settings.DefaultFieldNameInferrer(p => p); var client = new ElasticClient(settings); services.AddSingleton(client); } 需要注意的是,代码修改后,别忘记重建索引。否则你会发现原来不正常的( Logstash更新过的数据)都正常了,原来搜索正常的,现在却所有字段名都变成了null。
-
Tips collection
Buefy is a lightweight UI components library for Vue.js based on Bulma @keyup.enter="eventHandler" doesn't work in el-input, but @keyup.enter.native="eventHandler" does. #element-ui git rm -rf . && git clean -fxd is the best way to delete all files except .git directory. #git To make your dynamic LINQ query safe, you must use placeholders for all user input. Never concatenate your string! #dotnetcore try_files $uri $uir/ =404; is better than try_files $uri $uri/ /index.html;, because it can avoid endless loop when /index.html doesn't exist. #nginx git tag -n99 show tags along with annotations Reference new crontab task added 0 6 * * * /bin/docker container prune -f 10 6 * * * /bin/docker rmi $(/bin/docker images -f "dangling=true" -q)
-
an idea for Pak'n…
PknSave fuel voucher is often wasted by their members because their tank is full before it expires automatically. So the idea is, we can share the fuel vouchers through a mobile app. If it is big enough, you print a voucher whatever you need or not. If you don't need to fuel your car, post this voucher on our app and set the amount with expire time. If you need fuel for your car but have not a voucher, open the app and try to find an unused one. When you decide to use it, you booked it so other people cannot use it anymore. If you eventually didn't use it, put it back into the voucher pool. Sounds great? Let's do it. If you want to contribute to this side project, contact me with [email protected]
-
Seafile server…
I am using the docker-compose version. The first problem I met was none of Seafile's concerns, it is actually a bug of docker. All of the containers cannot reach the internet (cannot resolve any DNS). The solution is at here. After fixed the issue above, the Seafile server runs well on centos. However, there are still two issues that need to be addressed. The first one is about the head icon of a user. It simply cannot display. You can easily found that the host part of the head icon is wrong. You need to edit "shared/seafile/conf/ccnet.conf" and change the SERVICE_URL to your real hostname in the [General] section. The second one is similar, if you don't fix it, you cannot download any of the file you uploaded. This time, you need to edit "shared/seafile/conf/seahub_settings.py" and change the last line to "https://your.domain.name/seafhttp".
-
tmux super simple…
echo 'set -g mouse on' >> ~/.tmux.conf tmux new -s tmux3 ^b % ^b " ^b d tmux attach -t tmux3
-
Superpay…
这两天在和开发小程序的同事对接supay支付,今天总算基本搞完了。他们的文档过于糟糕,太多槽要吐,记录一下也许会帮到其他也需要对接superpay的人。先说说我们的业务流程 小程序 wx.login 拿到 code 小程序 wx.getUserInfo 拿到加密的 userData和iv 小程序登录请求公司后端服务器 /wechatMiniProgram/login 接口三方登录,登录成功拿到可访问公司其他接口的 accessToken 小程序拿着accessToken下订单 小程序拿着订单id请求公司后端服务器 /supay/wechatMiniProgramPay/{orderId} 公司服务器请求 supay 小程序下单接口,获取pay_info 给小程序。故事主要发生在这里。 他们的文档里是有一个流程图的,写成文本大体是下面这样。 小程序向公司后台服务器发起下单支付请求 公司后台服务器请求 superpay 服务器获取 openid superpay 服务器返回 openid 给公司后台服务器 公司后台服务器拿着openid 请求superpay服务器(小程序下单接口)拿 pay_info 公司服务器把 pay_info 返回给小程序 小程序拿 pay_info 发起支付 这个流程图事后看其实也不算错,只是其中第2步和第3步是不必要的。因为小程序在三方登录的时候,我们已经可以拿到openid和unionid。补充一句,小程序支付只需要openid,并不需要unionid。 在和superpay的技术同事沟通过程中,我发现最有价值的聊天记录包括 不要管其他的接口了,就用小程序下单 交易状态 TRADE_FINISHED 不需要处理 小程序下单返回的接口数据中,所有时间均是北京时间 inner_trade_no是 supay 的单号,mch_order_no和outer_trade_no 是你们的单号 trade_amount是人民币金额,虽然例子里写的是纽币 签名的时候字典序是重要的,文档里虽然没有提到,但在签名串字典序末尾追加一个 &key=商户appsecret 再md5是至关重要的。 因为签名需要拼一个query…
-
How to setup pm2 to…
$ pm2 start $ pm2 save $ pm2 startup You will see something like the following after you run the last command: [PM2] Init System found: systemd [PM2] To setup the Startup Script, copy/paste the following command: sudo env PATH=$PATH:/usr/local/lib/nodejs/node-v12.18.0-linux-x64/bin /usr/local/lib/nodejs/node-v12.18.0-linux-x64/lib/node_modules/pm2/bin/pm2 startup systemd -u shukebeta --hp /home/shukebeta copy the sudo line & paste it on your command line then press Enter! You have done. Here's a sample pm2.config.json for a project. { "apps" : [{ "name": "tracking-system", "script": "app.js", "watch": ".", "exec_mode" : "cluster", "instances" : 4, "exec_mode" : "cluster", "autorestart": true } ] }
-
JavaScript中七种函数调用方式…
旧文重发存档,原文发表于9年前。原文地址 this 在 JavaScript 开发中占有相当重要的地位,不过很多人对this这个东西都感觉到琢磨不透。要真正理解JavaScript的函数机制,就非常有必要搞清楚this到底是怎么回事。 函数调用方式不同,this 含义也跟着不同。JavaScript语言中有七种调用函数方式: 第一种:调用方法 var obj = { method: function() { alert(this === obj); } } obj.method(); 上面这行obj.method()显然method是作为方法被调用,这种情况下,函数体中的this绑定的就是method的宿主对象,也就是obj。 从这种调用方式我们得出第一定律: 第一定律:以方法方式调用函数,this则绑定宿主对象。 第二种:调用全局函数 var method = function(){alert(this === window);} method(); 上面这个函数是个全局函数。我们知道,全局变量或函数都相当于window对象的属性。也就是说,上面这句实际上等同于下面这句: window.method = function(){alert(this === window);} window.method(); 既然这样,那么这里 this 绑定到 window 对象就显而易见,很容易理解了。相当于方法调用模式的一个特例,并不违背第一定律。 第三种:全局函数内调用内部函数 var m_ext = function() { alert(this === window); var m_inner = function() { alert(this === window); } m_inner(); } m_ext(); 执行上面这段代码,你会惊讶的发现,两个布尔表达式的值都是真。也就是说子函数孙函数,只要是以函数的方式调用,this 就铁了心绑定 window 对象了。从这种调用方式我们得出第二定律: 第二定律:不论子函数孙函数,只要是以函数的方式调用,this 就铁了心绑定 window 对象。 第四种:方法内调用内部函数 var obj = {}; obj.method = function() { alert(this === obj); var m_inner…
-
A quick way to run…
put a .my.cnf file into your home directory, for example $ cat ~/.my.cnf [client] user=yourDbUserName password=yourDbPassword host=yourDbHost write a bash script to update the database #!/bin/bash set -ex variable=`TZ="Africa/Abidjan" date '+%Y-%m-%d %H:%M:%S'` sql="Your SQL statement with ${variable}" logDir=/data/Logs/`date '+%Y'`/`date '+%m'` mkdir -p "${logDir}" echo "${sql}" >> "${logDir}/`date '+%d'`.sql" mysql -v -v -e "${sql}" >> "${logDir}/`date '+%d'`.result.txt" put a line by run crontab -e the end.
-
vue-cli-service…
严格来说,二者是两个维度,并没有必然的固定的映射关系。只是通常情况下,约定俗成的: --mode test <=> NODE_ENV=test --mode development <=> NODE_ENV=development --mode production <=> NODE_ENV=production --mode staging <=> NODE_ENV=staging 那怎么知道手头的项目是否符合这个约定俗成呢?通常来说,你可以看一下项目根目录下的 .env 系列文件,一般情况下,NODE_ENV 变量会定义在那里。
-
How to get HTTPS…
To be honest, 5 minutes is not enough, especially for the first time you do it. What you need to prepare a VPS (Virtual Personal Server) with public IP an Nginx Server running on that VPS. an OpenVPN Server running on that VPS. (or you have tailscale service running on both your local machine & the VPS server) a domain name the CertBot tool from Let's Encrypt Steps to get it to work For example, your local dev environment is running on 10.8.0.2:8080 your domain name is dev.myawesomedomain.com create a new virtual server on your Nginx server, you can use the config below as a template. upstream local-front-end-env { server 10.8.0.2:8080; } server { listen 80; listen [::]:80; server_name dev.myawesomedomain.com; access_log /var/log/nginx/dev.myawesomedomain.com.access.log; error_log /var/log/nginx/dev.myawesomedomain.com.error.log; location / { proxy_pass http://local-fornt-end-env; proxy_redirect off; proxy_set_header Host $host; proxy_set_header X-Forwarded-Proto https;…
-
Two silly moments…
Bound object changes but the UI didn't change. Solution: Template part, <el-select v-model="form.categoryIdList" multiple @change="setValue(form.categoryIdList)"> Component part, setValue(object) { this.$set(this.form, this.form.categoryIdList, object) }, VUE_APP_CUSTOM_VARIBLE doesn't work, solution: Restart your dev server.
-
Using crontab to…
on a server with huge disk space, run crontab -e and put the following code in it (you may need to change the directory names to fit your situation) 30 3 * * * mysqldump --databases DB1 DB2 DB3 DB4 | gzip > /data/backups/mysql/db_`date '+\%Y\%m\%d-\%H\%M\%S'`.sql.gz 30 4 * * * find /data/backups/mysql/db_* -mtime -1 -exec scp {} anotherserver:/data/backups/mysql \; 30 5 * * * find /data/backups/mysql/db_* -mtime +30 -exec rm {} \; on another server, run crontab -e and put the following line into it: 30 5 * * * find /data/backups/mysql/db_* -mtime +7 -exec rm {} \; summary & explanation: at 3:30 backup MySQL data in a local directory and keep latest 30 days backup in that directory at 4:30 transfer the latest backup to another server in case the first backup may be destroyed by an accident. at 5:30 remove the oldest backup on the local backup server (the code shows that the latest 30 days backups are kept on the server). at 5:30 remove the oldest backup on the remote server (the…
-
Git Tips
按最近提交的提交时间(DESC)列出本地分支 git branch --sort=-committerdate 太长记不住?运行下面的命令配置一个git命令别名,下次只需要敲 git brs 即可得到同样结果: git config --global alias.brs "branch --sort=-committerdate" 解决git 命令行把中文文件名显示成 \343\200\212类似乱码的问题 git config --global core.quotepath off 将变更加入缓冲区,但不加入空白(空格、制表符或者换行符)的变更 git diff -w | git apply --cached --ignore-whitespace Reference git diff 时排除掉某些不想看的文件 git diff -- . ':(exclude)db/irrelevant.php' ':(exclude)db/irrelevant2.php' 删除远端分支 git push origin --delete branchname 嫌打字麻烦的,可以使用以下简写命令 git push origin :branchname 发现文件丢了不知道谁删的,比如 yarn.lock , 用下面这个命令 git log -p -- yarn.lock 设置总是push到远端的同名分支,从此再也不用如此麻烦的敲 git push -u origin theSameBranchName,你只管 git push 就好! git config --global push.default current 从 git 2.37 版开始,我们可以用下面这个新设置更好的解决这个问题。它不仅起到类似上一个命令的作用,它还自动设置 track 到远端的同名分支。如果你的git版本比较新,使用这个设置更好。 git config --global push.autoSetupRemote true 解决 git diff 时出现讨厌的 ^M git config --global core.whitespace cr-at-eol Reference 更多的技巧请访问我的 GotGit 群组
-
Using sed to insert…
最近一直在写 .net core,它有诸多优点我且不提,我实在头痛于手写注入服务时的模式化代码,因此动了心思要写个小脚本帮我自动化一些事情。我的想法是告诉我要加入的 ServiceName, 指定一个 Controller然后脚本自动在这个 Controller 里声明一个 private readonly 属性,自动修改类的construction 函数,自动注入这个服务,并在construction 函数体写上 _serviceName = serviceName; 在第一步,注入 private readonly 属性那里,我就绊了个跟头。用 sed 匹配到某行,在它之前,或者之后插入数据是简单的。但我匹配到 public class xxxController 这行之后是单独一行 {,而我要加的变量要放到 {这行之后。网上一通搜索,试图找到定位到某行之后N行的命令,然而并没有这样的命令。然而功夫不负有心人,我最后还是找到了一个解决方案,那就是 sed '/pattern/!b;n;n;i\something' 具体解释见 Reference
-
ubuntu 20.04…
其实很简单,但因为网上有流传很广的教程并不适用于最新的 ubuntu 20.04,造成我也走了一点弯路。 certbot-auto 官方已停止维护,但网上广为流传的教程仍然推荐使用 certbot-auto 来生成证书。这是问题的根源。正确的姿势是这样的 sudo apt install certbot sudo certbot certonly --manual -d *.yourdomain.com -d youdomain.com --preferred-challenges dns-01 --server https://acme-v02.api.letsencrypt.org/directory 照提示一步一步来就好了。是不是超级简单?
-
A guide for git…
状态标识 标志 含义 nul 文件已提交到版本库未做修改 ?? untracked 新文件尚未 git add A staged 已经 git add 但尚未提交 AM staged 未提交又做限新的修改,新修改尚未staged MM 一些修改staged之后又做了新的修改,新修改尚未staged 状态转换指南 状态A -> 状态B 需要的操作 nul -> M 修改文件 MM -> nul git checkout HEAD file(s) OR git checkout -- file(s) A -> ?? git rm --cached file(s) M -> M git add file(s) A -> AM git reset file(s) A -> nul git reset file(s) ?? -> A git add file(s) A -> ?? git rm --cached file(s) A -> AM git add 之后再修改文件 AM -> A git checkout -- file(s)
-
switch case in bash…
, change the first letter of the value of the variable to lowercase, ,, change the value of the whole variable to lower case. $ test='HELLO' $ echo $test HELLO $ echo ${test,} hELLO $ echo ${test,,} hello $ test=${test,,} $ echo ${test^} Hello $ echo ${test^^} HELLO
-
-
A bash script to…
#!/bin/bash git push currentbranch=`git branch --show-current` if [ "${currentbranch}" == "local" ]; then git checkout develop git merge local git push elif [ "${currentbranch}" == "develop" ]; then git checkout local git merge develop git push fi git checkout $currentbranch Don't ask why I wrote this foolish script. I have to do it 😀
-
Using the cookie…
It took me more than an hour to understand how to use cookies when you are sending a request to the API server. The most important thing is that you only need to correctly add the cookies, then the cookies will be automatically sent to the API server. Don't try to add a cookie item at the headers' configuration part!
-
vim…
vim 命令模式粘贴寄存器中复制好的内容:先Ctrl+R,再输入寄存器名字。默认寄存器名字是 "
-
Attention: the…
I originally thought the later should be used. I was wrong.
-
Bash script for…
cat monitor.sh #!/bin/bash source /etc/profile cd /home/koala/Vagrant/windows-server-2019 (echo > /dev/tcp/192.168.178.220/23) > /dev/null 2>&1 if [ $? -ne 0 ]; then vagrant halt vagrant up fi
-
How to use Jenkins…
Checkout code Set correct config file Scp to the remote machine Run deploy.sh on the remote machine by ssh docker-compose build --no-cache docker-compose down docker-compose up -d sshPublisher setup Manage Jenkins -> Config System Find Publish over SSH Add New Server, test connection Write directive in Jenkins file sshPublisher( continueOnError: false, failOnError: true, publishers: [ sshPublisherDesc( configName: "yt-files-${BRANCH}", verbose: true, transfers: [ sshTransfer( sourceFiles: "**/**", remoteDirectory: "./publish/${BRANCH}", removePrefix: '', remoteDirectorySDF: false, cleanRemote: true, execCommand: "cd ./publish/${BRANCH} && bash deploy.sh ${BRANCH}" ) ]) ] ) 要在Jenkins中新增对一个仓库的发布,需要以下步骤 创建流水线, 添加Git仓库,Credentials 为各分支添加必要的配置文件(不方便加入版本控制的机密信息) 写 Jenkinsfile
-
-
转换 gbk txt文件为 utf-8…
这都是为了看《非正常人类异闻录》 iconv -c -f gbk -t utf-8 待转文件名 > target.txt -c 的意思是在输出文本中忽略非法的字符序列 Reference 然而都弄好了,即没有认真看那本书。不喜欢那种风格,没办法
-
-
设置mysql用户密码时小心 # 字符
我喜欢用 .my.cnf 配置 mysql 的登录信息,这样我执行一些命令的时候就不用在命令行上提供密码。但今天我被自己设置的”高强度密码“坑到了 简而言之,如果你的密码里有#字符,请用双引号把整个密码括起来,要知道没有被引号括起来的 #字符,标识后面的都是注释。哈
-
Debian/Ubuntu/PopOS…
package name for common used Linux util in Debian/Ubuntu ps apt install -y procps ping apt install -y iputils-ping telnet apt install -y telnet general solution for apt get/apt upgrade similiar issues first, sudo dpkg --configure -a followed by: sudo apt --fix-broken install
-
Samples for setting…
bash ASPNETCORE_URLS="http://*:9143" ASPNETCORE_ENVIRONMENT="Development" dotnet Yourproject.dll ASPNETCORE_ENVIRONMENT="Development" dotnet run --urls "http://*:9143" --no-launch-profile for Windows command line (cmd.exe) setx ASPNETCORE_URLS "http://localhost:5001" setx ASPNETCORE_ENVIRONMENT "Development" dotnet Yourproject.dll for Windows powershell $Env: ASPNETCORE_URLS "http://localhost:5001" $Env: ASPNETCORE_ENVIRONMENT "Development" dotnet Yourproject.dll Reference
-
Using dconf-editor…
The keyboard shortcuts setting in the Settings app can only support 4 workspaces. However, I want to use 8 workspaces to implement the goal of "everything in its right place". Solution: sudo apt install dconf-editor dconf-editor org/gnome/desktop/wm/keybindings # Then you can do what you want to do there Reference By the way, my final configuration is shown below: Ctrl + 1-8 Switch to workspace 1-8 Ctrl+Alt+1-8 Move current window to workspace 1-8 and jump to that workspace Workspace 1: Chrome Workspace 2: Gnome-terminal Workspace 3: Rider Workspace 4: WebStorm Workspace 5: Ebook reader (Evince and others) Workspace 6: File Manager, BitTorrent downloader, Workspace 7: VMs Workspace 8: Settings, Telegram, music player, misc.
-
Jenkins 三言两语(二)
Jenkins 虽然通过ssh访问一个node来执行build或者 deploy任务,而且它也确实执行了远程机器的.bashrc 脚本,但它却刻意的抹掉了PATH 环境变量。所以在你要运行的bash脚本里再 source 一遍 /etc/profile 就有了必要。 Jenkins自己的环境变量,可以在脚本里直接用,但从bash里来的环境变量,如 $?,就得用反斜线转义 \$ 符号。 .bashrc 别 echo 东西,否则 Jenkins 会拒绝干活。(应该弄一台专门的机器只跑 Jenkins) PS: 上面第2条其实描述不准确,后面踩的坑证明,如果用 sh 命令里有环境变量,老老实实用单引号,如果非用双引号,你反而要用\给 $转义。切记!Jenkins环境不是bash环境。不论是否 Jenkins里定义的环境变量,如果要在bash脚本里用,就老老实实用单引号。
-
Linux TIPS collect…
http_proxy environment in sudo command: http_proxy=xxx:xxx sudo yourcommand doesn't work, you should sudo http_proxy=xxx:yyy yourcommand instead. ssh running local script: ssh username@hostname 'bash -s' < your.local.script.sh ssh running local script with paraemters: ssh username@hostname < your.local.script.sh 'bash -s' yourparam1 yourparam2 doesn't work, you should runssh username@hostname < your.local.script.sh 'bash -s' -- yourparam1 yourparam2 make your fonts configuration work without a reboot: sudo fc-cache -fv
-
Can't boot VMs…
I followed this article to upgrade the kernel of one of our Linux server runs CentOS8. According to that article, upgrade the kernel of a CentOS system is rather simple, you just need to run the following command as root: rpm --import https://www.elrepo.org/RPM-GPG-KEY-elrepo.org dnf -y install https://www.elrepo.org/elrepo-release-8.0-2.el8.elrepo.noarch.rpm dnf -y --enablerepo=elrepo-kernel install kernel-ml Everything goes fine before I try to boot up one of the VM in Virtualbox 6. Boot failure, "The system is currently not set up to build kernel modules, please install the Linux kernel header files matching the current kernel.", it says. Obviously, we need the correct header file, after digging a while on Google, I didn't get an answer. Then I review the steps I have done to upgrade the kernel. Oh, I got the solution below: dnf -y --enablerepo=elrepo-kernel install kernel-ml-devel /sbin/rcvboxdrv setup Problem resolved.
-
Making bootable usb…
You are already using Linux, so you have dd already, you don't need any other tools to make a bootable USB disk! sudo dd bs=1M if=galliumos-3.1-baytrail.iso of=/dev/sda ; sync Notice: You should use your iso file name and replace /dev/sda to your own USB disk device. Reference
-
ubuntu 20.04…
try to download something but axel said "SSL error: (null)", so axel https://github.com/axel-download-accelerator/axel/releases/download/v2.17.9/axel-2.17.9.tar.gz tar xvfz axel-2.17.9.tar.gz cd axel-2.17.9 sudo apt install pkg-config -y ./configure && make && sudo make install sudo apt remove axel cd .. rm -rf axel-2.17.9
-
vim 向上删除 n 行
我们都知道从当前行往下删除 n 行很容易, ndd 就好了。但往上删除呢? 我以前是不知道的,最近搜索了一下,找到了答案,而且额外学到了其他的技巧,你想听吗(不想听我也会写,哈哈 8dd其实是dd重复8次,容易记忆,但效率很低。正确的姿势是 7dj 或者 d7j。我想你看到这里已经猜到应该怎么向上删除了。如果打算从当前行往上删除n行,你需要 {n-1}dk 或者 d{n-1}k 故事到这里应该结束了,然而.... 试试 V3kd, V4jd,注意是大写的V。你会对vim的强大有更多的理解。 By the way, 如果你要从当前行删除到你知道行号的某一行,举例来说,你要从当前行一直删到第434行,无所谓是向上删还是向下删,用 d434G 就可以了。
-
-
离奇的axios返回数据:得到了一个J…
同事前两天遇到一个离奇的 axios 问题,response.data看上去非常正常,但无法访问这个对象里面的任何一个键。console.log(response.data) 一看果然是 string。 同事很茫然,一直都好好的,也没有改什么啊。 改了 db.json。里面有一个多余的逗号。axios解析json字符串失败,就一声没吭的返回了字符串而非对象。这个坑货!想想axios也很无辜....因为我们有时候可能真的会有需要返回字符串。所以写期望的返回数据时,别偷懒又允许json又允许text。也许只允许json就不会有这个问题了。(待验证) Reference
-
解决CentOS 虚拟机从VMWare…
最近把一台CentOS7 虚拟机从Windows 10 的VMWare 迁移到 CentOS8 的VirtualBox上,结果不能启动,说找不到 root 和 swap。我猜测与 Host机器CPU架构不同有关,老机器是Intel芯片,新机器是 AMD CPU。 解决方法也蛮简单,进Rescue模式, yum update 就会自动装上一个新鲜的符合条件的内核。然后再重新启动就好了。 Reference 如此搞一下之后,启动倒是启动起来了,但启动时总有一个出错信息“error failed to send host log ”,虽然不影响使用,但看着很不爽。万能的Google很快给出了答案,把显卡换成 VBoxVGA 就好了。Reference
-
Jenkins 三言两语
三天小长假过完了。终于把 Jenkins 从windows 10 也迁到了那台 CentOS上,我对 Jenkins 的了解又深了一点点。 Jenkins 把所有的插件和用户数据都存一个目录里,这个设计非常赞。这让我得以专注于迁移我的流水线。 让 Jenkins 运行在docker里,把运行docker的host机器做成一个新节点,很不错。 我更喜欢声明式流水线....主要是对脚本式流水线更不熟悉,对 groove 语法也不熟悉,另外,也不很想在流水线里写复杂的逻辑。这俩谁都先进呢?说不准。我更看好声明式流水线。 agent和node之间的关系还是没有搞得特别清楚。时间紧,经理又催得急,先这么着吧。 怕删错文件,删文件的地方没敢用环境变量,越来越胆小。哈,应该有更好的解决办法。 ssh从docker里连到宿主机....用key文件没有成功。尚且不知道原因,应该加个todo。 PS: 更好的解决方法找到了,它就是 ${varName:?} 这种方式引用bash变量,若 varName 未设置值,则脚本会立即报错退出执行。
-
Ubuntu 22.04…
为啥用 fcitx 不用ibus呢.... 一开始我确实是用的ibus,但它老人家在 google doc 的网页里不显示候选文字框,等修复不知道要等到啥时候,我就扭头换 fcitx 了。 ibus-rime, fcitx-rime 已经内置这个功能,但它的默认配置里没有使用这个功能。废话不说,贴上我的配置文件 ~/.config/fcitx 或 ibus/rime/default.custom.yaml 内容如下 patch: style: display_tray_icon: true horizental: false font_point: 14 schema_list: - schema: wubi_pinyin - schema: pinyin_simp ascii_composer/switch_key: Shift_R: commit_code Shift_L: commit_code ~/.config/fcitx 或 ibus/rime/wubi_pinyin.custom.yaml 内容如下: patch: switches: - name: ascii_mode reset: 0 states: [ "中文", "西文" ] - name: full_shape states: [ "半角", "全角" ] - name: simplification states: [ "汉字", "漢字" ] simplifier/opencc_config: s2t.json engine/filters: - simplifier - uniquifier
-
What I have learnt…
长叹一声。Linux 上就没有一个好用的远程桌面服务器。虽然不喜欢,留个 teamviewer 进程一直开着以应不时之需是有必要的。 vagrant 的 public_network 在 usb 无线网卡有bug...(服务器好好的千兆网卡你不用用什么无线网卡....不是手头没有网线嘛 "Ansible for DevOps" 据说是一本好书。那待读书单里就加一本吧 CentOS8内置了一个叫 cockpit 的web管理器,还挺好用的。它的端口是9090,咋改成用正儿把经的https证书我还不知道。 Gnome桌面有一个叫 Vinagre 的远程桌面客户端,支持的服务器类型挺多的。(然而并不好用) 不应该把对应数据表的 entity model 直接用在 web API 里。别嫌麻烦,那个应该是贫血的,除了主键并不需要有其他的约束。把完整的表结构和所有字段暴露给客户端是不好的。 AutoMapper 有什么用?应该怎么用? ,这篇09年的老文章和里面的评论可能会有点用。 chrome OS 开了开发者模式,按 ctrl + alt + -> root 登录即可设置默认用户的密码。 想深入了解Linux了,所以又开始看 Linux From Scratch。
-
Tailscale:不一样的VPN
Tailscale 丁宇在推特上说这个东东比 frp 好用。我先一口气把它安装到四台服务器性质的 Linux 机器上,包括两台本来就有外网 IP 的vps,然后才琢磨这东西有啥用,怎么用。安装和授权过程都很简洁,没有废话,第一印象棒极了。 那...它有啥用呢?一句话,它把你所有的机器,不论物理上隔多远,放到一个局域网里了。在这个局域网里,没有防火墙,网内可以访问任何设备的任何端口。和普通的vpn不同,它没有中央设备,所有设备之间都是直连,因此性能比较好。 那有啥用呢? 管理你的一堆机器更方便了。 局域网内任何一台有外网IP的机器都能做为任何一台内网机器的跳板机(内网无端口限制的穿透)。 换言之,你的VPS只要有足够的流量,硬盘空间不再是限制你部署应用的瓶颈,你完全可以把你的各种试验性side project部署在你的家里,或者父母的家里,扔台旧机器装个Linux就全齐活了。 嗯,它不光支持 Linux,还支持macOS,iOS,Windows!牛大了。 记录一下小坑。macOS 10.15.4 安装好后 Login 是灰的,无法登录,重启下电脑就好了。
-
好香的接口测试工具:Insomnia…
这是我从新近follow的一个推友 @tywtywtyw 的推文里拣到的宝。他在推文里说 放弃了 postman 和 postwomen, 来到了 insomnia 能比 Postman 更好?这勾起了我的好奇心。结果发现真香。 顺便说一下,他的口号是“Design and debug APIs like a human, not a robot.” 不用写脚本,可以指定当前请求依赖哪个请求,以及是使用缓存的请求结果,还是需要时再发新请求(通常我都会选择发新请求,毕竟token会过期) 最重要的键是 Ctrl+空格。这是 autocomplete 的热键。 界面相对易用。 有父环境和子环境的概念,公共的东西写到父环境里,能省一些时间 就像使用苹果的软件,你不需要专门保存你的接口,你写了,你run了,接口就自动存好了。 遇到一个坑:如果是在JSON里使用环境变量,并且这个变量是个字符串,得用双引号括住这个变量! 我已经决定扔掉 Postman 了。就是这么喜新厌旧。
-
How to let…
It spent more than half an hour. Finally, I found this solution.... very simple! #!/bin/bash /usr/local/bin/noip2 -c /usr/local/etc/no-ip2.conf sleep 1 noip sucks! source
-
Database structure…
Two bash script achieved the goals in this subject. 1. Exporting data dictionary cat utils/exportDbDictionary if [ $# != 2 ] ; then echo "USAGE: $0 dbname tablename" echo " e.g.: $0 IDServer AspNetUsers" exit 1; fi document_path=/YourProjectName/documents/database [ -d $document_path/$1 ] || mkdir -p $document_path/$1 mysqlshow $1 $2 | sed 's/+/|/g' | sed '1,2d' | sed '$d' | awk -F"[|]" '{print $2"|"$3"|"$5"|"$6"|"$7"|"$10}' | sed 's/ *$//g' > $document_path/$1/$2.md People should always add comments to their field definitions. As soon as the definition of a table has been done, run this script could automatically generate a markdown table with the name of tableName.md. 2. export database structure without auto_incrment= statements cat utils/backupDbStructure backupFile=/YourProjectName/documents/database/databaseStructure.sql mysqldump -d --databases YourDB1 YourDB2 YourDB3 | sed 's/…
-
.net core…
If the field names in your Model class are not exactly the same as in a JSON string, you will need adding an option to guarantee the behavior is what you want. For example, if you have got the following response text: {"hello":"world"} and you have a Model class below: class SampleModel { public string Hello { get; set; }; } You can see the property name in your Model class is "Hello" instead of "hello", the following code won't get an expecting result. SampleModel s = JsonSerializer.Deserialize<SampleModel>("{\"hello\":\"world\"}"); you will get an object like { "Hello": null } You have to use an option below to get it to work. SampleModel s = JsonSerializer.Deserialize<SampleModel>("{\"hello\":\"world\"}", new JsonSerializerOptions { PropertyNameCaseInsensitive = true, }); on the other hand, you have to use the following code to guarantee the serialize behavior:…
-
-
Setting timezone for Linux system sudo timedatectl set-timezone Asia/Shanghai Setting timezone for MySQL add the line below to [mysqld] section in /etc/my.cnf default=time-zone = "+8:00"
-
Let your Linux…
$ sudo vim /etc/sysctl.conf add the line below to the end of this file: vm.swappiness = 10 save and exit. Execute $ sudo sysctl -p vm.swappiness = 10 means that the Linux system will only start using swap space when your available physical memory is less than 10%.
-
Vmware CentOS guest…
今天天气不错,和太太儿子去 Bowenvale Walking Tracks 走了一个短途的hiking。回家路上前端同学报告说测试机出问题了,所有接口都不通了。于是到家赶紧排查问题。 网络环境 Host:Windows 10,Vmware Station Guest: CentOS 7.7 Bridge network 一开始以为是服务进程崩了。连上vpn发现机器都ping不通。哦看来虚拟机是被谁关掉了。远程桌面到Host机器一看....虚拟机活得好好的,并没有被关掉。用控制台登录进去一看,发现IP不是我们以前设定的IP,而是变成 172.18.开头的一个地址,这是我们误以为网络不通了的原因。 经过一番排查,发现故事应该是这样的: CentOS机器的网络配置是 DHCP,因为网络是桥接的,因此只需要路由器上做点设置,根据CentOS机器网卡的Mac地址总是分配 192.168.178.52 这个IP给虚拟机就行了。我查看了路由器的设置,发现确实是这么设置的,虚拟机网卡的mac地址也没有变,看上去一切都很正常。不过这里有一个小小的细节,一开始我没有在意,但它可能是问题发生的始作俑者。 在登录公司路由器的时候,我没有直接进入设置界面,而是系统弹出一个提示框,说系统刚刚升级到某某版本,有一个引导界面走了好几步才进入路由器设置界面。 我先是修改CentOS的网络设置,把网络参数由 dhcp 改成 static,确保他总是使用 192.168.178.52 这个IP,也设置了默认路由,重启网络,发现修改生效了,IP地址现在是正确的了,但是却不能上网,内外不通。 那问题出在哪里呢?之前拿到的IP是172.18.x.x,这不是 Docker 喜欢用的IP段么?莫非和Docker 有关?我先是把 CentOS 虚拟机里的Docker 停掉....重启网络,依然固我。网还是不通。 我只好把关注点移到 Host 机器,硬件网卡,VMnet1, VMnet8, vEthernet (Default Switch)..... 慢,这个vEthernet 是什么鬼? 它的IP也是172.18.x.x的!网上搜索了一下,说这个东东应该是Docker添加的。对呀,我前几天刚好干过这个事情,在Windows 10 上安装了Docker,那时我是试图解决 Jenkins…
-
解决 ibus-rime 在…
我忍受这个问题已经有快一个月了,今天打算花点时间把它解决掉。 经过一翻搜索,我发现已经有人在 ibus-rime 项目上报告了这个问题,也有人给出了解决方法。遗憾的是,那个解决方案有些含糊,我不知道需要对系统做哪些改变。 也许从源码安装能够解决问题?但我一开始走了弯路,没有认真安装文档中提到的所有依赖,毫无疑问的,编译到中间就因为缺这缺那失败了。后面我就老老实实的按照文档说明,先安装好所有的依赖,再执行 ./install.sh。然而我仍然可耻的失败了。我不知道原因....也许应该报个bug给作者。幸运的是,源码里还有一个 install-static.sh 脚本,我执行了这个脚本,结果顺利编译成功并安装。 现在我的五笔拼音也能够识别中英方式了(英文状态显示A,中文状态显示“五”),太开心了! 我是 ubuntu 18.04 (pop!os) Gnome 3 桌面,五笔拼音输入法 为方便同样用 ubuntu 18.04 的同学,我把编译前的准备工作和编译步骤列在下面: 1. 准备工作 sudo apt install cmake libboost-all-dev libibus-1.0-dev libnotify-dev libgoogle-glog-dev \ libkyotocabinet-dev libleveldb-dev libmarisa-dev libopencc-dev libyaml-cpp-dev 2. clone project and submodules: git clone --recursive https://github.com/rime/ibus-rime.git cd ibus-rime # do this as normal user ./install-static.sh 3. 重启 ibus ibus-damon -dxr Enjoy your favorite input method!
-
My favorite…
Awesome-Linux-Software Awesome-Linux-Software Chinese Currently, my laptop runs Pop! OS 18.04 (Ubuntu). Thanks my boss, he bought me a Windows laptop, so I have the chance to run Linux as my main OS. The following is a list of my favorite apps on my laptop. mp3 player: Audacious browser: Chromium Markdown editor: Typora Text editor: Geany Quick view: gnome-sushi Epub reader: Foliate Console Dictionary: sdcv Console tts: say (in gnustep-gui-runtime package) hardware information: inxi say alternative: gnustep-gui-runtime apt-get install -y audacious chromium typora geany gnome-sushi foliate sdcv gnustep-gui-runtime inxi 3rd software Jetbrains: Rider, Webstorm, Phpstorm, Pycharm Telegram-desktop will update the list when I remember... 😀
-
`git rm --cached `…
There are 3 options, you probably want #3 This will keep the local file for you, but will delete it for anyone else when they pull. git rm cached or git rm -r cached This is for optimization, like a folder with a large number of files, e.g. SDKs that probably won't ever change. It tells git to stop checking that huge folder every time for changes, locally, since it won't have any. The assume-unchanged index will be reset and file(s) overwritten if there are upstream changes to the file/folder (when you pull). git update-index --assume-unchanged This is to tell git you want your own independent version of the file or folder. For instance, you don't want to overwrite (or delete) production/staging config files. git update-index --skip-worktree It's important to know that git update-index will not propagate with git, and each user will have to run it independently.
-
gnome3 how to alt…
gsettings set org.gnome.shell.app-switcher current-workspace-only true
-
status code versus…
同事扔给我一张截图,显示errCode是5,说: 「已注册」的error code是5, errorCode 4开头的会到404页面, 5开头的会到505页面, 我们之前有通过的都是200 我: 不不不 这个和 statusCode 是两码事儿 errCode 是业务错误代码 20x 40x 50x 是返回响应的状态码,通常是框架自动给的,若你的请求参数没有问题,系统通常都会返回状态码 200。但返回200并不意味着一切都对,在我们的项目中,状态码返回 200 并且 success 为 true 或者 errCode = 0才是真的没有问题 同事: 哦,是这样,所以我们还是有statusCode 我: 如果参数根本不符合约定,系统会立即拒绝你,那时候statusCode 会是 40x 如果参数都对,但后端的代码出了bug造成服务器不能正常返回,response会报 50x 表示前端没错,但服务器那边出问题了。 换言之如果是 20x,则你没错,我也没错,成功没有成功是业务逻辑的事情。 如果是 40x 意味着前端送过来的数据不符合后端要求,因此没有被进一步处理,而是被直接拒绝了 50x 表示前端送过来的东西没有大问题,但后端没有处理好出错了 同事: 好的,那我明白了,我记错了,是statusCode才是指到505,404, 我以为都改成了errCode 我: 所以 errCode 5 一定不能一杆子指到 505 页面去。 发现 50x 了去找后端工程师的麻烦一般不会错,如果 40x 了去找后端之前,最好先检查下自己的参数和出错信息 同事: 好 我: status code 和 errCode 本质上是两个东西,errCode是返回数据的一部分 status code 是本次请求返回响应的状态码,可以理解为和返回数据是同一等级的 同事: 那我们的error.response的数据结构有改变吗,我现在还是可以抓取到error.response.status,说明这部分应该是没有改的 我: 这个是axios的约定,并不是后端能够决定的,我们结构的变化,只是response.data 结构的变化是 response.data 吧,我不是很确定,毕竟好久不写 axios 代码了 同事: 是的,但是后来有加了一个data, 我们现在的结构变成这样的 [ Photo ] 我:…
-
Virtualbox MacOS VM…
I successfully ran macOS High Sierra on my Ubuntu 18.04 laptop through VirtualBox. VirtualBox is great ! This article helps! Install Rime on macOS in five minutes download the zip file from latest release from the Tags page on GitHUB unzip the file and install the pkg file go to https://github.com/rime/plum to get the wubi package. git clone https://github.com/rime/plum.git cd plum bash rime-install wubi pinyin-simp The last step, is creating a default.custom.yaml file and putting it in ~/Library/Rime directory. the content in my default.custom.yaml is patch: schema_list: - schema: wubi_pinyin - schema: pinyin_simp
-
How make openvpn…
I met this issue today morning and find the solution from the link I just refered. I have made a few change to the solution to meet my case, this is why I wrote this article. My version of fix-routes.sh #!/bin/sh echo "Adding custom route to $route_vpn_gateway with /24 mask..." # ip route add 10.8.0.0/24 via $route_vpn_gateway ip route add 192.168.178.0/24 via $route_vpn_gateway echo "Removing /1 routes..." ip route del 0.0.0.0/1 via $route_vpn_gateway ip route del 128.0.0.0/1 via $route_vpn_gateway I didn't use ip route add default via $route_vpn_gateway line because I didn't want to route everything through my VPN. Changes to my openvpn profile You can see I added an extra askpass line besides what the author has done. That line was added to help me get ride of the annoyance of entering the password for my private key every time I run the openvpn client program. auth SHA256 auth-nocache verb 3 askpass /home/davidwei/ovpn/pass.txt script-security 2 route-up…
-
Notes for upgrading…
前言 好几年前 123systems.net 打折的时候买了这个vps,年付只要 $3.8。不过配置还说得过去,256M 内存,10G ssd硬盘,每个月有512G流量,而且是 KVM的。那时候我还不知道啥是docker,买这台vps的目标很单纯,就是翻墙。然而当时 123systems.net 的服务非常烂,网络差,北京连过去经常丢包不说,而且还常down机,你提个ticket也要过上好几天才有人搭理。便宜没好货....看在乞丐价的份上,所以大爷我也忍了。不就3块8么,全当喂狗了。(所以后面不久我又从另一家买了一台配置高点的)。后来听说 123systems 被另一家 vps 提供商(对,就是chicago vps)收购了,我想那服务是不是会好点,就又连上去试了下。别说,网络真的稳定多了!也几乎不down机了,于是它就作为我的一个备用翻墙节点用起来了。这也才有了后面的年年续费。 在这台机器上我用了好几年 Ubuntu 14.04,但这台 vps 能够安装的操作系统模板,这么多年就一直没更新过。Ubuntu 最高是14.04, Centos是 6.5, Debian是7.3,Fedora 是 20。后来我玩 Docker 的时候想到这台机器是 kvm 啊,可以装docker的。于是就在上面装了Docker。后来随着 Docker 的一直升级,渐渐地新版 Docker 就不再支持 Ubuntu 14.04了。虽然用旧版也不是不行,但是我动了升级操作系统的念头。虽然模板中只有 14.04, 我总可以自己升级装好的系统嘛。然而升级并不顺利,我曾经磕磕绊绊升到 16.04 用了几天,发现不稳定(经常无故自动关机)就又回到了 14.04。后来经过一个不眠之夜,我装上了 Debian 7 又费了好大劲升级到 Debian 8 jessie。这个还比较稳定,就一直用着,直到昨天晚上。 昨天晚上闲逛的时候,我发现有一个人写了个一键自动重灌vps操作系统的脚本,支持 Debian 和 Centos, 支持指定版本号。 我的心又活络起来了。虽然那篇文间是2018年的,已经挺老了,但我还是打定主意打算试试,万一支持 Debian 10 呢。于是该备份的备份,然后开始尝试。不过作者说了不保证谁都能用,也不保证不丢数据。悲伤的是 他说对了 Debian装上启动不了,Centos…
-
-
x-www-form-urlencod…
This old blog has given a strong answer.
-
How to get coloured…
I haven't used my old MBP 13 for nearly a month. This evening I picked it up and opened the iTerm2 then connected to my home server through ssh. I noticed I get a white-black colored terminal. What's wrong? I remembered it was colorful when I logged into this machine last time using iTerm2 on my MBP 15. Firstly, I checked the version of iTerm2, it was a bit old, so I updated it first. Unfortunately, it doesn't help. I noticed I was using bash instead of zsh on this machine. So I ran chsh and changed the shell from bash to ssh. It also doesn't help. Then I find this answer from stackoverflow.com. A comment in this answer reminded me: I should check and compare the terminal configuration in iTerm2. So I found the secret! Command + , open the preference, then click the profiles tab, then change the Report terminal type from xterm to xterm-256 color, that's it!
-
-
-
-
夏时制即将结束所思所想
这是我对看新西兰站长所发文章「4月5日星期天凌晨3点新西兰夏令时结束」的评论。 这意味着对那些不记录 unix 时间戳而只记录本地时间的系统,如果他们依赖时间排序(因为没有时间戳)的话,夜里2点-3点钟的记录会是紊乱的,因为这段时间会过两遍。显示上看起来没有问题的数据,其实是偏离真实顺序的。比如一篇文章的两个评论,明明是后面的评论回复前面的评论,即可能现回复的评论先显示,然后才显示被回复的评论这种“怪事”。当然了,如果用unix时间戳排序会有另一种问题,数据的顺序是正确的,但显示的本地时间却是紊乱的。可能出现显示一个人在 2:45 分发表了一篇评论,但另一个人却“使用了月光宝盒”回到 2:15 分回复 2:45 分评论的“怪事”。 站长说的对,人们应该调整自己的作息时间,而不是调快或调慢计划仪器。但站长说的又是错的,因为人是愚蠢的动物,自律的人是那么的少,如果依赖们自己调整作息时间,节能效果就会大打折扣。所以“调快调慢”计时设备这个看上去错误的解决方案,即又是最管用的方案。世界就是这么奇妙!
-
We learn from…
We learn from history that we do not learn from history.
-
Defining arrow…
Today I was caught by a bug. I got an error message like "Uncaught (in promise) TypeError: Cannot set property 'users' of undefined" in the following code: import axios from 'axios'; export default { name: "Users", data() { return { users: null }; }, created: () => { axios .get('https://jsonplaceholder.typicode.com/users') .then(res => { this.users = res.data; }) } } Finally, I figured it out by changing the created method definition from an arrow function to a normal function, the following is the correct code: import axios from 'axios'; export default { name: "Users", data() { return { users: null }; }, created() { axios .get('https://jsonplaceholder.typicode.com/users') .then(res => { this.users = res.data; }) } } Do you see the difference?
-
Programming Tips on…
safely convert Unix TimeStamp to string : DateTimeOffset.UtcNow.ToUnixTimeSeconds().ToString(CultureInfo.InvariantCulture.NumberFormat) source DI with parameters in constructor services.AddScoped<SmsSentLogRepo>(s => new SmsSentLogRepo(Configuration.GetConnectionString("sms"))); You should use ConfigureAwait(false) in your library code. source
-
-
客户端 POST 错误,服务端应该回…
刚好今天和一个同事在这个问题上意见不一。 于是翻到了知乎上的这个问题,遗憾的是下面的答案都很水,没有一个深得我心。这很有可能证明我的看法是片面的,管它呢。但它激起了我的表达欲望,我于是键盘侠了下面这一篇。刚好傻子知乎嫌弃我没有认证国内手机号,不让我发表。那我就给自己的 Blog 添块砖吧。 其实这个标题蛮误导人。Post 错误....这种表述再宽泛了。因此有人支持有人反对都不奇怪。多么 Bad 的 Request 算Post错误?每个人有每个人的出发点,这太难达成一致了。 我的观点缩成一句话,只要请求使用 Api 协议(参数个数类型都)正确,我接受甚至有点喜欢响应 200 OK 再给出具体的 ErrorCode 和 ErrorMessage 这种做法。 既然请求能抵达你的 Action 处理方法,至少说明发起请求的一方是有一点点诚意的。如果你再有一点点时间,即使请求不是十全十美,给个不等于0的ErrorCode和一个合理的ErrorMessage是一种绅士的做法。 如果请求格式合法,服务器能够理解,但不能给出满意的结果,或者说 errorCode 不是0的情况,我个人的实践的是返回 200,并给出具体的错误码和错误信息。理由是这个请求不是无效的和非法的,直接扔400 是给前端增加工作量。 即使现在在的框架已经内置了 NotFound() 之类的快捷响应办法, 但只要Route正确到达了我的处理方法,而我又不想偷懒,我的观点也是应尽量给出人类能够理解的出错信息。你总不能因为商品暂时缺货就直接甩404吧! 我不赞成甚至讨厌那些把2xx - 5xx那几十个code 一个个或合理或牵强附会的对号入座,毕竟发明大部分这些Code 的时候还根本没有 Restful 概念。它们都过于宽泛了,是给喜欢偷懒和甩锅的程序员们准备的。即使你使用的前端框架能够自动帮你处理这些code,广泛而大量的使用这些code也只会降低用户的体验而不是改善用户的体验。因为最终用户大部分时候都只能知道错了,但不知道错在哪里。 当然是很个人的看法,欢迎任意批判。
-
-
微生物的力量
微生物的力量
-
Install…
The Vps is too old to get a newer OS from the provider. create /etc/apt/sources.list.d/jessie-backports.list, and fill in the following lines deb http://archive.debian.org/debian jessie-backports main deb http://archive.debian.org/debian jessie-backports-sloppy main apt-get update -o Acquire::Check-Valid-Until=false apt-get install shadowsocks-libev the -o Acquire::Check-Valid-Until=false is the key information. Hope it is helpful. source
-
what I learnt…
1. Use axel instead of wget $ sudo apt install axel axel -n 1000 url 2. Using Nginx as a file server https://www.yanxurui.cc/posts/server/2017-03-21-NGINX-as-a-file-server/ 3. Using supervisor and autossh to keep a tunnel being alive all time [program:autossh] command=autossh -M0 -N -o "ExitOnForwardFailure yes" -o "ServerAliveInterval 15" -o "ServerAliveCountMax 4" -o "ControlPath none" -o "UserKnownHostsFile=/dev/null" -o StrictHostKeyChecking=no -R 18022:localhost:22 -R 18080:localhost:80 -R 18443:localhost:443 user_name@user_ip_or_domain autostart=true autorestart=true startretries=999 redirect_stderr=true stdout_logfile = /var/log/supervisor/autossh.log stdout_logfile_maxbytes = 10MB source 4. Using shadowsocks + polipo to implement http/https proxy in Ubuntu 18.04 Guide in English 中文指南 How to avoid conflicts between dnsmasq and systemd-resolved? 5. Show System Info / Hardware Details on the Command Line (Ubuntu) $ sudo apt…
-
Install Debian 10…
I bought a VPS from http://virmach.com five years ago. It had been running Ubuntu 14.04 OS for over five years. It was stable but a bit out-of-date. Firstly I tried the Ubuntu 18 template, which was builtin by the cheap Vps provider (virmach). Unfortunately, I cannot log into the system after the OS installation, it always automatically refused my ssh connection, and continuously told me my password is wrong through the HTML5 vnc console. It's already very late yesterday evening, I was tired and wanted to give up. Then I found the Debian 10 Server X64 ISO file on the cdrom TAB. I love Debian, so I decided give it a go before going to bed. That's a very familiar and happy process. I just want to record the main steps of the process as a memo. Here it is mount the ios file you needed setup the boot sequence to CDROM first reboot your VPS and open the HTML vnc pannel Install the OS setup the boot sequence to HDD only Reboot
-
Shadowsocks for…
“把文档写详细点会死吗?” 大概率会吧。虽然我来写未必会更好,但我还是要批评 ShadowsocksX-NG 和 Shadowsocks for windows 的项目的 README.md 文件。 起因:我妹夫访问我的翻墙服务器实在是太脏话慢了。虽然我这会身在墙外,然而身为墙国人,祖国总会给机会锤炼你的翻墙技术。所以,本着药不能停的原则,我又拣起了高速翻墙的技能。 下面是我最后成功完成配置的具体步骤。 在你的服务器上搭好 Shadowsocks 和 Kcp server。 去 shadowsocks/windows 下载最新版,并解压缩到你打算放置的地方,比如 Desktop\shadowsocks。 去这里 下载Kcptun 最新版,把解压出来的 client_windows_amd64.exe 放到刚才放置 shadowsocks.exe 文件的同一文件夹。 配置shadowsocks 假定你的shadowsocks配置是: { "server":"0.0.0.0", "server_port":8964, "local_port":1080, "password":"your-secure-password", "timeout":60, "method":"chacha20-ietf-poly1305" } 假定你的 Kcptun server 配置是: ./server_linux_amd64 -t 127.0.0.1:8964 -l :28964 -mode fast3 -key chrd5 -sockbuf 16777217 -nocomp -dscp 46 -crypt none 则你的Shadowsocks for windows 需要如下配置: Server IP: your-server-ip-or-domain Server Port: 28964 Password: your-secure-password Encryption: chacha20-ietf-poly1305 Plugin Program: client_windows_amd64.exe…
-
Guide for…
There's little information on the internet about configuring the Kcptun plugin for ShadowsocksX-NG. It is necessary to write a blog to record the process that how I configured it, as it is not only helpful for myself later, and it could help the others who need it. Let's start. Download the latest ShadowsocksX-NG release and install it on your macOS (It is v1.9.3 when I wrote this article. If you meet issues with newer version, maybe it is worth to try the v1.9.3 release), it is the easiest step. You won't meet any problems at this stage. The following are samples for shadowsocks server configuration and Kcptun server configuration: Sample for the shadowsocks-libev config.json { "server":"0.0.0.0", "server_port":8964, "local_port":1080, "password":"your-secure-password", "timeout":60, "method":"chacha20-ietf-poly1305" } Sample for the Kcptun server configuration ./server_linux_amd64 -t…
-
dotnet-ef summary
Instal dotnet-ef dotnet tool install -g dotnet-ef --version 3.1.1 Add Migration dotnet-ef migrations add migration-name [-c SomeDbContext] Update Database dotnet-ef update database [migration-name] [-c SomeDbContext] Revert All Database Update dotnet-ef update database 0 [-c SomeDbContext]
-
Windows is still a…
I would like to give Windows 10 a try after the promise 12 years ago. I got a job a month ago, and I need to write ASP.NET Core application for this job. Though Asp.NET core and C# taste good, windows 10 makes me upset once more. Twelve years ago, that was the year 2008, I left windows XP for Arch Linux. I promised I will never use Windows as my main OS in the future at that time. My boss bought me an excellent DELL laptop with 32GB memory and equipped a 15" 4k screen. Yes, it is preinstalled with Windows 10 Professional. Today I have installed autojump, Wrox on windows 10, and changed a few settings here and there to reach my requirements. I know I may insist on Windows for a bit long time because I need the job to live and I should give Windows another go. I hope I can feel better later. The Windows 10 system does improve a lot than its previous version, however, the feeling, I cannot tell. Another long way to go, or it may never be perfect. Good luck to me, and to windows.
-
Windows 10…
去 https://rime.im/ 下载安装 右键点击“中”字图标,在弹出菜单中点击“输入法设定” 在弹出窗口中点击“获取更多输入方案”,这时会弹出一个 cmd 窗口让你输入需要添加的方案 先输入 rime-wubi 回车,wubi就自动装上了 再输入 rime-pinyin-simp 回车,拼音也装上了。 回车并随手关掉这个 cmd 窗口,加输入法的工作就完成了。 回到刚才点击 “获取更多输入方案” 的窗口,勾掉你不需要的那些七七八八的输入法,选中刚刚添加上的“五笔拼音”,然后再点一下 “中”按钮 (不是右下角的“中”图标),选择一个你喜欢的风格。 Mission Accomplished! Enjoy 你的五笔拼音吧! (By the way,写此Blog时我用的小狼毫版本是 0.14.3 )
-
CentOS 7…
[root@centos7 ~]# firewall-cmd --permanent --add-port=100/tcp success [root@centos7 ~]# firewall-cmd --reload success From how-to-open-a-port-in-centos-7-with-firewalld
-
Tips for dotnet…
On the Windows platform, the secrets file are saved at /Users/yourusername/%APPDATA%/Microsoft/UserSecrets/{projectid}/secrets.json; On Linux/Mac platform, the secrets file are saved at ~/.microsfot/usersecrets/{projectid}/secrets.json. Believe it or not, .NET Core console application doesn't support user secrets in its default configuration. You can use dotnet command set or list your secrets, but actually, you cannot get its value through the IConfiguration object. What's a shame! Finally, you may want to import secrets from one project to another project. I just wrote a small single-file script to save myself. Certainly, you can also use it if you like. The tool has been published on Github, here it is.
-
SSH Config Tips:…
Suppose you have a local laptop without a public IP named A (192.168.1.7) and a remote server that has a public IP name named B (172.16.0.77) and another remote server C (172.16.0.78) which is in the same LAN with B. You can connect to B directly by ssh, and you cannot connect to C directly because C doesn't have an external IP address. You want to map port 5001 on A to the same port on B to make you local service temporarily public), you should add this line in laptop A's .ssh/config file: RemoteForward 5001 localhost:5001 #here localhost refers to A You want to map port 3306 on Host B (Remote machine) to the 3306 port on Host A (your laptop), you should add this line in laptop A's .ssh/config file: LocalForward 3306 localhost:3306 # here localhost refers to B You want to map port 22 on machine C to the 8045 port on A, add this line: LocalFoward 8045 172.16.0.78:22 Finally, the following code shows the final configuration in your ~/.ssh/config file Host B HostName b.somedomain.com…
-
Methods for…
[HttpPost] public IActionResult Fill([FromBody] dynamic data) { string amount = data.amount.GetString(); } [HttpPost] public IActionResult Fill() { string dataStr = new StreamReader(Request.Body, Encoding.UTF8).ReadToEnd(); var data = JObject.Parse(dataStr); string amount = data.value.amount; } [HttpPost] public IActionResult Fill([FromBody] YourType data) { string amount = data.amount; }
-
First post
I just finished the installation for the Chryp lite blog system. I met a small issue related to its compatibility with MySQL version 8 but I managed to resolve it. Happy! The issue is that "groups" word has become a reserved keyword in MySQL 8.x, and unfortunately, there's a table in this blog system named "groups" too. I first tried to use "``" to encapsulate the table name and I failed quickly because there are too many places using the table name. Fortunately, the install program supports me to add a table prefix for all tables. So it was resolved by simply adding a table prefix! Happy!