2015年11月18日 星期三

Git - 儲存帳號密碼

作業系統:Windows

事件狀況:使用 Git 指令,登入伺服器需要輸入帳號密碼,如果遇到很多 submodule 時,動作更是繁瑣。

解決辦法:
  1. 設定環境變數 HOME。
    $setx HOME %USERPROFILE%
  2. 在家目錄下新增 _netrc 檔案。
    machine hostname1
    login login1
    password password1
    machine hostname2
    login login2
    password password2

2015年11月1日 星期日

Linux - 使用 grep 搜尋檔案內容

尋找單一檔案中的特定字串

 grep -n "keyword" /directory/file

尋找資料夾中含有特定字串的檔案

 grep -rl "keyword" /directory/*

尋找資料夾中含有特定字串的檔案,並標明字串位置

grep -rn "keyword" /directory/*

2015年10月2日 星期五

2015年9月25日 星期五

Git - 重新命名 branch

重新命名
$git branch -m OLD_NAME NEW_NAME

上傳新名稱 branch 到遠端
$git push origin NEW_NAME:NEW_NAME

刪除遠端的舊名稱 branch
$git push origin --delete OLD_NAME

2015年9月24日 星期四

Git - 同步 github 到 gitlab

下載 repository 到本地端
$git clone https://github.com/username/repo-name.git
進入 repository 目錄
$cd repo-name
增加遠端 repository
$git remote add gitlab https://gitlab.com/username/repo-name.git
上傳 commit
$git push -f --tags refs/heads/*:refs/heads/*
 

2015年9月15日 星期二

Linux - vim 使用技巧

替換檔案中的 tab 為 whitespace

如果有設定好 .vimrc,進入 vim 的命令模式輸入
:retab

搜尋並取代 

進入命令模式,輸入
:1,$s/hello/hi/g
將字串 hello 換成 hi。1,$表示從頭到尾。

2015年9月6日 星期日

Git - rebase 還原版本

如果要還原到前一個版本
$git rebase -i HEAD~2
如果要還原到前三個版本
$git rebase -i HEAD~4

接著,刪除不要的版本 (整行 pick),
最後,送交到遠端
$git push origin +master



2015年9月2日 星期三

Git - branch

下載遠端 branch
git clone -b BRANCH_NAME REMOTE_GIT_REPO_URL


下載遠端 branch 至本地指定目錄
git clone REMOTE_GIT_REPO_URL -b BRANCH_NAME DIR


新增本地 branch
git checkout -b BRANCH_NAME


上傳至遠端 branch
git push origin BRANCH_NAME

Git - submodule 的應用

下載有 submodule 的 git repository

git clone --recursive REMOTE_GIT_REPO_URL


加入其他 git repository 作為 submodule

git submodule add REMOTE_GIT_REPO_URL SUBMODULE_NAME



加入其他 git repository 且指定 branch 作為 submodule

git submodule add -b BRANCH_NAME REMOTE_GIT_REPO_URL SUBMODULE_NAME


移除 submodule

git rm SUBMODULE_NAME
rm -R SUBMODULE_DIR


上傳 submodule 至遠端

git checkout BRANCH_NAME
git add -A .
git commit -m "UPDATE_MESSAGE"
git push origin BRANCH_NAME


查詢 submodule 資訊

git submodule

2015年8月26日 星期三

Linux - vim 的 tab 設定

1. 在使用者目錄下建立並編輯檔案
$vim ~/.vimrc
2. 輸入以下內容
set tabstop=4
set shiftwidth=4
set softtabstop=4
set expandtab
set smarttab

2015年8月25日 星期二

Docker Compose - 操作說明

安裝 Docker Compose 程式

安裝 Python

$sudo apt-get install -y python python-pip

安裝 Docker Compose

$sudo pip install -U docker-compose


下載 services 的 images

$sudo docker-compose pull


建立 containers 並啟動 services

$sudo docker-compose up -d


啟動 services

$sudo docker-compose start


停止 services

$sudo docker-compose stop


重新啟動 services

$sudo docker-compose restart


移除 services 的 containers

沒有停止的 service 是無法移除 container
$sudo docker-compose rm -f


查詢 services 的狀態

$sudo docker-compose ps


查詢 services 的 log

$sudo docker-compose logs


啟動單一 service

假設 docker-compose.yml 中有定義一個 web service
$sudo docker-compose up -d web
操作單一 service 的方式也可以套用到其他指令上,只要在指令最後面加上 service 名稱。


指定 YAML 檔案並啟動 services

假設 YAML 檔案為 init.yml
$sudo docker-compose -f init.yml up -d
指定 YAML 檔案的方式也可以套用到其他指令上,只要在 docker-compose 後面加上 -f 的選項並指定檔案。

Docker - 操作說明

在 Ubuntu 14.04 安裝 Docker

$wget -qO- https://get.docker.com/ | sh

// If you would like to use Docker as a non-root user, you should now consider
// adding your user to the "docker" group with something like:
$sudo usermod -aG docker your-user


在 CentOS 6.5 或更新版本安裝 Docker

$sudo yum update
$curl -O -sSL https://get.docker.com/rpm/1.7.1/centos-6/RPMS/x86_64/docker-engine-1.7.1-1.el6.x86_64.rpm
$sudo yum localinstall --nogpgcheck docker-engine-1.7.1-1.el6.x86_64.rpm
$sudo service docker start
$sudo chkconfig docker on


測試 Docker 是否啟動

$sudo docker run hello-world


從 Docker hub 下載 Docker image (範例:最新版 Ubuntu)

$sudo docker pull Ubuntu
或是
$sudo docker pull ubuntu:latest
預設 tag 是 latest,這兩種寫法的執行結果是一樣的。


從 Docker hub 下載 Docker image (範例:指定 Ubuntu 14.04)

$sudo docker pull ubuntu:14.04
Docker image 的格式是 image:tag ,ubuntu 是 image 名稱,14.04 是 tag 名稱。


從 Docker hub 下載 Docker image (範例:Minimum 的 oracle-java 8)

$sudo docker pull minimum/oracle-java:8
minimum/oracle-java 是 image 名稱,8 是 tag 名稱。


查詢本機上的 Docker images

$sudo docker images


刪除本機上的 Docker image

舉 Ubuntu 14.04 為例,
$sudo docker rmi ubuntu:14.04
或是利用 images 的指令取得 image ID,
$sudo docker rmi d2a0ecffe6fa
或是簡單寫出 image ID 的前幾碼,
$sudo docker rmi d2a
此方法請小心誤刪其他有相同前幾碼的 images


刪除本機上的多個 Docker image

舉 Ubuntu 14.04 和 hello-world 為例,
$sudo docker rmi ubuntu:14.04 hello-world


強制刪除本機上的 Docker image

舉 Ubuntu 14.04 為例,
$sudo docker rmi -f ubuntu:14.04
此方法適用於有某一個 container 使用這個 image 建立,但是該 container 並不會一併被刪除。



建立 Docker container 並啟動

舉 Ubuntu 14.04 為例,
$sudo docker run -ti ubuntu:14.04
沒有指定 container 名稱時,Docker engine 會隨機命名。
也可以指定 container 名稱,例如指定為 ubuntu_instance,
$sudo docker run -ti --name ubuntu_instance ubuntu:14.04
建議全部指定 container 名稱,方便記憶與反覆進行 container 操作。

run 指令的參數介紹
-tTTY模式。
-i互動模式,可以和 container 進行指令操作。
-d後台模式,不會將 container 中的訊息輸出到 terminal。
-p host_port:container_port指定 container 的連接埠,例如 -p 8080:80,將 host 端 port 8080 導向到 container 的 port 80。
-e variable=value指定環境變數,例如 -e DB_HOST=mysql,在 container 中能存取 DB_HOST 這個環境變數。
-v host_dir:container_dir指定 container 的 volume,例如 -v /home/user/data:/data,container 的 /data 目錄是連結到 host 端的 /home/user/data 目錄。
--volumes-from name使用其他 container 的 volume,例如 --volumes-from web,將 container web 使用的 volumes 都連結到現在這個 container。
--link name[:alias]連線其他 container,例如 --link database:db,在 container 中能使用 db 作為 domain name。
--privileged=true如果要存取 container 中的系統資料夾,需要加這個參數提升權限。
--sig-proxy=false按下 Ctrl+C 只會中斷 container 中運行的程序,不會離開 container。可以按下 Ctrl+P 再按下 Ctrl+Q 離開 container,且 container 不會停止。
--restart=(no|on-failure|always)自動重新啟動 container,always 這個值在 Docker engine 啟動時也會有效。
--rm=truecontainer 停止時,自動刪除 container。


離開 Docker container

按下 Ctrl+C 可以從 container 中離開,或是在 container 中輸入 exit 指令離開。


查詢 Docker container

$sudo docker ps
可以查詢正在運行的 container ID、建立時間、狀態和名稱。
也可以查詢所有包含停止的 container,
$sudo docker ps -a


停止 Docker container

假定有個正在運行的 container ,其名稱是 ubuntu_instance,
$sudo docker stop ubuntu_instance


啟動 Docker container

假定有個停止的 container,其名稱是 ubuntu_instance,
$sudo docker start ubuntu_instance
start 指令的參數介紹
-a進入 container。
-i互動模式,可以和 container 進行指令操作。


刪除 Docker container

假定有個停止的 container,其名稱是 ubuntu_instance,
$sudo docker rm ubuntu_instance
假定有個正在運行的 container,其名稱是 ubuntu_instance,
$sudo docker rm -f ubuntu_instance
也可以一次刪除多數個 container,
$sudo docker rm ubuntu_instance_1 ubuntu_instance_2


進入 Docker container

假定有個正在運行的 container,其名稱是 ubuntu_instance,
$sudo docker attach ubuntu_instance

也可以加上參數 --sig-proxy=false。


查詢 Docker container 的訊息記錄

假定有個 container,其名稱是 ubuntu_instance,
$sudo docker logs ubuntu_instance
可以指定顯示行數
$sudo docker logs --tail=10 ubuntu_instance


查詢 Docker container 的組態設定

假定有個 container,其名稱是 ubuntu_instance,
$sudo docker inspect ubuntu_instance
可以查詢網路設定、連接埠設定、volume設定等。


將 Docker container 變成 Docker image

假設現有一個 container 為 hello,要變成 hello-world 第二版,
$sudo docker commit hello hello-world:2
也可以用來保存 container 內的資料。


刪除全部狀態為 Exited 的 Docker containers

$sudo docker rm -f `sudo docker ps -aq --filter="status=exited*"`


刪除全部無標籤的 Docker images

$sudo docker rmi `sudo docker images --filter "dangling=true" -q --no-trunc`


匯出並打包 Docker image

假定有個 image,其名稱是 hello-world,匯出成 docker-hello-world.tar。
$sudo docker save -o docker-hello-world.tar hello-world


解包並載入 Docker image

$sudo docker load --input docker-hello-world.tar

2015年7月15日 星期三

Chromebook - 移除SSH金鑰

作業系統:Chrome

事件狀況:
伺服器SSH金鑰有更換,或是SSH金鑰衝突,要從Chromebook使用SSH登入時,會發生無法登入的情況。

解決方法:

  1. 開啟SSH
  2. https://chrome.google.com/webstore/detail/secure-shell/pnhechapfaindjhompbnflcldabbghjo

  3. Ctrl + Shift + J
  4. 在Console輸入
  5. > term_.command.removeAllKnownHosts()

2015年6月22日 星期一

GCE - 收到"insufficient permission"訊息

在Google Compute Engine中操作gcloud指令時,
如果收到"insufficient permission"訊息,
請先輸入
$gcloud auth login 
 ,接著根據訊息操作,
就能正常原本想要操作的指令。

2015年6月14日 星期日

Linux - 查詢系統資訊

查詢系統位元

$file /bin/bash

查詢kernal版本

$uname -r

查詢系統版本

$cat /etc/issue

2015年4月9日 星期四

C語言 - 清空stdin

不能使用fflush(),無效。
要使用
int c;
while((c = getchar()) != '\n' && c != EOF);

2015年3月24日 星期二

Python - int, hex, char, string的轉換

  • Int to Hex
    hex(97)  # '0x61'
  • Int to Char
    chr(97)  # 'a'
  • Int to String
    str(97)  # '97'
  • Hex to int
    int('0x61', 16)  # 97
  • Hex to Char
     chr(int('0x61', 16)) # 'a'
  • Hex to String
     string = '61626364'
    ''.join(chr(int(string[i:i+2], 16)) for i in range(0, len(string), 2))  # 'abcd'
  • Char to Int
    ord('a')  # 97
  • Char to Hex
    hex(ord('a'))  # '0x61'
  • String to Int
    int('97')  # 97
  • String to Hex 
    string = 'abcd'
    ''.join([hex(ord(x))[2:] for x in string])  # '61626364'

2015年1月26日 星期一

Python - Unique list

map的key不允許重複,list的element可以允許重複,set的element不允許重複。
基於上述資料型態的特性,要將list變成unique list可以利用set。
sample = [1,2,3,1,2,3,4,5]
sample = list(set(sample))  # [1,2,3,4,5]

2015年1月22日 星期四

Python - fork

Python使用fork可以讓process從呼叫的那一刻起一分為二。
import os

def myFoo(num : int) -> int:
    loop_times = 0
    print('start pid', os.getpid())

    f = os.fork()

    if f == 0:
        # child process: num*(3^5)
        while loop_times < 5:
            num *= 3
            print('child', os.getpid(), loop_times, num)
            loop_times += 1
    else:
        # parent process: num*(2^10)
        while loop_times < 10:
            num *= 2
            print('parent', os.getpid(), loop_times, num)
            loop_times += 1
    return num

def main():
    print('pid', os.getpid(), myFoo(2))
    print('pid', os.getpid(), 'finish')

if __name__ == '__main__':
    main()
實驗的執行結果為:(請注意,每次執行的pid和印出來的順序會不同)
start pid 5653
parent 5653 0 4
parent 5653 1 8
parent 5653 2 16
parent 5653 3 32
parent 5653 4 64
child 5654 0 6
parent 5653 5 128
parent 5653 6 256
child 5654 1 18
parent 5653 7 512
child 5654 2 54
parent 5653 8 1024
child 5654 3 162
parent 5653 9 2048
child 5654 4 486
pid 5653 486
pid 5653 2048
pid 5654 finish
pid 5653 finish
在f = os.fork()這一行,parent process #5653呼叫os.fork(),呼叫後傳回child process的pid #5654給parent process的變數f,而child process誕生於呼叫os.fork()後,在child process中也會傳回值給變數f,但是因為child process並沒有從呼叫os.fork()開始,所以傳回的值是0。至此之後,所有的expression都一分為二,parent process和child process都各自有一份並進行動作。

上述例子中,還有一處值得探討的是print('pid', os.getpid(), myFoo(2))這一行輸出的結果
pid 5653 486和pid 5653 2048,執行輸出動作都是parent process,但是輸出內容有parent process從myFoo()回傳的2048和child process從myFoo()回傳的486。原因是,parent process呼叫print(),當print()進行到一半時跳到myFoo()之中,在myFoo()中呼叫os.fork()從此一分為二,parent process執行完myFoo()後回傳給呼叫myFoo的process,也就是parent process,child process執行完myFoo()後回傳給呼叫myFoo的process,一樣也是parent process,所以才會輸出pid 5653 486和pid 5653 2048;print('pid', os.getpid(), 'finish')這一行是在一分為二後才會進行的,parent process和child process個別進行,才會輸出pid 5654 finish和pid 5653 finish這兩行。