在线观看不卡亚洲电影_亚洲妓女99综合网_91青青青亚洲娱乐在线观看_日韩无码高清综合久久

鍍金池/ 教程/ Linux/ shell 學習三十八天---執(zhí)行順序和 eval
shell 學習四十五天---xargs
shell學習第三天
shell 學習十五天---join 連接字段
shell 學習第二天
shell 學習四十三天---臨時性文件的建立與使用
shell 學習第六天---小結
shell 學習三十三天---關于重定向
shell 學習二十九天---循環(huán)
shell 學習二十四天---提取開頭或結尾數行
shell 學習第十天---sed 查找與替換
shell 學習第十一天---sed 正則的精確控制
shell 學習三十天---break,continue,shift,getopts
shell 學習---小結
shell 學習三十一天---函數問題
shell 學習第四天---華麗的 printf 輸出
shell 學習三十五天---波浪號展開與通配符
shell 學習十九天---文本塊排序
shell 學習十二天---行與字符串
shell 學習二十一天---重新格式化段落
shell 學習十八天---文本排序
shell 學習十三天---sed 案例分析
shell 學習四十一天---列出文件 ls 和 od 命令
shell 學習十七天---awk 命令
shell 學習三十六天---命令替換
shell 學習十六天---join 練習
shell 學習三十二天---read 讀取一行
shell 學習二十二天---計算行數,字數以及字符數
shell 學習小總結---本章小結
shell 學習第八天---擴展正則表達式(ERE)
shell 學習四十二天---使用 touch 更新文件時間
shell 學習二十八天---case 語句
shell 學習三十九天---內建命令
shell 學習第一天
shell 學習三十四天---printf 詳解
shell 學習二十六天---變量與算數
shell 學習三十八天---執(zhí)行順序和 eval
shell 學習四十四天---尋找文件
shell 學習二十五天---神器的管道符
shell 學習十四天---使用 cut 選定字段
shell 學習第五天---基本的I/O重定向
shell 學習四十天---awk 的驚人表現
shell 學習二十天---sort 的其他內容以及 uniq 命令
shell 學習二十三天---打印
shell 學習第九天---分組
shell 學習四十八天---文件校驗和匹配
shell 學習二十七天---退出狀態(tài)和 if 語句
shell 學習四十七天---文件比較 cmp,diff,patch
shell 學習第七天---基礎正則表達式(BRE)
shell 學習四十六天---文件系統(tǒng)的空間信息 df 和 du 命令
shell 學習三十七天---引用
shell 學習小結

shell 學習三十八天---執(zhí)行順序和 eval

shell 從標準輸入或腳本中讀取的每一行稱為管道,它包含了一個或多個命令,這些命令被一個或多個管道字符(|)隔開.

事實上嗨喲很多特殊符號可用來分割單個的命令:分號(;),管道(|),&,邏輯 AND(&&),邏輯 OR(||).對于每一個地區(qū)的管道,shell 都會將命令分割,為管道設置 I/O,并且對每一個命令依次執(zhí)行下面的操作.

看起來很復雜,但是每一個步驟都是在 shell 的內存里發(fā)生的,shell 不會真的把每個步驟的發(fā)生演示給我們看.所以這是我們分析 shell 內存的情況,從而知道每個階段的命令行是如何被轉換的.
案例:

mkdir /tmp/x #建立臨時性目錄  
cd /tmp/x #切換到該目錄  
touch f1 f2 #建立文件  
f=f y=”a b” #賦值兩個變量  
echo ~+/${f}[12] $y $(echo cmd subst) $((3+2))>out      #忙碌的命令  

