將大寫變數分配給命令

將大寫變數分配給命令

在嘗試破解目前公司前員工編寫的一些腳本時,在許多腳本中,我遇到了以下語句,這些語句將變數分配給某些命令,如下所示:

CAT=cat
GREP=grep
SED=sed

在腳本的後面,我看到他們使用了這些變數而不是常規命令:

$GREP -v "^#" `dirname $0`/abcdfilename | while read line
do
<some loop operations>
done

我不明白使用這個變數而不是grep直接使用有什麼意義。我的問題是:

  • 以這種方式執行 grep 或 sed (在我們的例子中)有什麼意義嗎?
  • 這是某人試圖編寫腳本以使其他人更難以理解的結果嗎?
  • 或者這只是糟糕腳本的一個例子?

答案1

標準命令在系統上有不同的實作。與 Solaris 10 及更早版本一樣,您擁有/bin/sh舊的 Bourne shell 和/usr/xpg4/bin/shPOSIX 相容 shell。或在 OSX 上,呼叫時使用 BSD sed sed,呼叫時使用 GNU sed gsed。您可以選擇要在腳本中使用的實作。

因此,當您使用變數時,更改腳本中的實作會更容易。當您需要 GNU sed 時:

SED=gsed

如果您不使用變量,則必須替換sed腳本中所有出現的 。儘管您可以輕鬆做到這一點,但這被認為是不好的程式設計習慣。

答案2

有一種觀點認為,將整個腳本中重複使用的幾乎所有內容都變成變量,因為這樣您就可以重新定義它一次,並讓它影響腳本的其餘部分。

您可能會說,使用簡單的 sed 搜尋/替換基本上可以完成相同的事情,但許多用戶對搜尋/替換持謹慎態度,因為意外替換您不打算替換的內容並不難。

事實上,我建議對他們現有的版本進行這樣的改進:

GREP=${GREP:-/bin/grep}

這表示 GREP 將被設定為使用者在 shell 中設定的任何內容,或者如果未設置,則設定為 /bin/grep

這樣用戶就可以即時覆蓋「grep」。

$ export GREP=/bin/fgrep
$ ./path/to/script.sh

答案3

這可能是過早優化的一個例子。

該機器有多少種選擇,或者任何機器有用於sed,grep, 和awk?我敢打賭普遍平均值接近 1.0。給定特定機器上的兩個選擇,實現不同導致腳本在 PATH 上找到的版本失敗而與另一個版本一起工作的可能性有多大?如果確實發生這種情況,解決方案更有可能是更改腳本還是路徑?如果改變腳本被證明是答案,那麼找到至少一次呼叫的可能性有多大?grep代替$GREP?此套牌的堆疊不需要任何間接的需要,並且在需要時也可以按預期工作。

我不會對抗這種文化。如果您的商店有一些偏好$GREP或者/usr/bin/grep要不就grep,我可能會一起去相處。否則,KISS:避免間接,直到需要它出現為止。

相關內容