星期日, 7月 22, 2018

bash: SHELL BUILTIN COMMANDS

內建指令是 shell 本身提供的指令,有些 shell 用外部指令取代。

除非特別說明,接受「-」開頭選項的內建指令也接受「--」來表示選項的結束。但「:」、「true」、「false」、及「test」並不接受選項,也就不處理「--」。「exit」、「logout」、「break」、「continue」、「let」、及「shift」接受及處理「-」開始的引數,不需要「--」作為結束。其它接受引數、但不接受選項的內建指令,「-」開始的引數會解釋為無效的選項,需要「--」來避免這種情況。

: [arguments]

只是擴展 arguments 及進行指定的轉向。

.  filename [arguments]
source filename [arguments]

在當下的 shell 環境執行 filename。如果 filename 不含 slash,會去 PATH 找 filename (不需要可執行)。如果 bash 不在 posix  模式,會再找目前目錄。如果內建指令 shopt 的選項 sourcepath 關閉,不找 PATH。如果有任何 arguments,會成為位置參數。

如果 -T 選項啟用,繼承 DEBUG trap。如果沒啟用,DEBUG trap 字串會備份後清掉,執行完再回復。參考內建指令 set。

alias [-p] [name[=value] ...]

bg [jobspec ...]


bind [-m keymap] [-lpsvPSVX]
bind [-m keymap] [-q function] [-u function] [-r keyseq]
bind [-m keymap] -f filename
bind [-m keymap] -x keyseq:shell-command
bind [-m keymap] keyseq:function-name
bind [-m keymap] keyseq:readline-command

bash readline 按鍵對應功能的顯示和綁定、或設定 readline 變數。

每個非選項的引數是如同 .inputrc 的指令,但 binding 跟 command 需要用不同引數傳遞
。例如「"\C-x\C-r":  re-read-init-file」.

選項:
  • -m keymap:keymap 可為 emacs (emacs-standard)、emacs-meta、emacs-ctlx、vi (vi-command)、vi-move、及 vi-insert,影響後續的綁定。
  • -l:列出所有 readline 功能名稱
  • -p:顯示 readline 功能名稱及綁定 (可輸入格式)
  • -P:顯示 readline 功能名稱及綁定
  • -s:顯示 readline key sequences bound to macros and the strings they output (可輸入格式)
  • -S:顯示 readline key sequences bound to macros and the strings they output.
  • -v:顯示 readline 變數名稱及值 (可輸入格式)
  • -V:顯示 readline 變數名稱及值
  • -f filename:自 filename 讀取 key bindings
  • -q function:詢問 function 綁定的 key
  • -u function:取消 function 綁定的 key
  • -r keyseq:移除任何目前 keyseq 的綁定
  • -x keyseq:shell-command:輸入 keyseq 執行 shell-command。shell-command 執行時, shell 設定變數 READLINE_LINE 為 readline line buffer 內容及 READLINE_POINT 為目前游標位置。如果執行的指令改變 READLINE_LINE 或 READLINE_POINT 的值,將會反應在編輯狀態。
  • -X:列出綁定到 shell command 的 key sequence 和 shell command (可輸入格式)

break [n]

跳脫 n 層 for、while、until、或 select 迴圈,n 預設為 1。

builtin shell-builtin [arguments]

用內建指令執行。
當定義的 function 名稱跟內建指令相同時,用來強制使用內建指令。

內建指令 cd 常常用 function 重新定義。

如果 shell-builtin 不是一個內建指令,回傳值是 false。

caller [expr]


cd [-L|[-P [-e]] [-@]] [dir]


command [-pVv] command [arg ...]


compgen [option] [word]


complete [-abcdefgjksuv] [-o comp-option] [-DE] [-A action]  [-G glob‐pat] [-W wordlist] [-F function] [-C command] [-X filterpat] [-P prefix] [-S suffix] name [name ...]
complete -pr [-DE] [name ...]


compopt [-o option] [-DE] [+o option] [name]


continue [n]

直接開始下一回 for、while、until、或 select 的控制迴圈。如果有 n,開始第 n 層封閉迴圈。如果 n 超出所有封閉迴圈層數,則使用最外層。

declare [-aAfFgilnrtux] [-p] [name[=value] ...]
typeset [-aAfFgilnrtux] [-p] [name[=value] ...]


dirs [-clpv] [+n] [-n]


disown [-ar] [-h] [jobspec ... | pid ... ]


echo [-neE] [arg ...]


enable [-a] [-dnps] [-f filename] [name ...]

啟用及停用內建指令。
停用某個內建指令可以不用指令完整路徑執行同名的外部指令

範例:
  • `enable -n test` 停用內建指令 test
  • `enable test` 啟用內建指令 test
  • `enable` 或 `enable -p` 列出啟用的內建指令
  • `enable -n` 列出停用的內建指令
  • `enable -a` 列出所有內建指令,無論啟用及停用的
  • `enable -s` 列出啟用的 POSIX 內建指令
  • `enable -f filename name` 載入 filename (shared object 檔) 作為內建指令 name。
  • `enable -d` 移除之前透過 -f 載入的內建指令

eval [arg ...]

exec [-cl] [-a name] [command [arguments]]

執行 command 取代原本 process。
  • -l:在引數 0 前置「-」,如同指令 login。
  • -c:以空的環境變數執行。
  • -a name:使用 name 作為引數 0 (指令名稱)
shopt 選項 execfail 啟用:command 在非 interactive shell 無法執行時,不離開,改回傳失敗。

exit [n]


export [-fn] [name[=word]] ...
export -p


fc [-e ename] [-lnr] [first] [last]
fc -s [pat=rep] [cmd]


fg [jobspec]


getopts optstring name [args]


hash [-lr] [-p filename] [-dt] [name]

help [-dms] [pattern]


history [n]
history -c
history -d offset
history -anrw [filename]
history -p arg [arg ...]
history -s arg [arg ...]


jobs [-lnprs] [ jobspec ... ]
jobs -x command [ args ... ]


kill [-s sigspec | -n signum | -sigspec] [pid | jobspec] ...
kill -l|-L [sigspec | exit_status]


let arg [arg ...]

每個 arg 是要 evaluated 的 arithmetic expression。如果最後 arg evaluates 為 0,回傳 1,否則回傳 1。

local [option] [name[=value] ... | - ]


logout

登出,離開 login shell。

mapfile  [-d  delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]
readarray [-d delim] [-n count] [-O origin] [-s count] [-t] [-u fd] [-C callback] [-c quantum] [array]


popd [-n] [+n] [-n]


printf [-v var] format [arguments]


pushd [-n] [+n] [-n]
pushd [-n] [dir]


pwd [-LP]


read [-ers] [-a aname] [-d delim] [-i text] [-n nchars] [-N nchars] [-p prompt] [-t timeout] [-u fd] [name ...]


readonly [-aAf] [-p] [name[=word] ...]


return [n]


set [--abefhkmnptuvxBCEHPT] [-o option-name] [arg ...]
set [+abefhkmnptuvxBCEHPT] [+o option-name] [arg ...]

shift [n]

所有位置參數往前位移 n 個位置,沒給 n 值時當作 1。n 超出範圍不動作,回傳失敗。

shopt [-pqsu] [-o] [optname ...]


suspend [-f]


test expr 或 [ expr ]


times

印出 shell 和透過其執行的累計使用者和系統時間。

trap [-lp] [[arg] sigspec ...]


type [-aftpP] name [name ...]


ulimit [-HSabcdefiklmnpqrstuvxPT [limit]]

控制 shell 和啟始的 process 可用的資源。選項 -H 及 -S 分別指定只設定 hard limt 或 soft limit,不然兩者都設。hard limit 設定之後只有 root 可以增加。soft limit 不能增加超過 hard limit。limit 可以是一個數字 (依據特定資源的單位),或是 hard、soft、或 unlimited 之一。如果省略 limit,預設印出目前的 soft limit,除非加 -H 選項。如果一次要印出多個資源,資源名稱及單位會印在值之前。參數沒指定資源時,預設是 -f,指檔案最大可寫入的大小。值大多以 1024-byte 為單位,-c 和 -f 在 posix 模式以 512-byte 為單位。其它選項說明如下:
  • -a:印出所有資源限制。
  • -b:最大 socket buffer 數目。
  • -c:最大建立的 core files 大小。
  • -d:最大 process 的 data segment 大小。
  • -e:最大 scheduling priority ("nice")。
  • -f:最大檔案可寫入的大小。
  • -i:最多 pending signals 的數目。
  • -k:最多可配置的 kqueue 數目。
  • -l:最大可 locked into memory 的大小。
  • -m:最大 resident set 大小 (許多系統不 honor this limit)。
  • -n:最多可開啟的 file descriptor (大部分系統不允許設定)。
  • -p:pipe 大小,以 512-byte block 為單位。(可能不能設。)
  • -q:在 POSIX message queues 最大 byte 數。
  • -r:最大 real-time scheduling priority。
  • -s:最大 stack 大小。
  • -t:最大 cpu time 秒數。
  • -u:單一使用者最多 process 數目。
  • -v:shell (或其 children) 最大 virtual memory。
  • -x:最多可鎖定的檔案數目。
  • -P :最多虛擬終端機數目。
  • -T:最大 thread 數目。

