作者 主題: 請教 "login shell" 的定義  (閱讀 34215 次)

0 會員 與 1 訪客 正在閱讀本文。

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #30 於: 2005-07-10 00:52 »
我可能較駑鈍,差別除了一般變數的繼承性外,還有什麼嗎?

我到是比較想不通那個 $$ --既是目前 shell 的PID , 那麼如下實驗:

$ echo $$
2422

$ (echo $$) 
2422    
為何顯示了parent shell 的 PID ?

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #31 於: 2005-07-10 01:22 »
引述: "kenduest"
引述: "b90220208"
我可能較駑鈍,差別除了一般變數的繼承性外,還有什麼嗎?

我到是比較想不通那個 $$ --既是目前 shell 的PID , 那麼如下實驗:

$ echo $$
2422

$ (echo $$) 
2422    
為何顯示了parent shell 的 PID ?


很正常吧。

因為目前的 shell 先看到了 $$,所以先替換過了,實際上 subshell 是去執行 echo 2422 這樣固定的結果。

==

所以答案是:
neted sub shell 與 sub shell 的差別就在變數已經先被解析與否
還有其他答案嗎?

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
請教 "login shell" 的定義
« 回覆 #32 於: 2005-07-10 01:37 »
引述: "b90220208"
引述: "kenduest"
引述: "b90220208"
我可能較駑鈍,差別除了一般變數的繼承性外,還有什麼嗎?

我到是比較想不通那個 $$ --既是目前 shell 的PID , 那麼如下實驗:

$ echo $$
2422

$ (echo $$) 
2422    
為何顯示了parent shell 的 PID ?


很正常吧。

因為目前的 shell 先看到了 $$,所以先替換過了,實際上 subshell 是去執行 echo 2422 這樣固定的結果。

==

所以答案是:
neted sub shell 與 sub shell 的差別就在變數已經先被解析與否
還有其他答案嗎?


怎樣算是其他答案?另外 () 內的變數本來就是會被先展開,沒有跳脫字元或者單引號都會預先被目前 shell 展開解釋不是呼?

請使用一般使用者這樣測試:

$ su -l -c "echo $USER" 或者是 $ (su -l -c "echo $USER")

你會發現 USER 結果變數不會是 root,因為先被展開了。

所以你比較一下如下差異:

$ su -l root -c "echo $$"$su -l root -c "echo \$$"

另外

代碼: [選擇]

 $
    Expands to the process ID of the shell.  In a  ()  subshell,  it  expands  to  the  process  ID of the current shell, not the subshell.


所以你這樣測試似乎不準確,因為 $ 時情況是根本不一樣 ?

==
I am kenduest - 小州

my website: http://kenduest.sayya.org/

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #33 於: 2005-07-10 01:56 »
那麼請問以下想法還正確嗎?
neted sub shell 與 sub shell 的差別之一在於變數已經先被解析與否

由下實驗來看以上想法似乎是錯的...(有誤請指正)
$ A=NIKE
$ echo $A
NIKE

$ (A=ADDIDA; echo $A) 
$ echo $A
ADDIDA
NIKE
  

===========
若變數先被current shell解析,那豈不變成如下樣:

$ (A=ADDIDA; echo $A) # 就此行言: 也就是實際上 neted sub shell 是去執行 A=ADDIDA; echo NIKE 這樣固定的結果
$ echo $A
NIKE  
NIKE  

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #34 於: 2005-07-10 02:09 »
我上文紅字部分是不一樣的結果

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
請教 "login shell" 的定義
« 回覆 #35 於: 2005-07-10 02:11 »
引述: "b90220208"
我上文紅字部分是不一樣的結果


??? 完全看不懂你寫的意思。

你該篇文章改了多次 (目前看到 2 次修改),目前你要問的是?

() 裡面有 $$ 意思還是原本 shell 的 pid,不是 subshell 的 pid,這文件已經交代過了。 執行還是 subshell 執行沒錯,但是 $$ 值是原本 shell 的 pid值,而不是 subshell 的 pid。


所以我回應是針對你之前說的:

