2007年10月30日 星期二

把命令放到背景執行

Linux 允許把命令放到背景中執行,僅僅需要在命令的最後加上一個 &,就可以利用 Linux 的多工特性執行多個背景程式,如以下:
bang@linuxdiary:~$ sleep 300 &
[1] 8521
bang@linuxdiary:~$ sleep 500 &
[2]8522
  • [1] 代表指定給該工作的序號

  • 8521 代表 PID (process ID)
若想查詢當前的背景工作可使用 jobs 指令,
bang@linuxdiary:~$ jobs
[1] - Running sleep 300 &
[2]+ Running sleep 500 &
bang@linuxdiary:~$ jobs -l
[1] - 8521 Running sleep 300 &
[2]+ 8522 Running sleep 500 &

但如果後悔把命令放入背景時怎麼辦?你可以利用 fg 命令把工作帶回前景 (foreground);如果背景中堆積了好幾個命令,可用行程識別碼或工作序號來挑選他們。
bang@linuxdiary:~$ fg %1
sleep 300

bang@linuxdiary:~$ fg 8521
sleep 300

正在前景中執行的 sleep 300 是否困擾著你,可以不要等待嗎? 是的~ 可以
此時你可以點擊鍵盤上的組合鍵 Ctrl + Z ( 暫停程序,並將程序放置背景 )
bang@linuxdiary:~$ fg %1
sleep 300 => Ctrl + Z

