subShell与代码块
subShell 是一群被括在圓括號里的命令,這些命令會在另外的進程里執(zhí)行。當你需要讓一組命令在不同的目錄下執(zhí)行時,這種方法可以讓你不修改主腳本的目錄。
例; 將某個目錄樹通過管道復制到另外一個地方。
tar -cf - . | (cd /newdir; tar -xpf - )
代碼塊概念上與subShell相同,但是它不會建立新的進程。代碼塊里的命令用花括號{}括起來,且對主腳本的狀態(tài)會產(chǎn)生影響。
?子shell:?每個shell腳本都有效地運行在父shell的一個子進程中. 這個父shell指的是在一個控制終端或在一個xterm窗口中給出命令提示符的那個進程.
shell腳本也能啟動它自已的子進程. 這些子shell能夠使腳本并行的, 有效的, 同時運行多個子任務.
圓括號中的命令列表( command1; command2; command3; ... )圓括號中命令列表的命令將會運行在一個子shell中.
子shell中的變量對于子shell之外的代碼塊來說, 是不可見的. 當然, 父進程也不能訪問這些變量, 父進程指的是產(chǎn)生這個子shell的shell. 事實上, 這些變量都是局部變量.
子shell中的目錄更改不會影響到父shell.
子shell中的目錄更改不會影響到父shell.父shell不受任何影響, 并且父shell的環(huán)境也沒有被更改.
子shell的另一個應用, 是可以用來檢測一個變量是否被定義.
[[ ${variable-x} != x || ${variable-y} != y ]]??或 [[ ${variable-x} != x$variable ]]? 或 [[ ${variable+x} = x ]]? 或 ?[[ ${variable-x} != x ]]
使用"|"管道操作符, 將I/O流重定向到一個子shell中, 比如ls -al | (command).
在大括號中的命令不會啟動子shell.{ command1; command2; command3; . . . commandN; }
?
?
Here Document: ?一個here document就是一段帶有特殊目的的代碼段. 它使用I/O重定向的形式將一個命令序列傳遞到一個交互程序或者命令中, 比如ftp, cat, 或者ex文本編輯器.
COMMAND <<InputComesFromHERE
...
InputComesFromHERE
limit string用來界定命令序列的范圍(譯者注: 兩個相同的limit string之間就是命令序列). 特殊符號<<用來標識limit string. 這個符號的作用就是將文件的輸出重定向到程序或命令的stdin中.與interactive-program < command-file很相似, 其中command-file包含:
而here document看上去是下面這個樣子:
#!/bin/bash
interactive-program <<LimitString
?command #1
?command #2
...
?LimitString
選擇一個名字非常詭異limit string能夠有效的避免命令列表與limit string重名的問題.
-選項用來標記here document的limit string (<<-LimitString), 可以抑制輸出時前邊的tab(不是空格). 這么做可以增加一個腳本的可讀性.
結(jié)尾的limit string, 就是here document最后一行的limit string, 必須從第一個字符開始. 它的前面不能夠有任何前置的空白. 而在這個limit string后邊的空白也會引起異常.空白將會阻止limit string的識別.
?
列表結(jié)構(gòu):?"與列表"和"或列表"結(jié)構(gòu)能夠提供一種手段, 這種手段能夠用來處理一串連續(xù)的命令.
與列表:?command-1 && command-2 && command-3 && ... command-n,如果每個命令執(zhí)行后都返回true(0)的話, 那么命令將會依次執(zhí)行下去. 如果其中的某個命令返
回false(非零值)的話, 那么這個命令鏈就會被打斷, 也就是結(jié)束執(zhí)行, (那么第一個返回false的命令, 就是最后一個執(zhí)行的命令, 其后的命令都不會執(zhí)行).
或列表:command-1 || command-2 || command-3 || ... command-n如果每個命令都返回false, 那么命令鏈就會執(zhí)行下去. 一旦有一個命令返回true, 命令鏈就會被打斷, 也就是結(jié)束執(zhí)行, (第一個返回true的命令將會是最后一個執(zhí)行的命令). 顯然, 這和"與列表"完全相反.
與列表和或列表的退出狀態(tài)碼由最后一個命令的退出狀態(tài)所決定。
false && true || echo false # false # 與下面的結(jié)果相同 ( false && true ) || echo false # false# But *not*false && ( true || echo false ) # (沒有輸出) # 注意, 以從左到右的順序進行分組與求值, 這是因為邏輯操作"&&"和"||"具有相同的優(yōu)先級. 最好避免這么復雜的情況, 除非你非常了解你到底在做什么.?進程替換
進程替換與命令替換很相似. 命令替換把一個命令的結(jié)果賦值給一個變量, 比如dir_contents=`ls -al`或xref=$( grep word datafile). 進程替換把一個進程的輸出提供給另一個進程(換句話說, 它把一個命令的結(jié)果發(fā)給了另一個命令).
?用圓括號擴起來的命令>(command) , <(command)啟動進程替換. 它使用/dev/fd/<n>文件將圓括號中的進程處理結(jié)果發(fā)送給另一個進程.在"<"或">"與圓括號之間是沒有空格的. 如果加了空格, 會產(chǎn)生錯誤
進程替換可以比較兩個不同命令的輸出, 甚至能夠比較同一個命令不同選項情況下的輸出.
comm <(ls -l) <(ls -al) diff <(ls $first_directory) <(ls $second_directory) cat <(ls -l) # 等價于ls -l | cat sort -k 9 <(ls -l /bin) <(ls -l /usr/bin) <(ls -l /usr/X11R6/bin) # 列出系統(tǒng)3個主要'bin'目錄中的所有文件, 并且按文件名進行排序. 注意是3個(查一下, 上面就3個圓括號)明顯不同的命令輸出傳遞給'sort' diff <(command1) <(command2) # 給出兩個命令輸出的不同之處.while read des what mask iface; doecho $des $what $mask $iface done < <(route -n) 一個更容易理解的等價代碼是: route -n | while read des what mask iface; do # 管道的輸出被賦值給了變量. echo $des $what $mask $iface done # 這將產(chǎn)生出與上邊相同的輸出. 然而, Ulrich Gayer指出. . .這個簡單的等價版本在while循環(huán)中使用了一個子shell, 因此當管道結(jié)束后, 變量就消失了.?
?
Shell中腳本變量和函數(shù)變量的作用域 ?http://blog.csdn.net/ltx19860420/article/details/5570902
(1)Shell腳本中定義的變量是global的,其作用域從被定義的地方開始,到shell結(jié)束或被顯示刪除的地方為止。解析:腳本變量v1的作用域從被定義的地方開始,到shell結(jié)束。調(diào)用函數(shù)ltx_func的地方在變量v1的作用域內(nèi),所以能夠訪問并修改變量v1。
(2)Shell函數(shù)定義的變量默認是global的,其作用域從“函數(shù)被調(diào)用時執(zhí)行變量定義的地方”開始,到shell結(jié)束或被顯示刪除處為止。函數(shù)定義的變量可以被顯示定義成local的,其作用域局限于函數(shù)內(nèi)。但請注意,函數(shù)的參數(shù)是local的。
解析:函數(shù)變量v2默認是global的,其作用域從“函數(shù)被調(diào)用時執(zhí)行變量定義的地方”開始,到shell結(jié)束為止。注意,不是從定義函數(shù)的地方開始,而是從調(diào)用函數(shù)的地方開始。打印命令在變量v2的作用域內(nèi),所以能夠訪問變量v2。
?解析:函數(shù)變量v2顯示定義為local的,其作用域局限于函數(shù)內(nèi)。打印命令在函數(shù)外,不在變量v2的作用域內(nèi),所以能夠不能訪問變量v2。函數(shù)參數(shù)是local的,通過位置變量來訪問。打印命令輸出函數(shù)的第一個參數(shù)。
(3)如果同名,Shell函數(shù)定義的local變量會屏蔽腳本定義的global變量。
?在函數(shù)被調(diào)用之前, 所有在函數(shù)中聲明的變量, 在函數(shù)體外都是不可見的,當然也包括那些被明確聲明為local的變量.
退出狀態(tài)碼
函數(shù)返回一個值, 被稱為退出狀態(tài)碼. 退出狀態(tài)碼可以由return命令明確指定, 也可以由函數(shù)中最后一條命令的退出狀態(tài)碼來指定(如果成功則返回0, 否則返回非0值). 可以在腳本中使用$?來引用退出狀態(tài)碼. 因為有了這種機制, 所以腳本函數(shù)也可以象C函數(shù)一樣有"返回值".
return終止一個函數(shù). return命令 [1]可選的允許帶一個整型參數(shù), 這個整數(shù)將作為函數(shù)的"退出狀態(tài)碼"返回給調(diào)用這個函數(shù)的腳本, 并且這個整數(shù)也被賦值給變量$?.函數(shù)所能返回最大的正整數(shù)是255. ?為了讓函數(shù)可以返回字符串或是數(shù)組, 可以使用一個在函數(shù)外可見的專用全局變量.
重定向函數(shù)的stdin函數(shù)本質(zhì)上其實就是一個代碼塊, 這就意味著它的stdin可以被重定向.
?
2:shell什么情況下會產(chǎn)生子進程以下幾個創(chuàng)建子進程的情況。(以下英文摘自info bash) 1:&,提交后臺作業(yè) If a command is terminated by the control operator `&', the shell executes the command asynchronously in a subshell. 2:管道 Each command in a pipeline is executed in its own subshell 3:括號命令列表 ()操作符Placing a list of commands between parentheses causes a subshellenvironment to be created 4:執(zhí)行外部腳本、程序: When Bash finds such a file while searching the `$PATH' for a command, it spawns a subshell to execute it. In other words, executing filename ARGUMENTSis equivalent to executingbash filename ARGUMENTS說明:大致上子進程的創(chuàng)建包括以上四種情況了。需要說明的是只要是符合上邊四種情況之一,便會創(chuàng)建(fork)子進程,不因是否是函數(shù),命令,或程序,也不會因為是內(nèi)置函數(shù)(buitin)或是外部程序。?
轉(zhuǎn)載于:https://www.cnblogs.com/fly-xiang-zhao/p/3675642.html
總結(jié)
以上是生活随笔為你收集整理的subShell与代码块的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: CDOJ_327 BerOS file
- 下一篇: 1067: [SCOI2007]降雨量