2014-03-27 66 views
0

我想了解這個代碼,因爲我在shell腳本shell腳本代碼 - 不能理解

1 #!/bin/bash 
2 PATH=$PATH:/bin:/usr/bin 
3 
4 
5 TMP_FILE=/tmp/i_am_running 
6 [ -f $TMP_FILE ] && exit 
7 touch $TMP_FILE 
8 
9 
10 /usr/bin/python /home/ahmed/Desktop/python.py 
11 rm $TMP_FILE 
  1. 爲什麼我們用線1和2是初學者?
  2. 我剛纔要是再else結構

    如果 然後 網絡

着我們轉換線6-7在結構學到了什麼?

+1

新手指南BASH:HTTP://www.tldp。 org/LDP/Bash-Beginners-Guide/html/ – iamauser

回答

1

我會走行線這似乎是一個缺陷:應該有前無空格#。無論如何,這是一個「shebang線」,告訴使用什麼解釋器。有些人更喜歡看到#!/usr/bin/env bash,如果用戶想要在非默認版本的bash下運行,它會提供更大的靈活性。5,創建一個包含路徑的變量。

6:[ -f $TMP_FILE ] && exit表示「如果文件存在,退出(帶有成功代碼,即0)」。你說得對,它可以寫成「if」語句。還請注意[ -f $TMP_FILE ]實際上是test -f $TMP_FILE的簡寫;知道這一點,你可以看看man test看看各種選項。

7:現在我們知道文件不存在了,我們創建它。或者至少我們嘗試 - 由於各種原因,這可能會失敗,並且不會檢查返回代碼!將set -e放在任何shell腳本的頂部是一種很好的做法,這意味着「如果存在未經檢查的失敗代碼,則停止」。

10:接下來我們運行Python。不是用戶對Python解釋器的選擇,但特別是/ usr/bin /。再次,這不是最佳實踐 - 最好是在Python腳本本身的頂部有一個#!/usr/bin/env python shebang行,並直接調用它,從而允許用戶的環境選擇所需的Python解釋器。

11:現在我們刪除$ TMP_FILE,這將允許我們下次再次運行。因此它是一種「鎖定文件」,雖然不是一個非常強大的實施。例如,如果用戶在Python腳本運行時按Ctrl-C中斷腳本,會發生什麼情況?鎖定文件將被留下。在這種情況下,您可以使用Bash中的trap內建刪除在退出之前的鎖定文件。

也許你應該直接在Python中集成鎖文件功能,並擺脫這個包裝腳本。你可以做到這一點的把這個在你的Python腳本的頂部,並擺脫了包裝完全的:

import errno 
import fcntl 
import sys 

lockfile = open('/tmp/i_am_running', 'a') 
try: 
     fcntl.flock(lockfile, fcntl.LOCK_EX | fcntl.LOCK_NB) 
except IOError as ex: 
     if ex.errno == errno.EWOULDBLOCK: 
      sys.exit("oops, already running") 
     else: 
      raise 

# now the file is locked, do whatever you need and it will unlock on exit 

最後,請注意,這樣的鎖文件規範位置上的Linux系統是/var/run/下,不/tmp/

+0

太棒了!我非常瞭解。你可以修改這個概念來處理程序崩潰或用戶停止它的情況嗎? – user3265370

+0

當然,我編輯我的答案添加一些代碼,使其更強大。 –

+0

我很抱歉,但它看起來像蟒蛇。我應該制定一個單獨的程序以避免崩潰問題?我可以修改shell腳本嗎? – user3265370

1

第1行不應縮進;第一個字符應該是#。它告訴內核在這種情況下使用指定的解釋器/bin/bash來執行這個程序。如果您願意,可以在寬泛的範圍內指定任何可執行文件(不是腳本)作爲解釋器。

2號線正在防止荒謬;如果某人有一個沒有/bin/usr/bin的PATH設置,那麼他們已經遇到了一些麻煩。但是,這確保了它們存在。 (但是請注意,在Solaris,/bin是一個符號鏈接/usr/bin,所以沒有必要在兩者$PATH,但一個或另一個應該肯定是有。)

是的,你可以轉換成6-7成線:

if [ -f "$TMP_FILE" ] 
then exit 
fi 
touch "$TMP_FILE" 

在您選擇的鎖定文件名就足夠了,如果有隻在系統上的單一用戶,它不適合更廣泛的應用程序(兩個人不能同時使用文件一次)。

您可以通過添加trap命令來清理臨時文件,提高代碼:

trap "rm -f '$TMP_FILE'; exit 1" 0 1 2 3 13 15 
…commands… 
rm -f "$TMP_FILE" 
trap 0 

如果程序崩潰或中斷,則該刪除臨時文件。

1
  1. 第一行是所謂的shebang。它告訴試圖運行該文件如何運行它。第二行確保/bin/usr/bin位於$PATH上,方法是將它們附加到該變量,以便如果x位於這兩個目錄中的一個目錄中(或其他某個目錄已存在於$PATH中),則只需運行命令x即可運行。

  2. 第6行和第7行實際上並沒有任何關係。本身就是6號線也可以變成一個if聲明:

    1:

    if [ -f $TMP_FILE ] 
    then 
        exit 
    fi 
    
+0

謝謝。第5行是幹什麼的? – user3265370

+0

@ user3265370它在名爲'TMP_FILE'的變量中放置一個字符串(看起來像一個路徑)。 (這個變量稍後會用到。)聽起來你應該閱讀一個shell腳本教程,而不是在這裏重點討論問題。 – Biffen

1
1 #!/bin/bash 
2 PATH=$PATH:/bin:/usr/bin 
3 
4 
5 TMP_FILE=/tmp/i_am_running 
6 [ -f $TMP_FILE ] && exit 
7 touch $TMP_FILE 
8 
9 
10 /usr/bin/python /home/ahmed/Desktop/python.py 
11 rm $TMP_FILE 
  1. 第一行:指定解釋,這意味着使用bash
  2. 第二行執行:添加/bin/usr/bin到enviroenment變量PATH,這是不正常使用,這可能會發生,因爲有人刪除路徑。
  3. 6-7行:如果文件/tmp/i_am_running存在,退出。別的,創建它。見this post。 的if-else要做到這一點,您可以使用:

    if [ -f "$TMP_FILE" ] 
    then 
        exit 
    fi 
    touch "$TMP_FILE" 
    
  4. 10-11行:運行程序python.py和刪除$ TMP_FILE