引述: "b90220208"

$ echo $$
2422

$ (echo $$) 
2422


這不單純是 $$ 預先展開的問題,而且還與我上面解釋那段話的說明有關係。

==
I am kenduest - 小州

my website: http://kenduest.sayya.org/

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #36 於: 2005-07-10 02:27 »
先談一般的自定變數:

例子與結果:
------------------------
$ A=NIKE
$ echo $A
結果1-> NIKE

$ (A=ADDIDA; echo $A) 
$ echo $A
結果2-> ADDIDA
結果3-> NIKE  
------------------------

但是,
若 neted sub shell 的變數會先被 parent shell 解析,那麼同樣的例子結果將變成
結果1-> NIKE
結果2-> NIKE
結果3-> NIKE

因為這行:  $ (A=ADDIDA; echo $A) 
將"先"被 parent shell 解析成:  $ (A=ADDIDA; echo NIKE) , 再交給 neted sub shell 解譯並執行.

不好意思,有誤請指正.

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
請教 "login shell" 的定義
« 回覆 #37 於: 2005-07-10 02:38 »
引述: "b90220208"
先談一般的自定變數:

例子與結果:
------------------------
$ A=NIKE
$ echo $A
結果1-> NIKE

$ (A=ADDIDA; echo $A) 
$ echo $A
結果2-> ADDIDA
結果3-> NIKE  
------------------------

但是,
若 neted sub shell 的變數會先被 parent shell 解析,那麼同樣的例子結果將變成
結果1-> NIKE
結果2-> NIKE
結果3-> NIKE

因為這行:  $ (A=ADDIDA; echo $A) 
將"先"被 parent shell 解析成:  $ (A=ADDIDA; echo NIKE) , 再交給 neted sub shell 解譯並執行.

不好意思,有誤請指正.


好,那表示你正確,所以我前面說先帶入論點是錯的,那問題還是拉回到原點,那就是你使用

echo $$



(echo $$)

我前面文章已經說到,bash shell 文件都說了,() 裡面的 $$ 是原本 shell 的 pid,而不是 subshell 的 pid。所以這問題已經沒啥爭議了。

==
I am kenduest - 小州

my website: http://kenduest.sayya.org/

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #38 於: 2005-07-10 02:42 »
就 output 結果言: echo $$ = (echo $$)

所以 neted sub shell 與 sub shell 的差別為何呢?
(差別除了一般變數的繼承特色外,還有什麼嗎?)

先說抱歉,我很珍惜肯回答我的朋友的,所以如有冒犯,請您勿必見諒(我表達能力不是很好)

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
請教 "login shell" 的定義
« 回覆 #39 於: 2005-07-10 02:59 »
引述: "b90220208"
就 output 結果言: echo $$ = (echo $$)

所以 neted sub shell 與 sub shell 的差別為何呢?
(差別除了一般變數的繼承特色外,還有什麼嗎?)

先說抱歉,我很珍惜肯回答我的朋友的,所以如有冒犯,請您勿必見諒(我表達能力不是很好)


nested sub shell ??

$ (a=100 ; (echo $a ; a=200 ; echo $a) ; echo $a )

result :

100
200
100


==
I am kenduest - 小州

my website: http://kenduest.sayya.org/

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #40 於: 2005-07-10 03:10 »
太好了!(先感謝你不厭其煩的解說...)
您上文的例子我如今已能用看的就知結果,總算不用再借重於實驗了.

再請教:
文件雖說 () 中的 $ 會展開成 parent shell 的 PID,
還有之前就由實驗得知的 () 中的一般變數會繼承自 parent shell (當然得 parent 已設定過),
但一是文件規定,二是實驗得知,總是感覺只能"強記",有點痛苦,不知其原理為何,才會有這樣的結果?

還有,誠如之前 eric 問過的:
引用
用 nested sub shell 除了 env variable 之外的環境也會被subshell 繼承.
  我能說它是 "current shell 僅 fork 出自己,然後就直接執行(cmd) 中的 cmd" 嗎 ?

我想這或許可能就是"道理所在"了,有誰能說一下呢?...感激不盡#