umask [-p] [-S] [mode]


unalias [-a] [name ...]

unset [-fv] [-n] [name ...]


wait [-n] [n ...]

參考來源

bash man page 的 SHELL BUILTIN COMMANDS

bash: DEFINITIONS, RESERVED WORDS & COMMENTS

定義
  • blank:space 或 tab 字元。
  • word 或 token:字,視為一個單元的一系列字元,由 metacharacter 切割。token 可以是字或運算子。
  • name 或 identifier:由英文字母、數字及「_」組成的字,不能以數字開頭,可作為 shell 變數或 function 名稱。
  • metacharacter:沒 quoted 時切割出 word 的字元,包括:
    • space、tab
    • 「<」與「>」:亦有輸出入導向功能 (redirection operator)
    • 「|」「&」「;」「(」「)」<newline>:組合出所有控制運算子 (control operator),亦區隔出子指令並控制執行方式。
  • control operator:進行執行控制功能的 token,包括:
    • 「|」或「|&」:串接前後指令的輸出入成為 pipeline。
    • 「&&」:AND,前面指令執行成功 (回傳值 0) 才執行下個指令。
    • 「||」:OR,前面指令執行失敗 (回傳值不為 0) 才執行下個指令。
    • 「&」:背景執行
    • 「;」或 <newline>:執行
    • ( ):subshell 執行
    • 「;;」、「;&」、「;;&」:用在 case
保留字:在 shell 有特殊意義的字,用在 simple command 第一個字 (見 bash SHELL GRAMMAR) 或指令 case、for 的第三個字。
  • !
  • case esac
  • coproc
  • do done
  • for
  • function
  • if then elif else fi
  • in select
  • until
  • while
  • { }
  • time
  • [[ ]]
註解
  • 字元 # 開始的字到行末都會忽略。互動式 shell 可用內建指令 shopt 的 interactive_comments 關閉註解功能。

參考來源

man bash 的 DEFINITIONS, RESERVED WORDS & COMMENTS 節

bash: ALIASES

alias 意思是「化名」。在 bash,每個 simple command 的第一個字符合某個 alias 名稱,會取代為對應的 alias 值。取代後的第一個字再繼續進行 alias,但如果是已經用過的 alias 名稱,就不再進行。例如 ls alias 為 ls -F 只會進行一次。如果 alias 的值的最後字元是一個 blank (依定義,blank 是 space 或 tab),指令下個字也進行 alias。

