2017-01-03 83 views
2

我一直在使用參數總是開發了我的shell腳本,一個日常的基礎上,甚至開發一些自動化腳本時。但是,最近我嘗試了一種不同的方法,將環境變量導出到腳本中。我應該使用參數還是導出環境變量?

#!/bin/bash 

: ${USER?"Requires USER"} 
: ${FIRST_NAME?"Requires FIRST_NAME"} 
: ${LAST_NAME?"Requires LAST_NAME"} 
: ${EMAIL?"Requires EMAIL"} 

set -x 

setup_git_account(){ 
    su - "${USER}" -c "git config --global user.name '${FIRST_NAME} ${LAST_NAME}'" 
    su - "${USER}" -c "git config --global user.email '${EMAIL}'" 
} 

setup_git_account 

這將確保一個更小的代碼,很容易檢查是否所有必需的變量初始化並且也更好地瞭解腳本是幹什麼的,一旦所有的變量都在外部聲明。

export USER='john' && export FIRST_NAME='John' && export LAST_NAME='Doe' && export EMAIL='[email protected]' && setup_git_account.sh 

這可能是這樣表示,如果與接收的參數來實現:

setup_git_account.sh --user 'john' --firstname 'John' --lastname 'Doe' --email '[email protected]' 

然而,最後一個,需要的編碼方式多行來實現getopts開關的情況下,檢查傳遞的參數值等

不管怎樣,我知道我們已經習慣了第二種方法,但我認爲第一種方法也有幾個好處。如果在所提出的方法之間有任何不利之處,我想從你那裏聽到更多的消息。我應該使用哪一個?

謝謝!

+3

有了環境變量,如果不是所有的變量總是顯式設置,那麼顯然會出現意外行爲。他們可以通過系統設置(偶然),你的bashrc,你之前運行的腳本等。 – hasufell

+1

我建議使用參數 – hek2mgl

+1

使用小寫變量名稱。特別是'USER'已經在使用中,並且*將會被設置在您的環境中。 – chepner

回答

1

你的價值觀都不是可選的;我只會使用位置參數。

: ${1?"Requires USER"} 
: ${2?"Requires FIRST_NAME"} 
: ${3?"Requires LAST_NAME"} 
: ${4?"Requires EMAIL"} 

sudo -u "$1" git config --global user.name "$2 $3" user.email "$4" 

爲用戶提供指定任意順序值的方式只是一個不必要的複雜因素。

只需將調用腳本

setup_git_account.sh 'john' 'John' 'Doe' '[email protected]' 

重新考慮的姓氏和名字是否需要單獨的參數。無論如何,它們被腳本合併到git config的單個參數中;只是把這個名字當作一個單一的參數。

setup_git_account.sh 'john' 'John Doe' '[email protected]' 

(根據需要進行適當的更改到腳本)。

+0

完美!非常感謝您的回答! –

0

我從來沒有使用你的方法。我認爲使用參數沒有缺點。這是使用參數的常用方法,如果您使用longopts,則可以使用自描述。 在我看來ENV瓦爾是一個解決方案,如果你需要在不同的腳本中的數據。

也許你有問題,運行的地方,你不允許改變環境等系統的腳本。

2

有點偏離主題,與環境變量調用語法bash可以更短,無需export的:

USER='john' FIRST_NAME='John' LAST_NAME='Doe' EMAIL='[email protected]' setup_git_account.sh 
+0

這是一個很好的答案。環境變量與參數的問題有點基於意見,但如果使用環境變量,這是調用腳本的正確方法。 – chepner

0

我使用guide我寫了一段時間後,甚至加入--help參數的變量。

該解決方案接受環境變量以及選項(這將勝過變量):

while getopts e:f:hl:u:-: arg; do 
    case "$arg" in 
    e) EMAIL="$OPTARG" ;; 
    f) FIRST_NAME="$OPTARG" ;; 
    h) do_help ;; 
    l) LAST_NAME="$OPTARG" ;; 
    u) USER_NAME="$OPTARG" ;; 
    -) LONG_OPTARG="${OPTARG#*=}" 
     case $OPTARG in 
      email=?*) EMAIL="$LONG_OPTARG" ;; 
      first*=?*) FIRST_NAME="$LONG_OPTARG" ;; 
      help*)  do_help ;; 
      last*=?*) LAST_NAME="$LONG_OPTARG" ;; 
      user=?*) USER_NAME="$LONG_OPTARG" ;; 
      *) echo "Illegal option/missing argument: --$OPTARG" >&2; exit 2 ;; 
     esac ;; 
    *) exit 2 ;; # error messages for short options already given by getopts 
    esac 
done 
shift $((OPTIND-1)) 

HELP=" - see ${0##*/} --help" 
: ${USER_NAME?"Requires USER_NAME$HELP"} 
: ${FIRST_NAME?"Requires FIRST_NAME$HELP"} 
: ${LAST_NAME?"Requires LAST_NAME$HELP"} 
: ${EMAIL?"Requires EMAIL$HELP"} 

su - "$USER_NAME" -c "git config --global user.name '$FIRST_NAME $LAST_NAME'" 
su - "$USER_NAME" -c "git config --global user.email '$EMAIL'" 

注意,我改變$USER$USER_NAME避免與當地環境中的衝突($USER用戶名!

FULL_NAME="$(getent passwd |awk -v u="$USER_NAME" -F: '$1 == u { print $5 }')" 
:本地Linux系統上)

您也可以從系統中提取用戶的全名

(我沒有理由分開FIRST_NAME和LAST_NAME;你對Jean Claude Van Damme做什麼?無論如何,它們只能一起使用。另請注意,並非所有用戶都將在密碼文件中擁有全名。)

這使用do_help來顯示--help輸出。下面是一個例子,它看起來如何(我把它放在腳本的不同頂部,所以有人剛剛閱讀它可以得到大綱;它不在上面的代碼塊中,因爲我想阻止塊得到滾動條):

do_help() { cat <</help 
Usage: ${0##*/} [OPTIONS] 
    -u USER_NAME, --user=USER_NAME 
    -f FIRST_NAME, --firstname=FIRST_NAME 
    -l LAST_NAME, --lastname=LAST_NAME 
    -e EMAIL,  --email=EMAIL 
Each option may also be passed through the environment as e.g. $EMAIL 

Code taken from https://stackoverflow.com/a/41515444/519360 
/help 
} 
相關問題