上述命令的執(zhí)行步驟:

  1. 命令一開始會根據 shell 語法而分割為 token.最重要的一點是:I/O 重定向>out 在這里是被識別的,并存儲供稍后使用.流程繼續(xù)處理下面這行,其中每個 token 的范圍顯示于命令下方的行上:
    echo ~+/${f}[12] $y $(echo cmd subst) $((3 + 2))
    | 1 | |----- 2 ----| |3 | |-------- 4----------| |----5-----|
  2. 堅持第一個單詞(echo)是否為關鍵字,例如 if 或 for.在這里不是,所以命令行不變繼續(xù)執(zhí)行.
  3. 堅持第一個單詞(依然是 echo)是否為別名.這里不是,所以命令行不變繼續(xù)處理.
  4. 掃描所有單詞是否需要波浪號展開.在這里~+等同于$PWD,也就是當前目錄.token2 將被修改,處理繼續(xù)如下:
    echo /tmp/x/${f}[12] $y $(echo cmd subst) $((3 + 2))
    | 1 | |------- 2 -------| |3 | |-------- 4----------| |----5-----|
  5. 變量展開:token2 與 3 都被修改.產生:
    echo /tmp/x/${f}[12] a b $(echo cmd subst) $((3 + 2))
    | 1 | |------- 2 -------| | 3 | |-------- 4----------| |----5-----|
  6. 處理命令替換.注意,這里可遞歸引用列表里的所有步驟!在此例中,因為我們要試圖讓所有的東西容易理解,因此命令修改了token4,結果:
    echo /tmp/x/${f}[12] a b cmd subst $((3 + 2))
    | 1 | |------- 2 -------| | 3 | |--- 4 ----| |----5-----|
  7. 執(zhí)行算術替換 .修改 token5,結果:
    echo /tmp/x/${f}[12] a b cmd subst 5
    | 1 | |------- 2 -------| | 3 | |--- 4 ----| |5|
  8. 前面所有的展開產生的結果,都將再一次被掃描,看看是否有$IFS 字符.如果有,則他們是作為分隔符,產生額外的單詞.例如,兩個字符$y 原來是組成一個單詞,但展開式”a 空格 b”,在此階段被切分為兩個單詞:a 與 b.相同方式也應用于命令替換$(echo cmd subst)的結果上.先前的 token3 變成了 token3 與 4.先前的 token4 則成了 token5 與 6.結果:
    echo /tmp/x/${f}[12] a b cmd subst 5
    | 1 | |------- 2 -------| 3 4 |-5-| |- 6 -| 7
  9. 通配符展開.token2 變成了 token2 與 token3:
    echo /tmp/x/$f1 /tmp/x/$f2 a b cmd subst 5
    | 1 | |---- 2 ----| |---- 3 ----| 4 5 |-6-| |- 7 -| 8
  10. 這時,shell 已經準備好了要執(zhí)行最后的命令了,他會去尋找 echo.正好 ksh93 與 bash 的 echo 都內建到 shell 中了
    11.shell 實際執(zhí)行命令.首先執(zhí)行>out 的 I/O 重定向,在調用內部的 echo 版本,顯示最后的參數.

最后的結果:

$cat out  
/tmp/x/f1 /tmp/x/f2 a b cmd subst 5  

eval 語句
shell 中的 eval 這個命令很神奇,他能把字符串當做命令來執(zhí)行.PS:這個字符串必須是可執(zhí)行的 bash 命令才可以.
案例:
eval “l(fā)s” #輸出當前目錄的所有文件

語法: eval [參數]
補充說明:eval 可讀取一連串的參數,然后再依慘呼本身的特性來執(zhí)行.
參數:不限數目,彼此之間用分號隔開.
案例:我有一個文件test.txt
命令:cat test.txt
輸出:hello world
命令:myfile="cat test.txt"
命令:echo $myfile
輸出:cat test.txt
命令:eval $myfile
輸出:hello world
eval $myfile這條命令可以看出,eval 進行了變量替換,將字符串中屬于 bash 的命令執(zhí)行了.
把拼接起來的字符串當作命令執(zhí)行,這就是 eval 的神奇之處.

subShell 與代碼塊
subShell 是一群被括在圓括號里的命令,這些命令會在另外的進程中執(zhí)行.當你需要讓一小組的命令在不同的目錄下執(zhí)行時,這種方式可以讓你不必修改主腳本的目錄,直接處理這種情況.
例如:tar -cf -.| (cd /tmp;tar -xpf -)
左邊的 tar 命令會產生當前目錄的 tar 打包文件,將他傳送給標準輸出.這份打包文件會通過管道傳遞給走遍的 subShell 里的命令.開頭的 cd 命令會先切換到新目錄,也就是讓大寶文件在此目錄下解開.然后,走遍的 tar 將從打包文件中解開文件.注意,執(zhí)行此管道的 shell(或腳本)并未更改他的目錄.

代碼塊概念上與 subShell 雷同,只不過他不會建立新的進程.代碼塊里的命令以花括號({})括起來,且對主腳本的狀態(tài)會造成影響(例如他的當前目錄).一般來說,花括號被視為 shell 關鍵字,意即他們只有出現在命令的第一個符號時會被識別.實際上:這表示你必須將結束花括號放置在換行字符或分號之后.例如:

 cd /home/directory||{  
echo could not change to /home/directory!>&2  
echo you lose !>&2  
exit1  
}  

I O重定向也可以套用 subShell 與代碼塊里.在該情況下,所有的命令會從重定向來源讀取它們的輸入或傳送他們的輸出.

??????????????????subShell與代碼塊

結構

定界符

認可的位置

另外的進程

SubShell

()

行上的任何位置

代碼塊

{}

在換行字符,分號或關鍵字之后

注意:代碼塊里的 exit 會終止整個腳本.
我們通常在 shell 中運行一個腳本只需要簡單的調用./[script_name]即可,這種方式下,shell 會啟動一個子進程來運行該腳本,稱為 subShell,當 subShell 運行完成,子進程結束.父進程的環(huán)境不會有任何改變.
案例:bash 代碼

 #!/bin/bash  
cd /var/cache  
testname="fine"  

分別在 shell 中運行

  1. ./test.sh;echo $testname 會發(fā)現還是位于原來的目錄中,$testname 的值書粗話為 null.
  2. source ./test.sh;echo $testname 這里就不一樣了,現在你位于/var/cache 中,$testname 的值也變成了 fine

用 source 命令來運行腳本,不會產生子進程,腳本在 shell 的進程空間中執(zhí)行,所以運行重定義的變量,執(zhí)行的操作,都會在 shell 的運行環(huán)境中保留下來.