shell 有個 alias 列表,可透過內建指令 alias 和 unalias 來列出、設定和消除。alias 名稱不能包含字元 /、$、`、=、metacharacter 或 quoting 字元。alias 值可以包含任何 valid shell input,包括 metacharacters。

alias 用在互動式 shell,如果非互動式 shell 也要用,使用內建指令 shopt 設 expand_aliases。

alias 是在整行指令讀取時進行,而不是執行時進行。同行的新 alias 定義要等到指令執行完才會生效,並不會對同行指令生效。在 function 也是同樣的,alias 是在 function 定義讀取時進行,function 裡的新 alias 定義要等到 function 執行才會生效。安全的作法是把 alias 定義放在自己獨立一行,不要用在 compound command。

alias 進行優先於 shell function。

內建指令:alias [-p] [name[=value] ...]

alias 或 alisa -p 以 alias name=value 格式印出所有 alias 或印指定 name 的 alias。
設定 name 的 alias 為 value。

內建指令:unalias [-a] [name ...]

移除 alias 名稱 name。選項 -a 移除所有 alias。

shell 變數 BASH_ALIASES

由 alias 名稱作為 index 的一個  associative  陣列,成員是 alias 表。陣列新增成員會出現在 alias 表,但清除成員目前並不會從 alias 表移除。如果 unset BASH_ALIASES 會失去其特殊 properties。

列出 BASH_ALIASES
$ declare -p BASH_ALIASES

$ for k in "${!BASH_ALIASES[@]}"; do printf '%s => %s\n' "$k" "${BASH_ALIASES[$k]}"; done

參考來源

  1. bash 的 ALIASES 節、內建指令 alias、shell 變數 BASH_ALIASES
  2. https://unix.stackexchange.com/questions/109124/bash-aliases-not-equal-to-alias

bash: OPTIONS 和內建指令 set

bash 指令格式是 bash [--選項] [-選項] [引數],多字元選項「--選項」必須放在單字元選項「-選項」前面,之後是引數。通常第一個引數是指令 ($0),剩下引數傳給指令使用 ($1, $2, ...)。

單字元選項可使用內建指令 set 支援的單字元選項外,還可以用下列選項:
  • -c:第一個引數還是一樣是指令,但傳給指令的 $0 是第二個引數,位置參數 $1 從第三個引數開始。$0 作為警告和錯誤訊息的指令名稱。
  • -iinteractive shell
  • -l 或 --login:啟動為 login shell
  • -r:見 RESTRICTED SHELL
  • -s:指令從標準輸入讀取,不用引數的指令。在 interactive shell 設定為位置參數。
  • -D--dump-strings:在標準輸出印出所有前置 $ 的雙引號字串,當 locale 不為 C 或 POSIX 時會做語言轉換。隱含 -n 選項,不執行指令。
  • [-+]O [shopt_option]:-O 設定內建指令 shopt 的 shell 選項,+O 清掉。沒有 shopt_option 時,印出這些選項的名稱及值,如果用 +O 輸出可作為輸入的格式。
  • ---:表示選項結束,之後的引數視為檔名及其引數。
其它多字元選項:
  • --debugger:在 shell 開始前安排執行 debugger profile,啟用 extended 除錯模式 (見 bash 內建指令 shopt 選項 extdebug 的說明)
  • --dump-po-strings:相當於 -D,但以 GNU gettext po (portable object) 檔案格式輸出。
  • --help:顯示使用說明。
  • --init-file file--rcfile file:在 interactive shell 改執行 file 取代 /etc/bash.bashrc 及 ~/.bashrc (見 bash INVOCATION)。
  • --noediting:在 interactive shell 不使用 GNU readline 函式庫來讀取指令行。
  • --noprofile:不執行 /etc/profile、~/.bash_profile、~/.bash_login、或 ~/.profile。login shell 預設執行這些檔案 (見 bash INVOCATION)
  • --norc:在 interactive shell 不執行 /etc/bash.bashrc 及 ~/.bashrc。以 sh invoke 時預設啟用。
  • --posix:行為符合 POSIX 標準模式。見 SEE ALSO 參考  how posix mode affects bash's behavior 細節的文件。
  • --restricted:restricted shell (見 bash RESTRICTED SHELL).
  • --verbose:相當於 -v。
  • --version:顯示版本訊息。

內建指令 set

功能有設定 shell 選項、設定位置參數、列變數

set [--abefhkmnptuvxBCEHPT] [-o option-name] [arg ...]
set [+abefhkmnptuvxBCEHPT] [+o option-name] [arg ...]
set #依順序列出所有 shell 變數
set arg ... #依序設定位置參數 $1、$2、 ...

指令的選項用來設定或清除 shell 選項。除非特別說明,選項預設是關閉的。使用 --o 開啟選項,++o 關閉選項。

$- 可看到目前的選項。

指令選項說明如下:

-a 或 -o allexport

每個新建或更改的變數,export 到接下來指令的環境。

-b 或 -o notify

立刻回報結束的背景工作,而不是等到下個指令提示。

-e 或 -o errexit

待續

-f 或 -o noglob

停用 pathname 擴展。

-h 或 -o hashall

記憶執行時查到的指令路徑,預設是開啟的。

-k 或 -o keyword

待續

-m 或 -o monitor

待續

-n 或 -o noexec

讀取指令但不執行。可用來檢查 shell 指令搞是否有 syntax errors。在 interactive shell 沒作用。

-o option-name

沒 option-name 時列出目前 shell 選項設定,+o 顯示一系列 set 指令,可用來重新建立目前選項設定。

option-name 大多搭配有單字元格式,沒有的有:
  • emacs:使用 emacs-style 指令行編輯界面。interactive shell 預設啟用,除非 shell 時使用選項 --noediting。同時影響編輯界面用來讀取 -e。
  • history:啟用指令歷史功能 (見 bash HISTORY)。interactive shell 預設啟用。
  • ignoreeof:等同執行 shell 指令 ``IGNOREEOF=10''。(見 Shell Variables).
  • nolog:目前忽略
  • pipefail:回傳最後失敗指令的回傳值。
  • posix:使用 posix 模式。.
  • vi:使用 vi-style 指令行編輯界面。同時影響編輯界面用來讀取 -e。

-p 或 -o privileged

開啟特權 (privileged) 模式,此時 $ENV 及 $BASH_ENV 的檔案不處理,不自環境繼承 shell 函數,忽略變數 SHELLOPTS、BASHOPTS、CDPATH、及 GLOBIGNORE。
如果 shell 開始時的 effective user (group) ID 和 real user (group) ID 不同,也進行
這些動作。此時如果 -p 沒設,effective user id (group) 會設為 real user (group) id;如果有設,則不動 effective user (group) id。

-t 或 -o onecmd

讀完執行一個指令離開。

-u 或 -o nounset

待續

-v 或 -o verbose

印出讀到的輸入行。

-x 或 -o xtrace

trace 模式。擴展每個 simple command、for、case、select、或 arithmetic for 後,顯示 PS4 和指令。

-B 或 -o braceexpand

進行 brace expansion (見 bash Brace Expansion),預設啟用。

-C 或 -o noclobber

>,  >&,  and <> redirection operators 不覆寫存在的檔案。對 >| 則不影響。

-E 或 -o errtrace

待續

-H 或 -o histexpand

待續

-P 或 -o physical

待續

-T 或 -o functrace

待續

--

表示是最後的指令選項,接下來有引數的話,設定位置參數,否則重置位置參數。

-

表示是最後的指令選項,接下來有引數的話,設定位置參數。關閉指令選項 -x 和 -v。

參考來源

man bash OPTIONS 節、內建指令 set

星期四, 7月 19, 2018

TLPI: Creating a Daemon, Guidelines for Writing Daemons

初步了解 daemon 後,來看 daemon 建立的步驟:
  1. fork() 結束親行程,繼續的子行程呼叫 setsid() (TLPI §34.3) 成立新的行程群組。
    • 假設 daemon 是從指令行執行,親行程結束讓 shell 得以繼續,留下子行程在背景執行。
    • 親行程可能是行程群組領導,可能帶有其它子行程。fork() 後子行程就不會是領導,呼叫 setsid() 後成立新的獨立行程群組。
  2. 如果 daemon 之後需要開啟終端 device,需要動作確保不會變成控制終端,有兩種方式:
    • open() 任何終端 device 指定 O_NOCTTY 旗標。
    • 另一種較簡易的方式是進行第二次 fork(),一樣只讓子行程繼續執行。如此一來,子行程不會是行程群組領導,依據 Linux 跟隨的 the System V 只有領導取得控制終端機的傳統,可避免取得控制終端機 (TLPI §34.4)。如果是跟隨 BSD 傳統的系統,行程只有明確用 ioctl() TIOCSCTTY 設定後,才會得到控制終端機,第二次 fork() 是多餘的但也沒什麼傷害。
  3. 清除行程的 umask (TLPI §15.4.6),確保 daemon 建立檔案或目錄時,有需要的 permissions.
  4. 在 daemon 結束前,其工作目錄無法卸載 (TLPI §14.8.2),改變工作目錄到根目錄 ( / ) 或其它適當的目錄,可方便在 daemon 結束前卸載。
  5. 繼承的 file descriptor,沒用到的都關閉,以節省資源。 例如 daemon 已經失去控制終端,保留 file descriptors 0、1、和 2 並無意義。例外,開啟的檔案所在的檔案系統無法卸載。
  6. 將 file descriptors 0、1、和 2 都導到 /dev/null。
    • 避免 daemon 呼叫函式庫有輸出無法輸出,造成非預期的錯誤。
    • 避免 daemon 後續開啟檔案使用到 1 和 2,函式庫輸出而造成破壞。
glibc 提供不是標準的函數 daemon() 可轉換呼叫的程式為 daemon,下面是另一個實作的範例。

#include <sys/stat.h>
#include <fcntl.h>
#include "tlpi_hdr.h"
int                             /* Returns 0 on success, -1 on error */
becomeDaemon(int flags)
{
    int maxfd, fd;
    switch (fork()) {                   /* Become background process */
        case -1: return -1;
        case 0:  break;                 /* Child falls through... */
        default: _exit(EXIT_SUCCESS);   /* while parent terminates */
    }
    if (setsid() == -1)                 /* Become leader of new session */
        return -1;
    switch (fork()) {                   /* Ensure we are not session leader */
        case -1: return -1;
        case 0:  break;
        default: _exit(EXIT_SUCCESS);
    }
    if (!(flags & BD_NO_UMASK0))
        umask(0);                       /* Clear file mode creation mask */
    if (!(flags & BD_NO_CHDIR))
        chdir("/");                     /* Change to root directory */
    if (!(flags & BD_NO_CLOSE_FILES)) { /* Close all open files */
        maxfd = sysconf(_SC_OPEN_MAX);
        if (maxfd == -1)                /* Limit is indeterminate... */
            maxfd = BD_MAX_CLOSE;       /* so take a guess */
        for (fd = 0; fd < maxfd; fd++)
            close(fd);
    }
    if (!(flags & BD_NO_REOPEN_STD_FDS)) {
        close(STDIN_FILENO);            /* Reopen standard fd's to /dev/null */
        fd = open("/dev/null", O_RDWR);
        if (fd != STDIN_FILENO)         /* 'fd' should be 0 */
            return -1;
        if (dup2(STDIN_FILENO, STDOUT_FILENO) != STDOUT_FILENO)
            return -1;
        if (dup2(STDIN_FILENO, STDERR_FILENO) != STDERR_FILENO)
            return -1;
    }
    return 0;
}

寫一個程式呼叫 becomeDaemon(0),然後 sleep() 一陣子,可以用指令 ps 來看程式的一些屬性:
$ ./test_become_daemon
$ ps -C test_become_daemon -o "pid ppid pgid sid tty command"
  PID  PPID  PGID   SID TT       COMMAND
24731     1 24730 24730 ?        ./test_become_daemon
TT 下顯示 ? 表示沒有控制終端機。SID 不同於 PID,表示不是 session leader,不會再取得控制終端機。

由於 daemons 是長時間執行。需要特別注意可能的記憶體洩漏 (TLPI §7.1.3) 和 file descriptor 洩漏 (沒有關閉所有開啟的 file descriptor。程式結束不是全部自動關閉嗎?)。

daemon 通常是系統結束時呼叫其 shutdown script,沒有的則由 init process 送 SIGTERM,5 秒後再送 SIGKILL。

許多 daemon 需要確保一個時間只有一個在執行,方法見 TLPI §55.6。

參考來源

  1. TLPI §37.2 & §37.3

bash

GNU 的 Bash (Bourne-Again SHell) 是一個指令語言直譯器,執行來自標準輸入或檔案的指令,與 sh 相容並結合 Korn shell (ksh) 及 C shell (csh) 的優點,相容 IEEE POSIX 標準的 Shell and Utilities 部份。

指令格式:
bash [options] [command_string | file]
整個指令由空白字元分成許多字,一開始可有一些選項 (option)。如果選項沒設 -c 或 -s 且之後還有引數,第一個引數會認定是一個檔名,並設為 $0。之後的引數依序設為位置參數 $1、$2、...。bash 會讀取並執行檔案內的指令,然後離開,離開狀態碼預設 0,最後執行的指令有最後決定權。檔案首先會在目前目錄找,如沒有再找 PATH 指定的目錄。

INVOCATION
DEFINITIONS, RESERVED WORDS, & COMMENTS
SHELL GRAMMAR
QUOTING
PARAMETERS
EXPANSION
REDIRECTION
ALIASES 別名
FUNCTIONS
ARITHMETIC EVALUATION
CONDITIONAL EXPRESSIONS
SIMPLE COMMAND EXPANSION
COMMAND EXECUTION
COMMAND EXECUTION ENVIRONMENT
ENVIRONMENT
EXIT STATUS 結束狀態
SIGNALS
JOB CONTROL
PROMPTING
READLINE
HISTORY
HISTORY EXPANSION
SHELL BUILTIN COMMANDS 內建指令
RESTRICTED SHELL
SEE ALSO
FILES

參考來源
  1. man bash
延伸閱讀

nc

netcat 在 Linux 中的指令為 nc,網路的 cat 工具程式,透過網路連結 stdin 和 stdout,原汁原味傳送資料。另外也可以掃描通訊埠。

     nc [-46bCDdFhklNnrStUuvZz] [-I length] [-i interval] [-M ttl] [-m minttl]
        [-O length] [-P proxy_username] [-p source_port] [-q seconds]
        [-s source] [-T keyword] [-V rtable] [-w timeout] [-X proxy_protocol]
        [-x proxy_address[:port]] [destination] [port]

nc 可作為基於指令稿的 Client 或 Server,可用在 TCP、UDP、或 UNIX-domain sockets,作通訊埠掃描,可處理 IPv4 和 IPv6。
  • destination 是 IP 位址或主機名稱,當伺服器端時 (使用 -l 選項) 不指定是指本機。在 UNIX-domain 是 socket 路徑。
  • port 可以是數字或服務名稱,或數字範圍。

使用可直接看下面範例。

    基本 client/server 連線

    在特定埠等待連線,server 端使用選項 -l (listen 等待進來連線。不能搭配選項 -p、-s、-z 使用,-w timeout 選項沒作用。)
    $ nc -l 1234
    在另一個終端機當 client,進行連線
    $ nc 127.0.0.1 1234
    任何一方的輸入,在另一方會出現。Ctrl-C 結束連線 (EOF (‘^D’) ?)。

    nc 沒有選項將收到的資料作為指令執行 (例如其它指令的選項 -c 或 -e),但可透過輸出轉向和 fifo 解決。server 輸出導給 fifo,取出給 /bin/sh 執行,再將結果傳給 server 顯示到 client。
    伺服器端:
    $ rm -f /tmp/f; mkfifo /tmp/f
    $ cat /tmp/f | /bin/sh -i 2>&1 | nc -l 127.0.0.1 1234 > /tmp/f
    使用者端:
    $ nc host.example.com 1234
    $ (shell prompt from host.example.com)
    註:busybox nc 有 -e 選項。

    當連線結束,nc 就結束。想要持續 listening 使用 -k 選項。

    傳送檔案

    接收端:
    $ nc -l 1234 > filename.out
    傳送端:
    $ nc -N host.example.com 1234 < filename.in

    傳送目錄

    接收端:
    nc -l 1234 | tar xvf -

    傳送端:
    tar cvf - /path/to/dir | nc host.example.com 1234

    遠端備份硬碟

    接收端:
    nc -l 1234 | dd of=sdb-backup.img.gz
    傳送端:
    dd if=/dev/sdb | gzip -c | nc hostB.com 1234
    回復接收端:
    nc -l 5000 | gzip -d | sudo dd of=/dev/sdb
    回復傳送端:
    nc hostA.com 5000 < sdb-backup.img.gz

    連線到伺服器

    取網頁:(註:echo 參數,n 不送換行,e 解釋反斜線跳脫。)
    $ echo -ne "GET / HTTP/1.0\r\n\r\n" | nc host.example.com 80
    送電子郵件到 SMTP 伺服器:
    $ nc [-C] localhost 25 << EOF
    HELO host.example.com
    MAIL FROM:<user@host.example.com>
    RCPT TO:<user2@host.example.com>
    DATA
    Body of email.
    .
    QUIT
    EOF

    偵測通訊埠

    用 -v 選項啟用 stderr verbose 輸出
    $ nc -v host.example.com 1234
    nc: connect to host.example.com (tcp) failed: Connection refused
    有開啟的話,通常 greeting banner 訊息含有伺服器執行的軟體和版本:
    $ nc -v host.example.com 22
    Connection to host.example.com 22 port [tcp/ssh] succeeded!
    SSH-2.0-OpenSSH_6.0p1 Debian-4
    使用 -z 選項和依序掃描通訊埠範圍:
    $ nc -zv host.example.com 20-30
    Connection to host.example.com 22 port [tcp/ssh] succeeded!
    Connection to host.example.com 25 port [tcp/smtp] succeeded!
    指定掃描的埠:
    $ nc -zv host.example.com 80 20 22
    nc: connect to host.example.com 80 (tcp) failed: Connection refused
    nc: connect to host.example.com 20 (tcp) failed: Connection refused
    Connection to host.example.com port [tcp/ssh] succeeded!
    掃描通訊埠範圍取得 greeting banners 才斷開連線,可透過 -w 指定短 timeout 或送「QUIT」指令給伺服器:
    $ echo "QUIT" | nc host.example.com 20-30
    SSH-1.99-OpenSSH_3.6.1p2
    Protocol mismatch.
    220 host.example.com IMS SMTP Receiver Version 0.84 Ready
    使用 -uz 選項的 UDP port 掃描不論有沒有都會回報成功 (有送出就成功?),可用 traffic sniffer 查看封包。

    送測試 UDP 封包
    echo -n "foo" | nc -u -w1 host.example.com 1234
    接收:
    nc -lu 1234

    其它範例

    TCP 連線到 host.example.com:42,使用 31337 最為來源埠,timeout 5 秒:
    $ nc -p 31337 -w 5 host.example.com 42
    UDP 連線到 host.example.com:53:
    $ nc -u host.example.com 53
    TCP 連線到 host.example.com:42,使用 10.1.2.3 作為來源 IP:
    $ nc -s 10.1.2.3 host.example.com 42
    接收 UNIX-domain stream socket 的連線:
    $ nc -lU /var/tmp/dsocket
    透過 HTTP proxy 10.2.3.4:8080 連線到 host.example.com:42。見 ssh_config 的 ProxyCommand directive 搭配 ssh 使用。
    $ nc -x10.2.3.4:8080 -Xconnect host.example.com 42
    透過有認證的 HTTP proxy 連線:
    $ nc -x10.2.3.4:8080 -Xconnect -Pruser host.example.com 42

    其它選項說明

    • -4:只用 IPv4 位址
    • -6:只用 IPv6 位址
    • -b:允許廣播
    • -C:送 CRLF 作為 line-ending
    • -D:啟用 socket 除錯
    • -d:不嘗試讀取 stdin
    • -F:使用 sendmsg() Pass the first connected socket 到 stdout 後離開。使用 -X 選項跟 proxy 進行連線後,把連線留給其它程式,例如 ssh() 使用 ssh_config ProxyUseFdpass 選項。
    • -h:印出 help
    • -I length:指定 TCP 接收 buffer 大小。
    • -i interval:指定每行送收間的延遲時間。同時導致連線多個通訊埠的延遲時間。
    • -k:連線結束後持續等待其它連線,需搭配 datagram 選項 (-u) 使用。
    • -M ttl:設送出封包的 TTL。
    • -m minttl:請求 kernel 拋棄進來封包 TTL 小於 minttl 的。
    • -N:輸入 EOF 後 shutdown() 網路 socket。有些伺服器需要這樣才能完成工作。
    • -n:不對指定的位址、主機名稱、或通訊埠進行 DNS service lookup。
    • -O length:指定 TCP 傳送 buffer 大小。
    • -P proxy_username:指定 HTTP proxy 認證的使用者名稱。
    • -p source_port:指定使用的來源通訊埠。subject to privilege restrictions and availability。
    • -q seconds:在 stdin 的 EOF 後,等候後才離開 (implies -N)。如果是負數,wait forever。
    • -r:在範圍內,以亂數方式選擇通訊埠。
    • -S:啟用 RFC 2385 TCP MD5 signature 選項。
    • -s source:指定來源 IP 或 UNIX-domain socket 檔案。
    • -T keyword:設定 IPv4 ToS 值,可以是 critical、inetcontrol、lowcost、lowdelay、netcontrol、throughput、reliability、或 DiffServ Code Point (ef、af11、...、af43、cs0、...、cs7)、或十六進位或十進位數字。
    • -t:送 RFC 854 DON'T and WON'T response to RFC 854 DO and WILL 請求,讓 nc script telnet session。
    • -U:使用 UNIX-domain socket。
    • -u:使用 datagram。
    • -V rtable:設定使用的 routing table。
    • -v:verbose 輸出。
    • -w timeout:對外連線的 timeout。
    • -X proxy_protocol:使用的 proxy 協定,4 是 SOCKS v.4、5 是 SOCKS v.5、connect 是 HTTPS proxy。預設是使用 SOCKS v.5。
    • -x proxy_address[:port]:proxy 的位址。
    • -Z:DCCP 模式。
    • -z:進行掃描。

    參考來源

    1. man nc
    2. http://blog.gtwang.org/linux/linux-utility-netcat-examples/

    延伸閱讀

    星期二, 7月 17, 2018

    TLPI: DAEMONS Overview

    daemon 是有下列特性的 process:
    • 常駐的。通常在系統起始時建立,運作到系統結束。
    • 背景執行,且沒有控制終端機。由於缺乏終端機,要確保 kernel 不會自動生任何 job 控制或終端相關 signals (如 SIGINT、SIGTSTP、SIGHUP) 給 daemon。
    daemon 用來執行特定工作,例如:
    • cron:在排定的時間執行指令。
    • sshd:使用 secure communication protocol 遠端登入的 secure shell daemon。
    • httpd:HTTP 伺服器 daemon,提供網頁。
    • inetd:Internet 超級伺服器 daemon (見 TLPI §60.5),在特定 TCP/IP 埠等待網路連線,啟動對應的伺服器程式處理。
    daemon 常習慣取名以子母 d 為結尾。

    許多標準 daemon 是特權行程 (也就是 effective user ID 是 0),因此應該依照 TLPI §38 的準則撰寫。

    在 Linux,有些 daemon 是 kernel thread,是 kernel 的一部分。當用 ps 指令列出時,名稱會用 [] 包起來,例如 [pdflush],週期 flushes dirty pages 到硬碟。

    參考來源:TLPI §37.1

    The Linux Programming Interface

    不錯的 Linux 書,2010 十月出版,作者 Michael Kerrisk 是 Linux man-pages 的維護者而許多內容類似。
    官網:http://man7.org/tlpi/
    章節:http://man7.org/tlpi/toc-detailed.html
    PREFACE
    1 HISTORY AND STANDARDS
    1.1 A Brief History of UNIX and C
    1.2 A Brief History of Linux
    1.2.1 The GNU Project
    1.2.2 The Linux Kernel
    1.3 Standardization
    1.3.1 The C Programming Language
    1.3.2 The First POSIX Standards
    1.3.3 X/Open Company and The Open Group
    1.3.4 SUSv3 and POSIX.1-2001
    1.3.5 SUSv4 and POSIX.1-2008
    1.3.6 UNIX Standards Timeline
    1.3.7 Implementation Standards
    1.3.8 Linux, Standards, and the Linux Standard Base
    1.4 Summary

    2 FUNDAMENTAL CONCEPTS
    2.1 The Core Operating System: The Kernel
    2.2 The Shell
    2.3 Users and Groups
    2.4 Single Directory Hierarchy, Directories, Links, and Files
    2.5 File I/O Model
    2.6 Programs
    2.7 Processes
    2.8 Memory Mappings
    2.9 Static and Shared Libraries
    2.10 Interprocess Communication and Synchronization
    2.11 Signals
    2.12 Threads
    2.13 Process Groups and Shell Job Control
    2.14 Sessions, Controlling Terminals, and Controlling Processes
    2.15 Pseudoterminals
    2.16 Date and Time (https://lirobo.blogspot.com/2014/12/linux-time.html)
    2.17 Client-Server Architecture
    2.18 Realtime (https://lirobo.blogspot.com/2014/12/linux-time.html)
    2.19 The /proc File System
    2.20 Summary

    3 SYSTEM PROGRAMMING CONCEPTS
    3.1 System Calls
    3.2 Library Functions
    3.3 The Standard C Library; The GNU C Library (glibc)
    3.4 Handling Errors from System Calls and Library Functions
    3.5 Notes on the Example Programs in This Book
    3.5.1 Command-Line Options and Arguments
    3.5.2 Common Functions and Header Files
    3.6 Portability Issues
    3.6.1 Feature Test Macros
    3.6.2 System Data Types
    3.6.3 Miscellaneous Portability Issues
    3.7 Summary
    3.8 Exercise

    4 FILE I/O: THE UNIVERSAL I/O MODEL
    5 FILE I/O: FURTHER DETAILS

    6 PROCESSES
    6.1 Processes and Programs
    6.2 Process ID and Parent Process ID
    6.3 Memory Layout of a Process
    6.4 Virtual Memory Management
    6.5 The Stack and Stack Frames
    6.6 Command-Line Arguments (argc, argv)
    6.7 Environment List
    6.8 Performing a Nonlocal Goto: setjmp() and longjmp()
    6.9 Summary
    6.10 Exercises

    7 MEMORY ALLOCATION

    8 USERS AND GROUPS
    8.1 The Password File: /etc/passwd
    8.2 The Shadow Password File: /etc/shadow
    8.3 The Group File: /etc/group
    8.4 Retrieving User and Group Information
    8.5 Password Encryption and User Authentication
    8.6 Summary
    8.7 Exercises

    9 PROCESS CREDENTIALS
    9.1 Real User ID and Real Group ID
    9.2 Effective User ID and Effective Group ID
    9.3 Set-User-ID and Set-Group-ID Programs
    9.4 Saved Set-User-ID and Saved Set-Group-ID
    9.5 File-System User ID and File-System Group ID
    9.6 Supplementary Group IDs
    9.7 Retrieving and Modifying Process Credentials
    9.7.1 Retrieving and Modifying Real, Effective, and Saved Set IDs
    9.7.2 Retrieving and Modifying File-System IDs
    9.7.3 Retrieving and Modifying Supplementary Group IDs
    9.7.4 Summary of Calls for Modifying Process Credentials
    9.7.5 Example: Displaying Process Credentials
    9.8 Summary
    9.9 Exercises

    10 TIME
    10.2.3 Converting Between Broken-Down Time and Printable Form
    10.3 Timezones
    10.4 Locales
    10.5 Updating the System Clock
    10.6 The Software Clock (Jiffies)
    10.7 Process Time
    10.8 Summary
    10.9 Exercise

    11 SYSTEM LIMITS AND OPTIONS
    11.1 System Limits
    11.2 Retrieving System Limits (and Options) at Run Time
    11.3 Retrieving File-Related Limits (and Options) at Run Time
    11.4 Indeterminate Limits
    11.5 System Options
    11.6 Summary
    11.7 Exercises

    12 SYSTEM AND PROCESS INFORMATION
    12.1 The /proc File System
    12.1.1 Obtaining Information About a Process: /proc/PID
    12.1.2 System Information Under /proc
    12.1.3 Accessing /proc Files
    12.2 System Identification: uname()
    12.3 Summary
    12.4 Exercises

    13 FILE I/O BUFFERING
    13.1 Kernel Buffering of File I/O: The Buffer Cache
    13.2 Buffering in the stdio Library
    13.3 Controlling Kernel Buffering of File I/O
    13.4 Summary of I/O Buffering
    13.5 Giving the Kernel Hints About I/O Patterns: posix_fadvise()
    13.6 Bypassing the Buffer Cache: Direct I/O
    13.7 Mixing Library Functions and System Calls for File I/O
    13.8 Summary
    13.9 Exercises

    14 FILE SYSTEMS
    14.1 Device Special Files (Devices)
    14.2 Disks and Partitions
    14.3 File Systems
    14.4 I-nodes
    14.5 The Virtual File System (VFS)
    14.6 Journaling File Systems
    14.7 Single Directory Hierarchy and Mount Points
    14.8 Mounting and Unmounting File Systems
    14.8.1 Mounting a File System: mount()
    14.8.2 Unmounting a File System: umount() and umount2()
    14.9 Advanced Mount Features
    14.9.1 Mounting a File System at Multiple Mount Points
    14.9.2 Stacking Multiple Mounts on the Same Mount Point
    14.9.3 Mount Flags That Are Per-Mount Options
    14.9.4 Bind Mounts
    14.9.5 Recursive Bind Mounts
    14.10 A Virtual Memory File System: tmpfs
    14.11 Obtaining Information About a File System: statvfs()
    14.12 Summary
    14.13 Exercise

    15 FILE ATTRIBUTES
    15.1 Retrieving File Information: stat()
    15.2 File Timestamps
    15.2.1 Changing File Timestamps with utime() and utimes()
    15.2.2 Changing File Timestamps with utimensat() and futimens()
    15.3 File Ownership
    15.3.1 Ownership of New Files
    15.3.2 Changing File Ownership: chown(), fchown(), and lchown()
    15.4 File Permissions
    15.4.1 Permissions on Regular Files
    15.4.2 Permissions on Directories
    15.4.3 Permission-Checking Algorithm
    15.4.4 Checking File Accessibility: access()
    15.4.5 Set-User-ID, Set-Group-ID, and Sticky Bits
    15.4.6 The Process File Mode Creation Mask: umask()
    15.4.7 Changing File Permissions: chmod() and fchmod()
    15.5 I-node Flags (ext2 Extended File Attributes)
    15.6 Summary
    15.7 Exercises

    16 EXTENDED ATTRIBUTES
    16.1 Overview
    16.2 Extended Attribute Implementation Details
    16.3 System Calls for Manipulating Extended Attributes
    16.4 Summary
    16.5 Exercise

    17 ACCESS CONTROL LISTS
    17.1 Overview
    17.2 ACL Permission-Checking Algorithm
    17.3 Long and Short Text Forms for ACLs
    17.4 The ACL_MASK Entry and the ACL Group Class
    17.5 The getfacl and setfacl Commands
    17.6 Default ACLs and File Creation
    17.7 ACL Implementation Limits
    17.8 The ACL API
    17.9 Summary
    17.10 Exercise

    18 DIRECTORIES AND LINKS
    18.1 Directories and (Hard) Links
    18.2 Symbolic (Soft) Links
    18.3 Creating and Removing (Hard) Links: link() and unlink()
    18.4 Changing the Name of a File: rename()
    18.5 Working with Symbolic Links: symlink() and readlink()
    18.6 Creating and Removing Directories: mkdir() and rmdir()
    18.7 Removing a File or Directory: remove()
    18.8 Reading Directories: opendir() and readdir()
    18.9 File Tree Walking: nftw()
    18.10 The Current Working Directory of a Process
    18.11 Operating Relative to a Directory File Descriptor
    18.12 Changing the Root Directory of a Process: chroot()
    18.13 Resolving a Pathname: realpath()
    18.14 Parsing Pathname Strings: dirname() and basename()
    18.15 Summary
    18.16 Exercises

    19 MONITORING FILE EVENTS
    19.1 Overview
    19.2 The inotify API
    19.3 inotify Events
    19.4 Reading inotify Events
    19.5 Queue Limits and /proc Files
    19.6 An Older System for Monitoring File Events: dnotify
    19.7 Summary
    19.8 Exercise

    20 SIGNALS: FUNDAMENTAL CONCEPTS
    20.1 Concepts and Overview
    20.2 Signal Types and Default Actions
    20.3 Changing Signal Dispositions: signal()
    20.4 Introduction to Signal Handlers
    20.5 Sending Signals: kill()
    20.6 Checking for the Existence of a Process
    20.7 Other Ways of Sending Signals: raise() and killpg()
    20.8 Displaying Signal Descriptions
    20.9 Signal Sets
    20.10 The Signal Mask (Blocking Signal Delivery)
    20.11 Pending Signals
    20.12 Signals Are Not Queued
    20.13 Changing Signal Dispositions: sigaction()
    20.14 Waiting for a Signal: pause()
    20.15 Summary
    20.16 Exercises

    21 SIGNALS: SIGNAL HANDLERS
    21.1 Designing Signal Handlers
    21.1.1 Signals Are Not Queued (Revisited)
    21.1.2 Reentrant and Async-Signal-Safe Functions
    21.1.3 Global Variables and the sig_atomic_t Data Type
    21.2 Other Methods of Terminating a Signal Handler
    21.2.1 Performing a Nonlocal Goto from a Signal Handler
    21.2.2 Terminating a Process Abnormally: abort()
    21.3 Handling a Signal on an Alternate Stack: sigaltstack()
    21.4 The SA_SIGINFO Flag
    21.5 Interruption and Restarting of System Calls
    21.6 Summary
    21.7 Exercise

    22 SIGNALS: ADVANCED FEATURES
    22.1 Core Dump Files
    22.2 Special Cases for Signal Delivery, Disposition, and Handling
    22.3 Interruptible and Uninterruptible Process Sleep States
    22.4 Hardware-Generated Signals
    22.5 Synchronous and Asynchronous Signal Generation
    22.6 Timing and Order of Signal Delivery
    22.7 Implementation and Portability of signal()
    22.8 Realtime Signals
    22.8.1 Sending Realtime Signals
    22.8.2 Handling Realtime Signals
    22.9 Waiting for a Signal Using a Mask: sigsuspend()
    22.10 Synchronously Waiting for a Signal
    22.11 Fetching Signals via a File Descriptor
    22.12 Interprocess Communication with Signals
    22.13 Earlier Signal APIs (System V and BSD)
    22.14 Summary
    22.15 Exercises

    23 TIMERS AND SLEEPING
    23.1 Interval Timers
    23.2 Scheduling and Accuracy of Timers
    23.3 Setting Timeouts on Blocking Operations
    23.4 Suspending Execution for a Fixed Interval (Sleeping)
    23.4.1 Low-Resolution Sleeping: sleep()
    23.4.2 High-Resolution Sleeping: nanosleep()
    23.5 POSIX Clocks
    23.5.1 Retrieving the Value of a Clock: clock_gettime()
    23.5.2 Setting the Value of a Clock: clock_settime()
    23.5.3 Obtaining the Clock ID of a Specific Process or Thread
    23.5.4 Improved High-Resolution Sleeping: clock_nanosleep()
    23.6 POSIX Interval Timers
    23.6.1 Creating a Timer: timer_create()
    23.6.2 Arming and Disarming a Timer: timer_settime()
    23.6.3 Retrieving the Current Value of a Timer: timer_gettime()
    23.6.4 Deleting a Timer: timer_delete()
    23.6.5 Notification via a Signal
    23.6.6 Timer Overruns
    23.6.7 Notification via a Thread
    23.7 Timers That Notify via File Descriptors: the timerfd API
    23.8 Summary
    23.9 Exercises

    24 PROCESS CREATION
    24.1 Overview of fork(), exit(), wait(), and execve()
    24.2 Creating a New Process: fork()
    24.2.1 File Sharing Between Parent and Child
    24.2.2 Memory Semantics of fork()
    24.3 The vfork() System Call
    24.4 Race Conditions After fork()
    24.5 Avoiding Race Conditions by Synchronizing with Signals
    24.6 Summary

    25 PROCESS TERMINATION
    25.1 Terminating a Process: _exit() and exit()
    25.2 Details of Process Termination
    25.3 Exit Handlers
    25.4 Interactions Between fork(), stdio Buffers, and _exit()
    25.5 Summary
    25.6 Exercise

    26 MONITORING CHILD PROCESSES
    26.1 Waiting on a Child Process
    26.1.1 The wait() System Call
    26.1.2 The waitpid() System Call
    26.1.3 The Wait Status Value
    26.1.4 Process Termination from a Signal Handler
    26.1.5 The waitid() System Call
    26.1.6 The wait3() and wait4() System Calls
    26.2 Orphans and Zombies
    26.3 The SIGCHLD Signal
    26.3.1 Establishing a Handler for SIGCHLD
    26.3.2 Delivery of SIGCHLD for Stopped Children
    26.3.3 Ignoring Dead Child Processes
    26.4 Summary
    26.5 Exercises

    27 PROGRAM EXECUTION
    27.1 Executing a New Program: execve()
    27.2 The exec() Library Functions
    27.2.1 The PATH Environment Variable
    27.2.2 Specifying Program Arguments As a List
    27.2.3 Passing the Caller's Environment to the New Program
    27.2.4 Executing a File Referred to by a Descriptor: fexecve()
    27.3 Interpreter Scripts
    27.4 File Descriptors and exec()
    27.5 Signals and exec()
    27.6 Executing a Shell Command: system()
    27.7 Implementing system()
    27.8 Summary
    27.9 Exercises

    28 PROCESS CREATION AND PROGRAM EXECUTION IN MORE DETAIL
    28.1 Process Accounting
    28.2 The clone() System Call
    28.2.1 The clone() flags Argument
    28.2.2 Extensions to waitpid() for Cloned Children
    28.3 Speed of Process Creation
    28.4 Effect of exec() and fork() on Process Attributes
    28.5 Summary
    28.6 Exercise

    29 THREADS: INTRODUCTION
    29.1 Overview
    29.2 Background Details of the Pthreads API
    29.3 Thread Creation
    29.4 Thread Termination
    29.5 Thread IDs
    29.6 Joining with a Terminated Thread: pthread_join()
    29.7 Detaching a Thread: pthread_detach()
    29.8 Thread Attributes
    29.9 Threads Versus Processes
    29.10 Summary
    29.11 Exercises

    30 THREADS: THREAD SYNCHRONIZATION
    30.1 Protecting Accesses to Shared Variables: Mutexes
    30.1.1 Statically Allocated Mutexes
    30.1.2 Locking and Unlocking a Mutex
    30.1.3 Performance of Mutexes
    30.1.4 Mutex Deadlocks
    30.1.5 Dynamically Initializing a Mutex
    30.1.6 Mutex Attributes
    30.1.7 Mutex Types
    30.2 Signaling Changes of State: Condition Variables
    30.2.4 Example Program: Joining Any Terminated Thread
    30.4 Exercises

    31 THREADS: THREAD SAFETY AND PER-THREAD STORAGE
    31.1 Thread Safety (and Reentrancy Revisited)
    31.2 One-Time Initialization
    31.3 Thread-Specific Data
    31.3.1 Thread-Specific Data from the Library Function's Perspective
    31.3.2 Overview of the Thread-Specific Data API
    31.3.3 Details of the Thread-Specific Data API
    31.3.4 Employing the Thread-Specific Data API
    31.3.5 Thread-Specific Data Implementation Limits
    31.4 Thread-Local Storage
    31.5 Summary
    31.6 Exercises

    32 THREADS: THREAD CANCELLATION
    32.1 Canceling a Thread
    32.2 Cancellation State and Type
    32.3 Cancellation Points
    32.4 Testing for Thread Cancellation
    32.5 Cleanup Handlers
    32.6 Asynchronous Cancelability
    32.7 Summary
    32.8 Exercises

    33 THREADS: FURTHER DETAILS
    33.1 Thread Stacks
    33.2 Threads and Signals
    33.2.1 How the UNIX Signal Model Maps to Threads
    33.2.2 Manipulating the Thread Signal Mask
    33.2.3 Sending a Signal to a Thread
    33.2.4 Dealing with Asynchronous Signals Sanely
    33.3 Threads and Process Control
    33.4 Thread Implementation Models
    33.5 Linux Implementations of POSIX Threads
    33.5.1 LinuxThreads
    33.5.2 NPTL
    33.5.3 Which Threading Implementation?
    33.6 Advanced Features of the Pthreads API
    33.7 Summary
    33.8 Exercises

    34 PROCESS GROUPS, SESSIONS, AND JOB CONTROL

    35 PROCESS PRIORITIES AND SCHEDULING
    35.2 Overview of Realtime Process Scheduling
    35.4 CPU Affinity
    35.5 Summary
    35.6 Exercises

    36 PROCESS RESOURCES
    36.1 Process Resource Usage: getrusage()
    36.2 Process Resource Limits: getrlimit() and setrlimit()
    36.3 Details of Specific Resource Limits
    36.4 Summary
    36.5 Exercises

    37 DAEMON 簡介、和建立
    37.4 Using SIGHUP to Reinitialize a Daemon
    使用 syslog 紀錄日誌
    37.6 Summary
    37.7 Exercise

    38 WRITING SECURE PRIVILEGED PROGRAMS
    38.1 Is a Set-User-ID or Set-Group-ID Program Required?
    38.2 Operate with Least Privilege
    38.3 Be Careful when Executing a Program
    38.4 Avoid Exposing Sensitive Information
    38.5 Confine the Process
    38.6 Beware of Signals and Race Conditions
    38.7 Pitfalls when Performing File Operations and File I/O
    38.8 Don't Trust Inputs or the Environment
    38.9 Beware of Buffer Overruns
    38.10 Beware of Denial-of-Service Attacks
    38.11 Check for Failures; Fail Safely
    38.12 Summary
    38.13 Exercises

    39 CAPABILITIES
    39.1 Rationale for Capabilities
    39.2 The Linux Capabilities
    39.3 Process and File Capabilities
    39.3.1 Process Capabilities
    39.3.2 File Capabilities
    39.3.3 Purpose of the Process Permitted and Effective Capability Sets
    39.3.4 Purpose of the File Permitted and Effective Capability Sets
    39.3.5 Purpose of the Process and File Inheritable Sets
    39.3.6 Assigning and Viewing File Capabilities from the Shell
    39.4 The Modern Capabilities Implementation
    39.5 Transformation of Process Capabilities During exec()
    39.5.1 Capability Bounding Set
    39.5.2 Preserving root Semantics
    39.6 Effect on Process Capabilities of Changing User IDs
    39.7 Changing Process Capabilities Programmatically
    39.8 Creating Capabilities-Only Environments
    39.9 Discovering the Capabilities Required by a Program
    39.10 Older Kernels and Systems Without File Capabilities
    39.11 Summary
    39.12 Exercise

    40 LOGIN ACCOUNTING
    40.1 Overview of the utmp and wtmp Files
    40.2 The utmpx API
    40.3 The utmpx Structure
    40.4 Retrieving Information from the utmp and wtmp Files
    40.5 Retrieving the Login Name: getlogin()
    40.6 Updating the utmp and wtmp Files for a Login Session
    40.7 The lastlog File
    40.8 Summary
    40.9 Exercises

    41 FUNDAMENTALS OF SHARED LIBRARIES
    41.1 Object Libraries
    41.2 Static Libraries
    41.3 Overview of Shared Libraries
    41.4 Creating and Using Shared Libraries—A First Pass
    41.4.1 Creating a Shared Library
    41.4.2 Position-Independent Code
    41.4.3 Using a Shared Library
    41.4.4 The Shared Library Soname
    41.5 Useful Tools for Working with Shared Libraries
    41.6 Shared Library Versions and Naming Conventions
    41.7 Installing Shared Libraries
    41.8 Compatible Versus Incompatible Libraries
    41.9 Upgrading Shared Libraries
    41.10 Specifying Library Search Directories in an Object File
    41.11 Finding Shared Libraries at Run Time
    41.12 Run-Time Symbol Resolution
    41.13 Using a Static Library Instead of a Shared Library
    41.14 Summary
    41.15 Exercise

    42 ADVANCED FEATURES OF SHARED LIBRARIES
    42.1 Dynamically Loaded Libraries
    42.1.1 Opening a Shared Library
    42.1.2 Diagnosing Errors from the dlopen API
    42.1.3 Obtaining the Address of a Symbol: dlsym()
    42.1.4 Closing a Shared Library: dlclose()
    42.1.5 Obtaining Information About Loaded Symbols: dladdr()
    42.1.6 Accessing Symbols in the Main Program
    42.2 Controlling Symbol Visibility
    42.3 Linker Version Scripts
    42.3.1 Controlling Symbol Visibility with Version Scripts
    42.3.2 Symbol Versioning
    42.4 Initialization and Finalization Functions
    42.5 Preloading Shared Libraries
    42.6 Monitoring the Dynamic Linker: LD_DEBUG
    42.7 Summary
    42.8 Exercises

    43 INTERPROCESS COMMUNICATION OVERVIEW
    43.1 A Taxonomy of IPC Facilities
    43.2 Communication Facilities
    43.3 Synchronization Facilities
    43.4 Comparing IPC Facilities
    43.5 Summary
    43.6 Exercises

    44 PIPES AND FIFOS
    44.1 Overview
    44.2 Creating and Using Pipes
    44.3 Pipes As a Method of Process Synchronization
    44.4 Using Pipes to Connect Filters
    44.5 Talking to a Shell Command via a Pipe: popen() and pclose()
    44.6 Pipes and stdio Buffering
    44.7 FIFOs
    44.8 A Client-Server Application Using FIFOs
    44.9 Nonblocking I/O
    44.10 Semantics of read() and write() on Pipes and FIFOs
    44.11 Summary
    44.12 Exercises

    45 INTRODUCTION TO SYSTEM V IPC
    45.1 API Overview
    45.2 IPC Keys
    45.3 Associated Data Structure and Object Permissions
    45.4 IPC Identifiers and Client-Server Applications
    45.5 Algorithm Employed by System V IPC get Calls
    45.6 The ipcs and ipcrm Commands
    45.7 Obtaining a List of All IPC Objects
    45.8 IPC Limits
    45.9 Summary
    45.10 Exercises

    46 SYSTEM V MESSAGE QUEUES
    46.1 Creating or Opening a Message Queue: msgget()
    46.2 Exchanging Messages
    46.2.1 Sending Messages: msgsnd()
    46.2.2 Receiving Messages: msgrcv()
    46.3 Message Queue Control Operations: msgctl()
    46.4 Message Queue Associated Data Structure
    46.5 Message Queue Limits
    46.6 Displaying All Message Queues on the System
    46.7 Client-Server Programming with Message Queues
    46.8 A File-Server Application Using Message Queues
    46.9 Disadvantages of System V Message Queues
    46.10 Summary
    46.11 Exercises

    47 SYSTEM V SEMAPHORES
    47.1 Overview
    47.2 Creating or Opening a Semaphore Set: semget()
    47.3 Semaphore Control Operations: semctl()
    47.4 Semaphore Associated Data Structure
    47.5 Semaphore Initialization
    47.6 Semaphore Operations: semop()
    47.7 Handling of Multiple Blocked Semaphore Operations
    47.8 Semaphore Undo Values
    47.9 Implementing a Binary Semaphores Protocol
    47.10 Semaphore Limits
    47.11 Disadvantages of System V Semaphores
    47.12 Summary
    47.13 Exercises

    48 SYSTEM V SHARED MEMORY
    48.1 Overview
    48.2 Creating or Opening a Shared Memory Segment: shmget()
    48.3 Using Shared Memory: shmat() and shmdt()
    48.4 Example: Transferring Data Via Shared Memory
    48.5 Location of Shared Memory Segments in Virtual Memory
    48.6 Storing Pointers in Shared Memory
    48.7 Shared Memory Control Operations: shmctl()
    48.8 Shared Memory Associated Data Structure
    48.9 Shared Memory Limits
    48.10 Summary
    48.11 Exercises

    49 MEMORY MAPPINGS
    49.1 Overview
    49.2 Creating a Mapping: mmap()
    49.3 Unmapping a Mapped Region: munmap()
    49.4 File Mappings
    49.4.1 Private File Mappings
    49.4.2 Shared File Mappings
    49.4.3 Boundary Cases
    49.4.4 Memory Protection and File Access Mode Interactions
    49.5 Synchronizing a Mapped Region: msync()
    49.6 Additional mmap() Flags
    49.7 Anonymous Mappings
    49.8 Remapping a Mapped Region: mremap()
    49.9 The MAP_NORESERVE Flag and Swap Space Overcommitting
    49.10 The MAP_FIXED Flag
    49.11 Nonlinear Mappings: remap_file_pages()
    49.12 Summary
    49.13 Exercises

    50 VIRTUAL MEMORY OPERATIONS
    50.1 Changing Memory Protection: mprotect()
    50.2 Memory Locking: mlock() and mlockall()
    50.3 Determining Memory Residence: mincore()
    50.4 Advising Future Memory Usage Patterns: madvise()
    50.5 Summary
    50.6 Exercises

    51 INTRODUCTION TO POSIX IPC
    51.1 API Overview
    51.2 Comparison of System V IPC and POSIX IPC
    51.3 Summary

    52 POSIX MESSAGE QUEUES
    52.1 Overview
    52.2 Opening, Closing, and Unlinking a Message Queue
    52.3 Relationship Between Descriptors and Message Queues
    52.4 Message Queue Attributes
    52.5 Exchanging Messages
    52.5.1 Sending Messages: mq_send()
    52.5.2 Receiving Messages: mq_receive()
    52.5.3 Sending and Receiving Messages with a Timeout
    52.6 Message Notification
    52.6.1 Receiving Notification via a Signal
    52.6.2 Receiving Notification via a Thread
    52.7 Linux-Specific Features
    52.8 Message Queue Limits
    52.9 Comparison of POSIX and System V Message Queues
    52.10 Summary
    52.11 Exercises

    53 POSIX SEMAPHORES
    53.1 Overview
    53.2 Named Semaphores
    53.2.1 Opening a Named Semaphore
    53.2.2 Closing a Semaphore
    53.2.3 Removing a Named Semaphore
    53.3 Semaphore Operations
    53.3.1 Waiting on a Semaphore
    53.3.2 Posting a Semaphore
    53.3.3 Retrieving the Current Value of a Semaphore
    53.4 Unnamed Semaphores
    53.4.1 Initializing an Unnamed Semaphore
    53.4.2 Destroying an Unnamed Semaphore
    53.5 Comparisons with Other Synchronization Techniques
    53.6 Semaphore Limits
    53.7 Summary
    53.8 Exercises

    54 POSIX SHARED MEMORY
    54.1 Overview
    54.2 Creating Shared Memory Objects: shm_open()
    54.3 Using Shared Memory Objects
    54.4 Removing Shared Memory Objects: shm_unlink()
    54.5 Comparisons Between Shared Memory APIs
    54.6 Summary
    54.7 Exercise

    55 FILE LOCKING
    55.1 Overview
    55.2 File Locking with flock()
    55.2.1 Semantics of Lock Inheritance and Release
    55.2.2 Limitations of flock()
    55.3 Record Locking with fcntl()
    55.3.1 Deadlock
    55.3.2 Example: An Interactive Locking Program
    55.3.3 Example: A Library of Locking Functions
    55.3.4 Lock Limits and Performance
    55.3.5 Semantics of Lock Inheritance and Release
    55.3.6 Lock Starvation and Priority of Queued Lock Requests
    55.4 Mandatory Locking
    55.5 The /proc/locks File
    55.6 Running Just One Instance of a Program
    55.7 Older Locking Techniques
    55.8 Summary
    55.9 Exercises
    延伸閱讀:Linux 防止 Shell 指令稿重複執行教學

    56 SOCKETS: INTRODUCTION
    57 SOCKETS: UNIX DOMAIN
    58 SOCKETS: FUNDAMENTALS OF TCP/IP NETWORKS
    59 SOCKETS: INTERNET DOMAINS
    60 SOCKETS: SERVER DESIGN
    61 SOCKETS: ADVANCED TOPICS

    62 TERMINALS

    63 ALTERNATIVE I/O MODELS
    63.1 Overview
    63.1.1 Level-Triggered and Edge-Triggered Notification
    63.1.2 Employing Nonblocking I/O with Alternative I/O Models
    63.2 I/O Multiplexing
    63.2.1 The select() System Call
    63.2.2 The poll() System Call
    63.2.3 When Is a File Descriptor Ready?
    63.2.4 Comparison of select() and poll()
    63.2.5 Problems with select() and poll()
    63.3 Signal-Driven I/O
    63.3.1 When Is "I/O Possible" Signaled?
    63.3.2 Refining the Use of Signal-Driven I/O
    63.4 The epoll API
    63.4.1 Creating an epoll Instance: epoll_create()
    63.4.2 Modifying the epoll Interest List: epoll_ctl()
    63.4.3 Waiting for Events: epoll_wait()
    63.4.4 A Closer Look at epoll Semantics
    63.4.5 Performance of epoll Versus I/O Multiplexing
    63.4.6 Edge-Triggered Notification
    63.5 Waiting on Signals and File Descriptors
    63.5.1 The pselect() System Call
    63.5.2 The Self-Pipe Trick
    63.6 Summary
    63.7 Exercises

    64 PSEUDOTERMINALS
    64.1 Overview
    64.2 UNIX 98 Pseudoterminals
    64.2.1 Opening an Unused Master: posix_openpt()
    64.2.2 Changing Slave Ownership and Permissions: grantpt()
    64.2.3 Unlocking the Slave: unlockpt()
    64.2.4 Obtaining the Name of the Slave: ptsname()
    64.3 Opening a Pseudoterminal Master: ptyMasterOpen()
    64.4 Connecting Two Processes with a Pseudoterminal: ptyFork()
    64.5 Pseudoterminal I/O
    64.6 Implementing script(1)
    64.7 Terminal Attributes and Window Size
    64.8 BSD Pseudoterminals
    64.9 Summary
    64.10 Exercises

    A TRACING SYSTEM CALLS
    B PARSING COMMAND-LINE OPTIONS
    C CASTING THE NULL POINTER
    D KERNEL CONFIGURATION
    E FURTHER SOURCES OF INFORMATION
    F SOLUTIONS TO SELECTED EXERCISES
    BIBLIOGRAPHY
    INDEX

    星期三, 7月 04, 2018

    滑鼠及微動開關

    今天換滑鼠左鍵微動開關,做個紀錄。

    滑鼠建議買 DPI 1000 以上的
    微動開關
    • OMRON D2F-01F (日製)
      • D2F 是 OMRON 的長效系列
      • 帶有 01 字樣的使用金合金接點,耐用度10萬次 。沒有01字樣的使用銀合金接點,耐用度3萬次。
      • 帶有 F 字樣的,最大力量為 0.74N,按鍵較輕 。沒有的,最大力量為 1.47N,按鍵較重。
      • 另外有輕手感特製版 60gf(max)
    • asus rog sica
    • D2FC-F-7N(20M)、D2FC-F-7N(10M)
    • Zippy DF3-P1 (0.1A, 5VDC, 台製)
    • Zippy DF3-S3 (3A 125VAC 及 3A 250VAC)

    滑鼠:建議買 DPI 1000 以上的,拆卸不用移除滑鼠腳。藍光?

    • ***logitech M105 還不錯,拆卸不用移除滑鼠腳。100.6x60.6x33.5 73g 1.5米
    • 華碩 U2000 滑鼠鍵盤組 滑鼠 1000 dpi
    • 公司 ASUS 滑鼠
      • 20190131 右鍵換 DF3-P1
      • 20200526 左鍵換舊滑鼠左鍵
      • 20200824 左鍵換 DF3-P1
      • 20221111 左鍵長按會斷換舊的 D2FC-F-7N
      • 20221122 左鍵長按會斷換舊品
    • Logitech M110 Silent (M110s, 型號 M-U0051):1000dpi、靜音 112.96 公釐 x 61.7 公釐 x 38.4 公釐 85 公克 線長 180 公分
      • 20200121 購買
      • 202202 左鍵換舊 G102 滾輪雙腳微動開關。原本紅頭雙腳可能是 KAILH 靜音微動
      • 202211 右鍵長沒反應,打算淘汰,左鍵、中鍵備品。
    • Logitech M100r:1000dpi、113x 62x38 90g 1.8米
      • https://home.gamer.com.tw/creationDetail.php?sn=2860998
    • ASUS A43
    • Logitech G402:謙 202202 購買
    • Logitech G90
      • 2019/11 購買
      • 2020/04 左鍵出問題送修,送回 G102。
      • 2021/? 左鍵出問題。左右 D2FC-F-7N(10M),滾輪雙腳,中間、左前、左後 Kailh
    • Logitech M90 400dpi:鼠體有點大、噪音有點大
      • 202004 右鍵故障淘汰,左鍵中鍵拆下當零件。

    其它

    • 鐵氟龍膠帶
    • 3M 接點復活劑、接點復活膏
    • 光學滑鼠使用光學圖像處理晶片來偵測移動,通常使用紅色 LED,在太過平滑的平面上操作容易造成飄移的情況。雷射滑鼠則使用雷射光,基本上只要是在可以反射的平面上都可以使用,但比較敏感。藍光滑鼠最適用於各種平面上,但?精準度較差。觸控滑鼠:就是利用觸控來使用的,所以沒有滾輪。
    • 軌跡球滑鼠:拇指、食指、中指,空中。
    • 空中飛鼠

    參考: