2015-06-05 77 views
7

首先讓我說明什麼可行。如果我在文件路徑中使用flock,它將起作用。無法使用文件描述符使用羣集來鎖定文件

端子1:

[[email protected] ~]# flock -x -n /tmp/foo.txt -c "sleep 100" 

端子2:

[[email protected] ~]# flock -x -n /tmp/foo.txt -c "sleep 100" 
[[email protected] ~]# echo $? 
1 

以上顯示我首先在第一終端獲取關於/tmp/foo.txt的排他鎖。然後在第二個終端中,當我嘗試獲取同一個文件上的鎖時,它會失敗。

現在讓我知道什麼是行不通的。如果我使用文件描述符羣,它不起作用。

端子1:

[[email protected] ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt 

端子2:

[[email protected] ~]# { flock -x -n 100; sleep 100; } 100> /tmp/foo.txt 

以上顯示我首先嚐試在所述第一終端上/tmp/foo.txt獲取鎖。然後在第二個終端中,當我嘗試獲取對同一個文件的鎖定時,它會成功。我預料它會失敗,就像前面的例子一樣。它爲什麼成功?

回答

10

您正在使用-n這將終止,如果鎖不能立即獲得flock將退出代碼1.無法在第一個終端執行你的代碼。因此後,它睡覺了100秒。接下來,當您在另一個終端執行相同操作時,flock失敗並返回1,但由於存在;,並且您不對返回碼做任何事情,因此shell將繼續執行下一條語句並休眠100秒。

因此,您需要對雞羣的返回代碼做出如下決定。

(flock -x -n 100 || exit 55; sleep 100;) 100> /tmp/foo.txt 

現在,如果您在一個終端上執行上述行,它將睡眠100秒。接下來,如果您在另一個終端上運行代碼,它將立即返回提示。執行echo $?,您將看到它已返回55,因爲我們想使用||返回。

||做什麼是短路。如果flock返回的0與正常退出相同,那麼這是一個true shell的值,它不會執行表達式的右邊,因此轉到下一個語句。如果返回值是1這是一個爲殼,它將繼續評估右側表達式是exit 55,因此退出。你也可以通過if-then-fi來做到這一點。

另請注意,我已經使用括號()而不是花括號{}。這是因爲,如果使用curley-braces,那麼命令將在當前shell中執行,如果使用exit,則它將從當前shell中退出。括號將創建一個子shell,因此從那裏執行一個exit會終止子shell並將其返回到原始shell。

它適用於您的第一個示例,使用-c,因爲您在flock參數中包含單個命令。因此,如果flock無法獲取該鎖,它將不會執行該語句並終止。