Home » Posts tagged "shell"

comm 的用法...

最近在 Twitter 上看到不少 shell 指令的說明,這則 tweet 是講 comm 這個指令:

1 是只有第一個檔案有的內容,2 是只有第二個檔案有的內容,而 3 是兩者都有的內容,而且檔案內容需要排序過。

當你 -1 時表示幹掉 1 的部份,-2 代表幹掉 2 的部份,-3 代表幹掉 3 的部份,然後可以疊起來用... 不過平常還是用 diff 比較多,每次看到 comm 的說明都是玩過再熟悉一下,然後就丟著 XD

在 CLI 下開關以及查詢 EC2 的狀態...

有時候需要開 Ubuntu 測試東西,會在 AWS 上開 EC2 起來測試,但開 console 太麻煩了,寫幾個 function 丟進 shell script 裡面比較乾脆。其中查詢 Ubuntu AMI 的程式出自「How do I know what Ubuntu AMI to launch on EC2?」這邊。

ec2.ls() 裡,我的 jq 版本比較舊,不過不影響我的 copy & paste,所以就沒有 hack 他了。新版的應該可以多加上 | @tsv 變成 tab 隔開 (沒測過,查資料時查到而已)。

ec2.run() 裡,我這邊是先到 console 上查出 security group 與 subnet 的 id,然後這邊 hard code 進去。我的預設是開 t2.medium,臨時要指定的話就 ec2.run t2.nano 就可以改開 t2.nano 了,不過要注意的是,這邊程式在查詢時的條件是 hvm:ebs,換的時候要注意 image 相容性...

# AWS-related
function ec2.ls() {
    aws ec2 describe-instances | \
        jq -c -M '.Reservations[] | .Instances[] | [.InstanceId, .InstanceType, .PublicIpAddress]'
}

function ec2.rm() {
    local INSTANCE_ID=${1:i-xxxxxxxxxxxxxxxxx}
    aws ec2 terminate-instances --instance-id ${INSTANCE_ID}
}

function ec2.run() {
    local INSTANCE_TYPE=${1:-t2.medium}
    aws ec2 run-instances --image-id $(ec2.ubuntu_ami()) --key-name gslin --security-group-ids sg-xxxxxxxx --instance-type ${INSTANCE_TYPE} --subnet-id subnet-xxxxxxxx
}

function ec2.ubuntu_ami() {
    curl -s "https://cloud-images.ubuntu.com/locator/ec2/releasesTable" | \
    sed '$x;$G;/\(.*\),/!H;//!{$!d};$!x;$s//\1/;s/^\n//' | \
    jq -c '.aaData[] | select(contains(["16.04", "us-east-1", "hvm:ebs"]))' | \
    grep -o 'ami-[a-z0-9]\+' | \
    head -1
}

這種工具自己用的順手比較重要,要什麼功能自己改自己加...

話說 Ubuntu 網站上的 JSON 居然吐出 malformed data (trailing comma),這是自己 printf() 之類硬幹出來的嗎... XD

shellcheck

在朋友的 Twitter 上看到 shellcheck (ShellCheck, a static analysis tool for shell scripts) 這個專案:

可以看到有點像是 lint 工具,給了不少建議:

而且看起來已經發展很久了... 在各大 distribution 內都可以直接裝。

Bash 裡處理 PID file 的方式...

看到「Age comparison in Bash for files and processes」後查了一些資料,如果在不使用外部程式處理的話,的確是多做了不少事情。

這是 Bash-ot 的說明:

file1 -ot file2
       True if file1 is older than file2, or if file2 exists and file1 does not.