[1]+ Stopped sleep 300
但此時的工作是暫停的,若希望它能繼續在背景中執行,可利用 bg 命令恢復在背景(background) 中暫停的工作。
bang@linuxdiary:~$ bg %1
[1]+ sleep 300 &
bang@linuxdiary:~$ jobs
[1] - Running sleep 300 &
[2]+ Running sleep 500 &
如果想要刪除在背景的工作可用 kill 來完成
bang@linuxdiary:~$ kill %2
[2]+ Terminated sleep 500
最後介紹的指令,將對常用 ssh 遠端登入的使用者很有幫助,nohup (no hang up,不要掛斷)。當使用者利用 ssh 等指令或軟體登入主機後,想要執行某個指令,但一旦登出或關掉 ssh 軟體,那個在背景執行的工作會跟著消失,主要原因是它的父行程被關閉了,也就是使用者剛剛關閉的 bash,那怎麼辦?nohup 可以為您強制保存背景工作,即便父行程被關閉,以下為示範
bang@linuxdiary:~$ nohup sleep 500 &
[1] 8544
bang@linuxdiary:~$ nohup: appending output to `nohup.out'

bang@linuxdiary:~$ ps -fC sleep (用 ps 查詢正在用 sleep 命令執行的行程)
UID PID PPID C STIME TTY TIME CMD
root 8544 8014 0 16:41 pts/1 00:00:00 sleep 500
此時關閉 shell,重新登入
bang@linuxdiary:~$ ps -fC sleep
UID PID PPID C STIME TTY TIME CMD
root 8544 1 0 16:42 pts/1 00:00:00 sleep 500

會發現它還存在著,但 PPID 變為 1,亦即父行程被指派為 init,這個背景工作不會再受父行程關閉而關閉影響,因為如果想關閉 init,那就關機吧。

2007年10月28日 星期日

行程 (process) 的意義

Linux 整個運作建立在「行程」的觀念上,對核心而言,於系統上運作的每一個「程式」( program ),無論是命令 (command),應用程式 (application),程序稿 (script),全都是行程的組合。

舉例而言,在你登入系統之前,終端機是由 getty 行程所監控,登入之後,gtty 會自我中斷,並將終端機的掌控權交給 shell 接管 ( shell 是另一個行程 ),而你在 shell 中所見入的每個命令,都會觸發一個或多個行程,某些行程還會衍生新的行程,稱為子行程。
shell 的內建命令,如 cd,echo,jobs... 等,並不會被啟動成子行程,因為他們原本就是 shell 行程的一部分。

如果要知道有哪些行程正在執行,可參考 ps 命令。
bang@linuxdiary:~$ ps
PID TTY TIME CMD
7773 pts/0 00:00:00 bash
7789 pts/0 00:00:00 ps
  • PID (Process ID,行程識別碼):當行程被啟動,會被賦予一個 ID 為識別碼,每個行程都有自己所屬的 ID,管理者可 PID 來傳送信號給這些行程。
  • TTY 控制終端機:在何種終端機上面運作,若與終端機無關,則顯示 ?。tty1-tty6 是本機上面的登入者程序 (Ctrl + Alt + Fn),若為 pts/0 等等的,則表示為由網路連接進主機的程序,若為 ? 則代表背景執行程式。
  • TIME:目前為止所占用 CPU 的時間,使用者於命令列觸發的行程 (如 ls),他們的「生命期」多半相當短暫。但是對於提供公共服務的行程 (如 Apache web server),他們的生命期就相當長,甚至是在系統啟動之後就開始,直到關機或管理者給予結束才終止。
  • STAT (狀態):常見的狀態有
    • R (running):目前正在運作,或者在佇列中等待運作。
    • S (sleep):睡眠狀態,等待某些事件的完成,可被某些訊號 (signal) 喚醒。
    • T (terminable):停止了或該程序被其工作控制著。
    • Z (zombie):僵屍程序,應該已終止,但是其父程序卻無法正常的終止他。
    • <:高優先權的程序
    • N:低優先權的程序
    • +:在前景程序群組的程序 (如正在前景執行的程序)。
    • s:本程序為 session leader
  • CMD:命令名稱

2007年10月21日 星期日

shell 的設定檔

shell 的設定檔

在 bash shell 中,在系統登入的期間,會執行 4 個 shell 設定檔案,以下為他們執行順序
  1. /etc/profile
  2. /etc/bashrc
  3. ~/.bash_profile (red hat 3 與 4 相反)
  4. ~/.bashrc
在此說明各個設定檔

檔案

說明

/etc/profile

這是一個在登入時才執行的系統初始化設定檔,它通常包含一些環境變數,包括最初的 PATH 變數,和一些啟動程式。

/etc/bashrc

這是另一個系統端初始化檔案,當一個 bash shell 被啟動時,/etc/bashrc 通常會被 ~/.bashrc 呼叫執行,它通常包含一些 functions 和 aliases 。

~/.bash_profile

如果此檔案存在,它會在登入 Shell 期間,自動執行於 /etc/profile 之後。

~/.bash_login

如果 ~/.bash_profile 檔案不存在,此檔案會在登入 Shell 期間自動執行。

~/.profile

如果 .bash_profile.bash_login 皆不存在,此檔案會在登入 Shell 期間自動執行。此檔案是 Bourne shell 原始的設定檔。

~/.bashrc

此檔案會在啟動 Shell 時自動執行(包含xterm 和一般 Shell),通常包含一些環境變數與 aliases。

~/.bash_logout

此檔案會在 Shell 登出時自動執行。

~/.inputrc

此檔包含一些敲擊鍵盤的反應, Bash 預設反應設定與 Emacs 相同。

~/.bashrc 與 ~/.bash_profile 的差異
.bash_profile 只有在登入的時候才會啟用,原本設計的目的是為了讓你可以將交談方式操作的 shell 程式與非交談程式的(背景程式)shell 程式區分開來。但在目前的 X 視窗系統卻沒多大作用,主要原因為執行 xterm 視窗時,只有 .bashrc 會執行而 ~/.bash_profile 並不執行,因為 xterm 不需登入即可啟動。

如何變更 shell

如何變更 shell

先查看系統上目前可使用的 shell 有哪些。
bang@linuxdiary:~$ cat /etc/shells
# /etc/shells: valid login shells
/bin/csh
/usr/bin/es
/usr/bin/ksh
/bin/ksh
...略
改變自己的 shell 為 tcsh (要登出後再登入才會生效 )。
bang@linuxdiary:~$ chsh
Changing the login shell for root
Enter the new value, or press ENTER for the default
Login Shell [/bin/bash]:tcsh
登出後再登入,顯示目前所使用的 shell。 bang@linuxdiary:~$ echo $SHELL
/bin/tcsh

2007年10月10日 星期三

Shell 的變數

在 bash 運作期間,會維護一組變數,這類的變數含有 bash 運作時所需的重要的資訊。大多的變數,在 bash 啟動時就會設定好,但是使用者可隨時手動改變這些變數,藉此改變 shell 的一些行為。
bang@linuxdiary:~$ echo $PS1
${debian_chroot:+($debian_chroot)}\u@\h:\w\$

以變數 PS1 (Prompt String 1)為例,其值為一個代表命令提示字元的字串。由上例可知使用 echo 命令可顯是變數內容,方法是變數前加一個 $ 號。
在 $PS1 中 u,h,w 都是普通的字元,因為前面的「\」(meta chatacter) 她的意義為
  • \ u:username,使用者名稱
  • \h:hostname,主機名稱
  • \w:working directory 目前工作目錄
環境變數 (environment variables)
專屬某個 shell 的一組變數,使該行程能得知使用者喜好與系統組態。所有 sub-sheel,指令稿和程式可自動繼承這些變數。

shell 變數
只能在目前的 shell 或 script 中存取。

常用的變數的指令

  • env:顯示所有環境變數
  • export:設定環境變數
  • set:顯示所有變數
  • unset:取消變數
常用的變數(每個 distribution 會略有不同)
  • PATH:搜尋執行檔的路徑
  • SHELL:目前所使用的shell
  • HOSTNAME:主機名稱
  • USERNAME:使用者名稱
  • LOGNAME:登入的帳戶名稱
  • HOME:使用者家目錄
  • LANG:系統預設語系
  • HISTSIZE:指令歷程容量大小
  • MAIL:使用者存放郵件的目錄

2007年10月7日 星期日

指令歷程

現今的 bash 與 tcsh 對指令紀錄的已有大幅的進步,它讓你用相當簡單的方式調出先前曾經輸入的指令,當你與 bash 互動時,你所下達的每個命令,會先被 shell 記錄在自己的歷程表(history list),然後才開始進行解讀或執行。
歷程表的容量由變數 HISTSIZE 控制
bang@linuxdiary:~$ echo $HISTSIZE
500
預設值為 500,可視情況修改。
當你登出系統時,歷程表的內容會被寫進你的個人目錄之中的 .bash_history 之中 (環境變數 HISTFILE 所指定的檔案) ,當你下次登入系統時,即可使用 history 指令調出之前輸入的指令。
history
語法
history [option] [files]
列出指令歷程
常用選項
  • n :數字,意思是『要列出最近的 n 筆命令列表』的意思!
  • -c :將目前的 shell 中的所有 history 內容全部消除
  • -a :將目前新增的 history 指令新增入 histfiles 中,若沒有加 histfiles , 則預設寫入 ~/.bash_history
  • -r :將 histfiles 的內容讀到目前這個 shell 的 history 記憶中;
  • -w :將目前的 history 記憶內容寫入 histfiles 中!
bang@linuxdiary:~$ history 3
125 history
126 history 5
127 history 3
history expansion 歷程擴展
所謂的歷程擴展,就是在命列重新執行歷程表中的舊命令,以下列出歷程擴展的語法
語法 說明
!! 歷程最後一道命令,同按上後 Enter。
!n 歷程第 n 個命令。
!-n 執行前 n 個命令。
!string 歷程表中最後一筆開頭為 string 的命令。
!?string 歷程表中最後一筆含有為 string 的命令。
^string1^string2 重複最後一筆命令,但命令中 string1 置換為 string2
!$ 前一個命令的最後一個元素
!:n-1 前一個命令的第 n 個元素