?? abs_guide_cn.txt
字號:
1 #!/bin/bash
2 #background-loop.sh
3
4 for i in 1 2 3 4 5 6 7 8 9 10 #第一個循環
5 do
6 echo -n "$i"
7 done& #在后臺運行這個循環
8 #在第2個循環之后,將在某些時候執行.
9
10 echo #這個'echo'某些時候將不會顯示.
11
12 for i in 11 12 13 14 15 16 17 18 19 20 #第二個循環
13 do
14 echo -n "$i"
15 done
16
17 echo #這個'echo'某些時候將不會顯示.
18
19 #--------------------------------------------------------
20
21 #期望的輸出應該是
22 #1 2 3 4 5 6 7 8 9 10
23 #11 12 13 14 15 16 17 18 19 20
24
25 #然而實際的結果有可能是
26 #11 12 13 14 15 16 17 18 19 20
27 #1 2 3 4 5 6 7 8 9 10 bozo $
28 #(第2個'echo'沒執行,為什么?)
29
30 #也可能是
31 #1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
32 #(第1個'echo'沒執行,為什么?)
33
34 #非常少見的執行結果,也有可能是:
35 #11 12 13 1 2 3 4 5 6 7 8 9 10 14 15 16 17 18 19 20
36 #前臺的循環先于后臺的執行
37
38 exit 0
39
40 # Nasimuddin Ansari 建議加一句 sleep 1
41 #+ 在 6行和14行的 echo -n "$i"之后加
42 #+ 將看到一些樂趣
################################End Script#########################################
注意:在一個腳本內后臺運行一個命令,有可能造成這個腳本的掛起,等待一個按鍵
響應.幸運的是,我們可以在Example 11-24附近,看到這個問題的解決辦法.
&& 與-邏輯操作.
- 選項,前綴.在所有的命令內如果想使用選項參數的話,前邊都要加上"-".
COMMAND -[Option1][Option2][...]
ls -al
sort -dfu $filename
set -- $variable
1 if [ $file1 -ot $file2 ]
2 then
3 echo "File $file1 is older than $file2."
4 fi
5
6 if [ "$a" -eq "$b" ]
7 then
8 echo "$a is equal to $b."
9 fi
10
11 if [ "$c" -eq 24 -a "$d" -eq 47 ]
12 then
13 echo "$c equals 24 and $d equals 47."
14 fi
- 用于重定向 stdin 或 stdout.
################################Start Script#######################################
1 (cd /source/directory && tar cf - . ) | (cd /dest/directory && tar xpvf -)
2 # 從一個目錄移動整個目錄樹到另一個目錄
3 # [courtesy Alan Cox <a.cox@swansea.ac.uk>, with a minor change]
4
5 # 1) cd /source/directory 源目錄
6 # 2) && 與操作,如果cd命令成功了,那么就執行下邊的命令
7 # 3) tar cf - . 'c'創建一個新文檔,'f'后邊跟'-'指定目標文件作為stdout
8 # '-'后邊的'f'(file)選項,指明作為stdout的目標文件.
9 # 并且在當前目錄('.')執行.
10 # 4) | 管道...
11 # 5) ( ... ) 一個子shell
12 # 6) cd /dest/directory 改變當前目錄到目標目錄.
13 # 7) && 與操作,同上.
14 # 8) tar xpvf - 'x'解檔,'p'保證所有權和文件屬性,
15 # 'v'發完整消息到stdout
16 # 'f'后邊跟'-',從stdin讀取數據
17 #
18 # 注意:'x' 是一個命令, 'p', 'v', 'f' 是選項.
19 # Whew!
20
21
22
23 # 更優雅的寫法應該是
24 # cd source/directory
25 # tar cf - . | (cd ../dest/directory; tar xpvf -)
26 #
27 # 當然也可以這么寫:
28 # cp -a /source/directory/* /dest/directory
29 # 或者:
30 # cp -a /source/directory/* /source/directory/.[^.]* /dest/directory
31 # 如果在/source/directory中有隱藏文件的話.
################################End Script#########################################
################################Start Script#######################################
1 bunzip2 linux-2.6.13.tar.bz2 | tar xvf -
2 # --未解壓的tar文件-- | --然后把它傳遞到"tar"中--
3 # 如果 "tar" 沒能夠正常的處理"bunzip2",
4 # 這就需要使用管道來執行2個單獨的步驟來完成它.
5 # 這個練習的目的是解檔"bzipped"的kernel源文件.
################################End Script#########################################
注意:在上邊這個例子中'-'不太象是bash的操作符,而更像是tar的參數.
bash$echo "whatever" | cat -
whatever
在需要一個文件名的地方,-重定向輸出到stdout(如在tar和cf命令中),或者從
stdin中接受輸入,而不是從一個文件中接受輸入.這是在管道中作為一個過濾
器,來使用文件定位工具的一種辦法.
bash$file
用法: file [-bciknvzl] [-f namefile] [-m magicfiles] file...
上邊這個例子file將會出錯,提示你如何使用file命令.
添加一個"-"將得到一個更有用的結果.這將使得shell等待用戶輸入.
bash$file -
abc
standard input: ASCII text
bash$file -
#!/bin/bash
standard input: Bourn-Again shell script tesxt executable
現在命令從stdin中接受了輸入,并分析它.
"-"常用于管道后邊的命令,具體參看33.7節,來看使用技巧.
使用diff命令來和另一個文件的一部分進行比較.
grep Linux file1 | diff file2 -
最后,一個真實世界的使用tar命令的例子.
Example 3-4. 備份最后一天所有修改的文件.
################################Start Script#######################################
1 #!/bin/bash
2
3 # 在一個"tarball"中(經過tar和gzip處理過的文件)
4 #+ 備份最后24小時當前目錄下d所有修改的文件.
5
6 BACKUPFILE=backup-$(date +%m-%d-%Y)
7 # 在備份文件中嵌入時間.
8 # Thanks, Joshua Tschida, for the idea.
9 archive=${1:-$BACKUPFILE}
10 # 如果在命令行中沒有指定備份文件的文件名,
11 #+ 那么將默認使用"backup-MM-DD-YYYY.tar.gz".
12
13 tar cvf - `find . -mtime -1 -type f -print` > $archive.tar
14 gzip $archive.tar
15 echo "Directory $PWD backed up in archive file \"$archive.tar.gz\"."
16
17
18 # Stephane Chazelas指出上邊代碼,
19 #+ 如果在發現太多的文件的時候,或者是如果文件
20 #+ 名包括空格的時候,將執行失敗.
21
22 # Stephane Chazelas建議使用下邊的兩種代碼之一
23 # -------------------------------------------------------------------
24 # find . -mtime -1 -type f -print0 | xargs -0 tar rvf "$archive.tar"
25 # 使用gnu版本的find.
26
27
28 # find . -mtime -1 -type f -exec tar rvf "$archive.tar" '{}' \;
29 # 對于其他風格的UNIX便于移植,但是比較慢.
30 # -------------------------------------------------------------------
31
32
33 exit 0
################################End Script#########################################
注意:以"-"開頭的文件名在使用"-"作為重定向操作符的時候,可能會產生問題.
應該寫一個腳本來檢查這個問題,并給這個文件加上合適的前綴.如:
./-FILENAME, $PWD/-FILENAME,或$PATHNAME/-FILENAME.
如果變量的值以"-"開頭,可能也會引起問題.
1 var="-n"
2 echo $var
3 #具有"echo -n"的效果了,這樣什么都不會輸出的.
- 之前工作的目錄."cd -"將回到之前的工作目錄,具體請參考"$OLDPWD"環境變量.
注意:一定要和之前討論的重定向功能分開,但是只能依賴上下文區分.
- 算術減號.
= 算術等號,有時也用來比較字符串.
1 a=28
2 echo $a # 28
+ 算術加號,也用在正則表達式中.
+ 選項,對于特定的命令來說使用"+"來打開特定的選項,用"-"來關閉特定的選項.
% 算術取模運算.也用在正則表達式中.
~ home目錄.相當于$HOME變量.~bozo是bozo的home目錄,并且ls ~bozo將列出其中的
內容. ~/就是當前用戶的home目錄,并且ls ~/將列出其中的內容,如:
bash$ echo ~bozo
/home/bozo
bash$ echo ~
/home/bozo
bash$ echo ~/
/home/bozo/
bash$ echo ~:
/home/bozo:
bash$ echo ~nonexistent-user
~nonexistent-user
~+ 當前工作目錄,相當于$PWD變量.
~- 之前的工作目錄,相當于$OLDPWD內部變量.
=~ 用于正則表達式,這個操作將在正則表達式匹配部分講解,只有version3才支持.
^ 行首,正則表達式中表示行首."^"定位到行首.
控制字符
修改終端或文本顯示的行為.控制字符以CONTROL + key組合.
控制字符在腳本中不能正常使用.
Ctl-B 光標后退,這應該依賴于bash輸入的風格,默認是emacs風格的.
Ctl-C Break,終止前臺工作.
Ctl-D 從當前shell登出(和exit很像)
"EOF"(文件結束符).這也能從stdin中終止輸入.
在console或者在xterm window中輸入的時候,Ctl-D將刪除光標下字符.
當沒有字符時,Ctrl-D將退出當前會話.在xterm window也有關閉窗口
的效果.
Ctl-G beep.在一些老的終端,將響鈴.
Ctl-H backspace,刪除光標前邊的字符.如:
1 #!/bin/bash
2 # 在一個變量中插入Ctl-H
3
4 a="^H^H" # 兩個 Ctl-H (backspaces).
5 echo "abcdef" # abcdef
6 echo -n "abcdef$a " # abcd f
7 # 注意結尾的空格 ^ ^ 兩個 twice.
8 echo -n "abcdef$a" # abcdef
9 # 結尾沒有空格 沒有 backspace 的效果了(why?).
10 # 結果并不像期望的那樣
11 echo; echo
Ctl-I 就是tab鍵.
Ctl-J 新行.
Ctl-K 垂直tab.(垂直tab?新穎,沒聽過)
作用就是刪除光標到行尾的字符.
Ctl-L clear,清屏.
Ctl-M 回車
################################Start Script#######################################
1 #!/bin/bash
2 # Thank you, Lee Maschmeyer, for this example.
3
4 read -n 1 -s -p $'Control-M leaves cursor at beginning of this line. Press Enter. \x0d'
5 #當然,'0d'就是二進制的回車.
6 echo >&2 # '-s'參數使得任何輸入都不將回顯出來
7 #+ 所以,明確的重起一行是必要的.
8
9 read -n 1 -s -p $'Control-J leaves cursor on next line. \x0a'
10 echo >&2 # Control-J 是換行.
11
12 ###
13
14 read -n 1 -s -p $'And Control-K\x0bgoes straight down.'
15 echo >&2 # Control-K 是垂直制表符.
16
17 # 關于垂直制表符效果的一個更好的例子見下邊:
18
19 var=$'\x0aThis is the bottom line\x0bThis is the top line\x0a'
20 echo "$var"
21 # 這句與上邊的例子使用的是同樣的辦法,然而:
22 echo "$var" | col
23 # 這將造成垂直制表符右邊的部分在左邊部分的上邊.
24 # 這也解釋了為什么我們要在行首和行尾加上一個換行符--
25 #+ 來避免一個混亂的屏幕輸出.
26
27 # Lee Maschmeyer的解釋:
28 # ---------------------
29 # In the [first vertical tab example] . . . the vertical tab
29 # 在這里[第一個垂直制表符的例子中] . . . 這個垂直制表符
30 #+ makes the printing go straight down without a carriage return.
31 # This is true only on devices, such as the Linux console,
32 #+ that can't go "backward."
33 # The real purpose of VT is to go straight UP, not down.
34 # It can be used to print superscripts on a printer.
34 # 它可以用來在一個打印機上打印上標.
35 # col的作用,可以用來模仿VT的合適的行為.
36
37 exit 0
################################End Script#########################################
Ctl-Q 繼續(等價于XON字符),這個繼續的標準輸入在一個終端里
Ctl-S 掛起(等價于XOFF字符),這個被掛起的stdin在一個終端里,用Ctl-Q恢復
Ctl-U 刪除光標到行首的所有字符,在某些設置下,刪除全行.
Ctl-V 當輸入字符時,Ctl-V允許插入控制字符.比如,下邊2個例子是等價的
echo -e '\x0a'
echo <Ctl-V><Ctl-J>
Ctl-V在文本編輯器中十分有用,在vim中一樣.
Ctl-W 刪除當前光標到前邊的最近一個空格之間的字符.
在某些設置下,刪除到第一個非字母或數字的字符.
Ctl-Z 終止前臺工作.
空白部分
分割命令或者是變量.包括空格,tab,空行,或任何它們的組合.
在一些特殊情況下,空白是不允許的,如變量賦值時,會引起語法錯誤.
空白行在腳本中沒有效果.
"$IFS",對于某些命令輸入的特殊變量分割域,默認使用的是空白.
如果想保留空白,使用引用.
注意事項:
[1] shell做大括號的命令擴展.但是命令本身需要對擴展的結果作處理.
[2] 例外:在pipe中的一個大括號中的代碼段可能運行在一個子shell中.
1 ls | { read firstline; read secondline; }
2 # 錯誤,在打括號中的代碼段,將運行到子shell中.
3 #+ 所以ls的輸出將不能傳遞到代碼塊中.
4 echo "First line is $firstline; second line is $secondline" # 不能工作
5
6 # Thanks, S.C.
[3] 換行符也被認為是空白.這也解釋了為什么一個空行也會被認為是空白.
第4章 變量和參數的介紹
======================
4.1 變量替換
------------
$ 變量替換操作符
只有在變量被聲明,賦值,unset或exported或者是在變量代表一個signal的時候,
變量才會是以本來的面目出現在腳本里.變量在被賦值的時候,可能需要使用"=",
read狀態或者是在循環
?? 快捷鍵說明
復制代碼
Ctrl + C
搜索代碼
Ctrl + F
全屏模式
F11
切換主題
Ctrl + Shift + D
顯示快捷鍵
?
增大字號
Ctrl + =
減小字號
Ctrl + -