而這是 test (也就是 [ 這隻程式) 對 -ot 的說明:

FILE1 -ot FILE2
       FILE1 is older than FILE2

多了檔案是否存在的檢查...

另外可以參考「What's the difference between [ and [[ in Bash?」這邊的說明,Bash 的 [[ 是 Bash 特有的加強版,而 [ 則是用系統的 test 運算。

各家 glob 的效能...

在「Glob Matching Can Be Simple And Fast Too」這邊看到在分析 (a.*)nb 這樣的 pattern 的效能 (像是 a.*a.*a.*b 這樣的東西),第一波先測 shell,結果發現有趣的現象:

那個 csh 是怎麼了 XDDD

Looking at the source code, it doesn’t attempt to perform glob expansion itself. Instead it calls the C library implementation glob(3), which runs in linear time, at least on this Linux system. So maybe we should look at programming language implementations too.

再來是看各程式語言:

各家實做方式不一樣 XD

然後文章裡有提到這個方式是之前蠻常見的 DoS 技巧,用很少的資源就可以吃光你的 CPU resource... 另外也提到了可能的解法,就是限制星號的數量:

At the very least, most FTP servers should probably reject glob patterns with more than, say, 3 stars.

後面演算法的部份也是很有趣的主題...

另外一套用 shell script 寫的 ACME client (或者說 Let's Encrypt client)

acme.sh 是另外一套用 shell script 寫的 ACME client,由西安的 Neilpang 寫的。我也包成 Ubuntu PPA 了:「PPA for acme.sh」。

我建議的用法是先建立 /etc/acme.sh,把各種設定都放到這個目錄裡面,然後用這樣的指令執行:

$ sudo acme.sh --issue -d www.example.com -w /srv/www.example.com/webroot/ --home /etc/acme.sh/

不過 acme.sh 有個問題,沒有將檔案與目錄權限處理好... 我申請完後發現目錄是 drwxr-xr-x,而 key 是 -rwxr-xr-x,這樣會有安全性的問題,需要自己再修改。

letsencrypt.sh 改名為 dehydrated

Twitter 上被提醒 letsencrypt.sh 改名為 dehydrated 了:

在「renamed project to dehydrated and main script to dehydrated.sh」這邊可以看到對應的 commit。

原有的 letsencrypt.sh PPA 仍然會保留,但不會再更新 (維持 letsencrypt.sh 所發行的最後一個版本,0.3.0),要使用的人請使用 dehydrated PPA,目前是 0.3.1。

原先的設定要搬過去的話有不少要改:

  • /usr/sbin/letsencrypt.sh -> /usr/sbin/dehydrated (執行檔)
  • /etc/letsencrypt.sh/ -> /etc/dehydrated/ (設定檔與 cert & key 的目錄)
  • /var/www/letsencrypt/ -> /var/www/dehydrated/ (challenge 的目錄)

既然 cert & key 的目錄也換了,apachenginx 的設定也要記得換,我這邊還要多換 Postfix 的設定...

接下來要改對應的教學文件...

更新 letsencrypt.sh 的 PPA

letsencrypt.sh 是個用 shell script 實作出來的 letsencrypt/acme client,可以對 Let's Encrypt 申請出 SSL certificate。相較於官方後來交接給 EFFCertbot,我還蠻推薦使用純粹只需要 shell script 的 letsencrypt.sh...

由於作者沒有發出新的 release tarball,加上目前最新的 release 的程式也已經無法使用,所以昨天花了點時間更新了 letsencrypt.sh 的 PPA,就弄了一個 0.2.0.20160822 (版本號碼大於目前的 release 版本的 0.2.0):「PPA for letsencrypt.sh」。

與 0.2.0 版相比有個 BC-break 的地方:新版的 config 改檔名了 (從 config.sh 變成 config),如果之前有設定的話要記得改:

$ cd /etc/letsencrypt.sh/
$ sudo mv config.sh config

也趁機把之前建立 source package 的 build.sh 改成可以吃 git hash 或是 tag name 的版本,這樣需要針對特定版本產生 source package 也簡單多了。

中國富豪搬移財產的方法

中國因為一年只讓國民帶五萬美金出國,於是中國的富豪就想到各種方法搬移財產,其中 Boing Boing 介紹的這個方法真的頗棒的 XDDD:「Chinese millionaire sues himself through an offshore shell company to beat currency export controls」。

先成立一家空殼公司,然後再用空殼公司告自己的公司,藉由法院的賠償程序,避開了個人財產的轉移限制:

But there's a better way: for a small sum, you can just set up an offshore shell company, direct it to sue a Chinese company you own, throw the lawsuit, and then, oh well, I guess there's nothing for it but to send a bunch of cash to your shell company, exempted from export controls, in the form of court-ordered damages.

這方法 XDDD

Archives