let scope

var id = 2;
function x() {
  console.log(id);  //reference error 
  let id = 3;
  console.log(id); 
}
x();

雖然let引入block scope,避免了var的variable hoisting,但是須注意

https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/let

let bindings are created at the top of the (block) scope containing the declaration, commonly referred to as "hoisting". Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated. Accessing the variable before the initialization results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.

所以上面的id會引發reference error
但是比較var範例

var id = 2;
function x() {
  console.log(id); 
  //undefined,因為下面定義的variable hoisting
  var id = 3;
  console.log(id); 
}
x();
Posted in nodejs | Leave a comment

JSON5

JSON5 (https://spec.json5.org)

https://github.com/json5/json5

nodejs讀取設定檔常使用json格式(http://www.ecma-international.org/publications/files/ECMA-ST/ECMA-404.pdf, https://tools.ietf.org/html/rfc8259), 但是json在描述時限制較多,例如在key要雙引號,字串要用雙引號不能用單引號,不能有註解等。

因此可讀性變差,JSON5主要將ECMAScript 5.1語法引入,整體看來,syntax對於熟悉javascript的使用者更友善

幾個比較大的差異

  • key不一定需要引號(根據ECMAScript 5.1 IdentifierName規則)
  • Objects may have a single trailing comma.
  • Arrays may have a single trailing comma.
  • Strings may be single quoted/支援多行/支援 \x的escape (U+0000 through U+00FF)
  • String更寬容的escape字元包含
    • JSON:All Unicode characters may be placed within the
      quotation marks, except for the characters that MUST be escaped: quotation mark, reverse solidus, and the control characters (U+0000 through U+001F).
    • JSON5:All Unicode characters may be placed within the quotation marks, except for the characters that must be escaped: the quotation mark used to begin and end the string, reverse solidus, and line terminators.
  • Number支援更廣泛的表示方式(eg. hex, + sign), inf, NaN
  • Single and multi-line comments are allowed
  • 更寬容的whitespace支援 (JSON只支援0x20, 0x09, 0x0A, 0x0D)
     
Posted in nodejs | Leave a comment

find files modified in 1 day

找出最近更動的檔案(1 day),這在清查設定檔或是程式被更動時方便使用的指令

find . -mtime -1 -ls

參考:
https://stackoverflow.com/questions/16085958/scripts-find-the-files-have-been-changed-in-last-24-hours

Posted in System Administration | Leave a comment

rootpath module

https://www.npmjs.com/package/rootpath

//BEFORE

// from $HOME_PROJECT/lib/math/
var myLib = require('../myLibrary');
var myUtils = require('../../utils/myUtils');
var myTest = require('../../test/myTest');
//AFTER

// from $HOME_PROJECT/lib/math/

require('rootpath')();

var myLib = require('lib/myLibrary');
var myUtils = require('utils/myUtils');
var myTest = require('test/myTest');

在vsphere rest sdk sample看到的一個用法,這對於library更動目錄時不需要再改寫require path非常方便,但是須注意webpack使用時,應該用webpack resolve configuration來處理

Posted in nodejs | Leave a comment

git tips

delete a tag locally and remotely

git push –delete origin tagName
git tag -d tagName

Posted in System Administration | Leave a comment

socks5 proxy

SOCKS5 rfc可參考1996年 rfc 1928 (其他: rfc 3089 socks based gateway)
須注意socks5本身並未加密,最好是透過ssh port forwarding

SOCKS5 proxy設置最簡單的方式 是

putty ssh tunnel

ssh -D 1080 user@server

注意port number 1024以下的權限問題(root)

-D [bind_address:]port
Specifies a local “dynamic” application-level port forwarding. This works by allocating a socket to listen to port on the local side, optionally bound to the specified bind_address. Whenever a connection is made to this port, the connection is forwarded over the secure channel, and the application protocol is then used to determine where to connect to from the remote machine. Currently the SOCKS4 and SOCKS5 protocols are supported, and ssh will act as a SOCKS server. Only root can forward privileged ports. Dynamic port forwardings can also be specified in the configuration file.

socks5 proxy設定成 127.0.0.1:1080

ssh tunnel with SOCKS5

如果要透過跳轉兩台server連接時(例如server2只允許server1連入)
client -> socks5 -> server1 -> socks5 -> server2 -> destination

在server1上先建立SOCKS5 proxy to server2
ssh -D 1080 server2
在client端建立ssh tunnel local port forwarding
ssh -L 1080:localhost:1080

#ss5 install
yum groupinstall 'Development Tools'
yum install gcc automake autoconf libtool make pam-devel yum-utils openldap-devel openssl-devel
mkdir /opt/ss5
cd /opt/ss5
wget http://sourceforge.net/projects/ss5/files/ss5/3.8.9-8/ss5-3.8.9-8.tar.gz
tar -zxf ss5-3.8.9-8.tar.gz
cd ss5-3.8.9
./configure
make
make install
cd /etc/opt/ss5/

設定全帳密認證
/etc/opt/ss5.conf
加上
auth 0.0.0.0/0 – u
permit u 0.0.0.0/0 – 0.0.0.0/0 – – – – –

帳密格式:
/etc/opt/ss5/ss5.passwd
ACCOUNT PASSWORD

啟動:
ss5 -u root -b 0.0.0.0:1080

測試:
curl –socks5 PROXY_IP:1080 –proxy-user user:password 遠端URL

參考: https://www.proxyrack.com/how-to-setup-a-socks5-proxy-server-using-ss5-on-centos7/

Posted in System Administration | Leave a comment

callback style與promise的整合

在需要呼叫多次callback時,async await可改善callback hell的現象
而nodejs在8.x支援原生的async await,在設計callback api時,可設計成同時支援舊的callback style與新的promise style,這樣一來可以使api同時支援’async’ library與async/await語法

作法1:

function delay(ms, cb){
  var func = delay;
  if(cb === undefined){
    //檢查是否有callback,如果沒有返回promise 
    return new Promise(function(resolve, reject){
      func(ms, function(err, data){
        if(err) return reject(err);
        resolve(data);
      });
    });
  }
  setTimeout(function(){ cb(null, Date.now()); }, ms); 
}

作法2: 參考: https://zaiste.net/node_js_functions_simultaneously_supporting_callbacks_promises/

function delay(ms, cb = function(){}){
  var func = delay;
  return new Promise(function(resolve, reject){
    setTimeout(function(){
      resolve(Date.now());
      cb(null, Date.now());
    }, ms);
  });
}

使用:

//callback用法
delay(2000, function(err, data){
  if(err){
    console.log('error', err);
  } else {
    console.log(data);
  }
});
//promise then用法
delay(2000).then(data => console.log(data)).catch(err => console.log('error', err));

//async await用法,await要包在async function內
(async function(){
  try{
    var resp = await delay(2000); //resolve時才往下走
    console.log(resp);
  }catch(e){
    console.log('error', e);
  }
})();
Posted in nodejs | Leave a comment

mysql shell clear screen

mysql>system clear

system呼叫系統shell執行

Posted in System Administration | Leave a comment

express error handler

在 https://github.com/expressjs/express/blob/master/lib/router/index.js#L46

function router(req, res, next) {
router.handle(req, res, next);
}

express router不會catch error,所以error handler定義在router內無法作用
要直接定義在app那層,參考doc Error-handling middleware

app.use(function(err, req, res, next) {
console.error(err.stack);
res.status(500).send('Something broke!');
});

另外是順序也很重要,next(err)會依照順序往下找,因此error handler應該定義在最後面

參考來源:
https://stackoverflow.com/questions/45431595/express-error-handler-inside-router-doesnt-work

Posted in nodejs | Leave a comment

pkg-config整理

config search path: (search for .pc)

pkg-config --variable pc_path pkg-config

/usr/local/lib/x86_64-linux-gnu/pkgconfig:/usr/local/lib/pkgconfig:/usr/local/share/pkgconfig:/usr/lib/x86_64-linux-gnu/pkgconfig:/usr/lib/pkgconfig:/usr/share/pkgconfig

PKG_CONFIG_PATH

範例

prefix=/usr
exec_prefix=${prefix}
libdir=/usr/lib/x86_64-linux-gnu
includedir=${prefix}/include

Name: x264
Description: H.264 (MPEG4 AVC) encoder library
Version: 0.148.2643 5c65704
Libs: -L/usr/lib/x86_64-linux-gnu -lx264
Libs.private: -lpthread -lm -ldl
Cflags: -I${prefix}/include

pkg-config exits with a nonzero code if it can’t find metadata for one or more of the packages on the command line

Libs: link flags
Libs.private: Private libraries are libraries which are not exposed through your library, but are needed in the case of static linking
Cflags: preprocessor flags, compiler flags, 不需要加上required package flags (pkg-config會處理)

常見用法: (配合autotools or Makefile使用)
–cflags, –libs

CXXFLAGS += $(shell pkg-config --cflags libavformat libavcodec libavutil)
LDFLAGS += $(shell pkg-config --libs libavformat libavcodec libavutil)

Posted in Library | Leave a comment