最後,所以 nested sub shell 與 sub shell 的差別,除了一般(自定)變數的繼承特色外就沒有別的了,對嗎?

ericshei

  • 全區板主
  • 俺是博士!
  • *****
  • 文章數: 2257
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #41 於: 2005-07-10 09:38 »
定義就是定義囉! 真要挖到原理,我猜可能得去 trace source code 了!

除了原理之外in case,用nested sub shell所產生的sub shell還是有自己的PID,因此想請教的是,"在nested sub shell中$$為parent sub shell"這樣的設計理念為何?

我把這篇移到精華區!  :wink:

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17464
    • 檢視個人資料
    • http://www.study-area.org
請教 "login shell" 的定義
« 回覆 #42 於: 2005-07-10 11:34 »
果然經典...

感謝小州老師幫忙釐清觀念!
發現我之前的理解也不很透切呢~~~
前面也有一些誤導, 真是不好意思...  ^_^

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
請教 "login shell" 的定義
« 回覆 #43 於: 2005-07-10 13:12 »
引述: "b90220208"
太好了!(先感謝你不厭其煩的解說...)
再請教:
文件雖說 () 中的 $ 會展開成 parent shell 的 PID,
還有之前就由實驗得知的 () 中的一般變數會繼承自 parent shell (當然得 parent 已設定過),但一是文件規定,二是實驗得知,總是感覺只能"強記",有點痛苦,不知其原理為何,才會有這樣的結果?


以我知道的層面來看的話,我是認為主要是 () 在某方面有使用上的方便,其方式是改用 subshell 的方式來提供該功能。而以上程式撰寫發展上考慮到更透通,$$ 維持在 parent shell 程式的 pid 總是有其必要。

這樣說好了,比方 c++ 內使用:

int num=100;
cout << num << endl;
{
   int num=200;
   cout << num << endl;
}

cout << num << endl;

其結果輸出是分別為 100,200,100

就 c++ 程式來看待,都是一個 process 來執行該敘述的。不過 shell 程式本身需要以 subshell 方式實作該功能 ( 也就是使用 (foo1 ; foo2) 敘述 ),所以產生出另外一個 child process 去執行流程敘述 (該 shell 有原本 parent process 變數環境)。

考慮到透通環境,使用者只要能夠知道 () 內的變數配置使用另外獨立一個區塊即可,不用去管實際實作是 parent 產生 child process 的情況。那這樣 $$ 都是 parent process 不都是很好嗎?

引用

還有,誠如之前 eric 問過的:
引用
用 nested sub shell 除了 env variable 之外的環境也會被subshell 繼承.
  我能說它是 "current shell 僅 fork 出自己,然後就直接執行(cmd) 中的 cmd" 嗎 ?

我想這或許可能就是"道理所在"了,有誰能說一下呢?...感激不盡#

最後,所以 nested sub shell 與 sub shell 的差別,除了一般(自定)變數的繼承特色外就沒有別的了,對嗎?
I am kenduest - 小州

my website: http://kenduest.sayya.org/

kenduest

  • 酷!學園 學長們
  • 俺是博士!
  • *****
  • 文章數: 3675
    • 檢視個人資料
    • http://kenduest.sayya.org
請教 "login shell" 的定義
« 回覆 #44 於: 2005-07-10 13:16 »
引述: "netman"
果然經典...
感謝小州老師幫忙釐清觀念!
發現我之前的理解也不很透切呢~~~
前面也有一些誤導, 真是不好意思...  ^_^


kenny,你這樣說實在很見外咧  :o

太客氣與 38 不好啦。

==
I am kenduest - 小州

my website: http://kenduest.sayya.org/

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #45 於: 2005-07-10 14:19 »
引述: "netman"
果然經典...

感謝小州老師幫忙釐清觀念!
發現我之前的理解也不很透切呢~~~
前面也有一些誤導, 真是不好意思...  ^_^

