2014-04-23 56 views
0

是否有之間的差異:將腳本編入bash?

$ bash ~/script.sh 

和:

$ cat ~/script.sh | bash 

他們似乎表現略有不同,我不能完全弄清楚到底是怎麼回事。我的script.sh包含幾行bash,但是當我將它管入bash中時似乎中止了(但直接運行腳本時運行完成)。

以這兩種方式運行腳本有什麼不同?

此外,當我使用<,行爲是一樣的第一個例子(運行至完成):

bash <(~/script.sh) 

的腳本是沿

set -eux 
ssh CLUSTER_0_SERVER_0 "do_something" || ssh CLUSTER_0_SERVER_1 "do_something" 
ssh CLUSTER_1_SERVER_0 "do_something" || ssh CLUSTER_1_SERVER_1 "do_something" 
+0

請同時提供'script.sh'文件的內容。 –

+0

這個腳本非常簡單,做了一個'set -eux'然後幾行'ssh CLUSTER_0_SERVER_0「do_something」|| ssh CLUSTER_0_SERVER_1「do_something」'然後爲另一組機器'ssh CLUSTER_1_SERVER_0「do_something」|| ssh CLUSTER_1_SERVER_1「do_something」等等(基本上,它被ssh集成到一堆集羣中,並試圖在每個集羣中的一臺機器上運行do_something直到成功,然後它應該移動到下一個集羣)。我直接運行它的行爲與將腳本管道化到bash上的行爲有所不同。 –

+3

'bash <(foo.sh)'**完全不同於'bash

回答

2

你的方式行運行相同的腳本在語義都是不同的。

例如參見這個簡單的腳本:

#!/bin/bash 
echo $$ 
ssh 127.0.0.1 
echo $$ 

運行它直接將執行所有內的線與這兩個echo調用將打印相同的PID:一切是運行該腳本內的命令的單個處理,一個接一個。

通過cat ./script.sh | bash運行它會在開始時創建兩個不同的進程:一個用於執行cat,另一個用於bash。然而,當bash的解釋讀取並執行ssh命令,你得到一個錯誤(如果SSH沒有配置爲不打印):

Pseudo-terminal will not be allocated because stdin is not a terminal 

,然後你得到一個登錄到本機並立即離開, 查殺當前程序。因此,第二個值是不同的PID。在你的情況下,你有兩個由條件運算符鏈接的ssh命令。然而,從第一個解釋器被殺之後,第二個命令將無法執行。這就是爲什麼你只能得到執行的命令*_SERVER_0ssh

第三個案件的作品,但只是錯誤的。 <(cmd)構造意味着執行cmd並將其輸出作爲文件參數傳遞給調用者。在你的情況下,腳本不打印任何東西,這就是爲什麼你沒有看到任何錯誤。運行示例腳本,你會得到這樣的錯誤:

/dev/fd/63: line 1: 29355: command not found 

第四種情況(在評論中建議)bash < script只是一樣cat script | bash

正確運行bash腳本的方法是通過bash script./script(和shebang)。如果你想在同一個過程中運行指令,你也可以使用. scriptsource)所有其他的可能工作或不工作,這取決於一些幸運的副作用(通常他們不應該工作)。

+1

或'。 。/ script',它是「正確的」但是具有不同的語義。 – rici

+0

是的,但我沒有提到它只是因爲不同的語義。 –