不好意思,不知可以麻煩 netman 兄把釐清的東東 post 一下,因我也想看看,畢竟是花了這麼多時間了,沒弄清楚有點遺憾啊...

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #46 於: 2005-07-10 14:29 »
關於以下的疑問都無人理我,難道是我犯了什麼錯嗎?:
--------------------------------------------------------
 nested sub shell 與 sub shell 的差別,除了一般(自定)變數的繼承特色外就沒有別的了,對嗎?
--------------------------------------------------------

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17464
    • 檢視個人資料
    • http://www.study-area.org
請教 "login shell" 的定義
« 回覆 #47 於: 2005-07-10 22:27 »
1) su 所帶出的 shell 有點特別. 我沒仔細研究過, 在某些版本中, su 似乎會 reset 環境. 看來不單純是 shell invocation 的問題.
2) 我也忽略了 nested subshell 的變數在 command line 已被展開的特性. 這還需要再多找些文件來說明...
3) 討論沒分對錯, 別想太多. 大家各有所忙, 不見得會馬上能回你的問題. 請體諒. 有時, 自己找答案, 更勝於等別人.

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #48 於: 2005-07-11 01:11 »
請教:
-----------------------
關於變數設定
$ a=NIKE
算是內建於 shell 的指令嗎?

-----------------------
以下單引號組所包圍的指令的執行是在 "current" or "sub" shell ? 其與 () , {} 有何異同?
$ cd /lib/modules/'uname -r'/kernel

另外,
$ cd 'echo $HOME' 為何不能執行呢?
p.s 我知 $ cd $HOME 才是正確的,只是想問:
既然上方兩例的單引號組所包圍的指令同樣都會產生 stdout ,為何一可行而另一卻不可行?

ericshei

  • 全區板主
  • 俺是博士!
  • *****
  • 文章數: 2257
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #49 於: 2005-07-11 11:33 »
引述: "b90220208"
請教:
-----------------------
關於變數設定
$ a=NIKE
算是內建於 shell 的指令嗎?

-----------------------
以下單引號組所包圍的指令的執行是在 "current" or "sub" shell ? 其與 () , {} 有何異同?
$ cd /lib/modules/'uname -r'/kernel


`uname -r`會產生sub process來執行. 與()及{}有資料流處理上的差異!

引用
另外,
$ cd 'echo $HOME' 為何不能執行呢?
p.s 我知 $ cd $HOME 才是正確的,只是想問:
既然上方兩例的單引號組所包圍的指令同樣都會產生 stdout ,為何一可行而另一卻不可行?


因為要用倒引號,不是單引號.單引號是使quote用途,會把$的變數替換動會取消.

[ericshei@tcl ericshei]$ echo cd `echo $HOME`
cd /home/ericshei
[ericshei@tc ericshei]$ echo cd 'echo $HOME'
cd echo $HOME

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17464
    • 檢視個人資料
    • http://www.study-area.org
請教 "login shell" 的定義
« 回覆 #50 於: 2005-07-11 13:22 »
代碼: [選擇]
[netman@www tmp]$ (a=100 ; (echo $a ; a=200 ; echo $a) ; echo $a )
100
200
100
[netman@www tmp]$ echo $a

[netman@www tmp]$ { a=100 ; { echo $a ; a=200 ; echo $a; } ; echo $a; }
100
200
200
[netman@www tmp]$ echo $a
200

b90220208

  • 鑽研的研究生
  • *****
  • 文章數: 557
    • 檢視個人資料
請教 "login shell" 的定義
« 回覆 #51 於: 2005-07-11 14:09 »
THANKS!
netman 舉的例子我了,只是:
引用

`uname -r`會產生sub process來執行. 與()及{}有資料流處理上的差異!

嗯,可以再說詳細些嗎...THANKS.

$ `指令`
會在 subshell 還是在 current shell 解譯與執行指令呢?

還有,關於
$ a=NIKE
會再開個 sub process 來執行嗎?

netman

  • 管理員
  • 俺是博士!
  • *****
  • 文章數: 17464
    • 檢視個人資料
    • http://www.study-area.org
請教 "login shell" 的定義
« 回覆 #52 於: 2005-07-11 14:52 »
我也不確定, 你先 try try 看...