Terminal

使用 ldapsearch 的參數創建 zsh 函式

  • June 9, 2022

我有幾個命令可以直接在命令行上毫無問題地執行,當我執行它們並替換$1為我想在 LDAP 中檢查的實際組名時。現在我想把它變成一個參數化的函式,我不能得到錯誤資訊或回顯來列印任何東西。

如何將下面的程式碼轉換為可以在 zsh 中呼叫的函式,方法是在命令行中將其添加到我的 .zshrc 中?(為公開發布略有調整)

alias ldapuserlookup=" /usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b 'ou=Groups,o=.com' '(cn=$1)' memberuid | sed 's/memberuid: //g')"

預期輸出:

username1
username2
username3

這必須被問過一百萬次,但我只是不知道將哪些關鍵字放入搜尋中,這會給我一個有用的例子。這麼多是為了 bash,或者不與我正在做的任何事情一起工作。

您可以向下滾動到最後找到解決方案,但是因為了解實際發生的情況很重要,所以這裡是完整的細分。

答案是三方面的:

1.您提供的命令包含錯誤:參數)末尾有一個額外的,sed導致以下錯誤輸出:

zsh: parse error near `)' 

(我猜這可能是嘗試使用$(...)語法時遺留下來的)



2. 您正在使用別名來執行預期對使用者提供的參數進行操作的命令。在這種情況下,您想改用函式。

別名本質上只是 shell 幫助程序,它們的預期目的是命令名稱的字元串替換,通常帶有附加的選項標誌,例如:alias ll='ls -al'alias grep='grep --color=auto'”。此外,別名有多個警告可以很容易地破壞命令行為,但這些超出了特定的回答這個問題。

在您的特定情況下,您希望使用一個函式,因為這些函式既可以接受命令參數,也可以根據需要解析它們。它們是兩全其美的,因為它們以類似於別名的方式執行——它們可以在全域以及在一個特定終端內動態初始化——但也具有真實腳本的多功能性,但不需要創建腳本文件的額外麻煩。

為了將別名重新格式化為函式,您可以像這樣聲明它(注意:這還不是完整的解決方案):

ldap_userlookup(){
# It is standard practice to use '_' as separator function names 
/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b 'ou=Groups,o=.com' '(cn=$1)' memberuid | sed 's/memberuid: //g'
}

**注意:**在命令前添加是檢查shellecho如何解析該特定命令的好方法。也可以set -x用於完整的調試輸出,但這可能非常冗長。

使用以下兩個帶前綴的聲明echo 將說明解析所提供參數的差異:

alias testalias='echo  "/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=$1) memberuid " '
test_func(){
  echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=$1) memberuid " }
  • **壞:**使用聲明的別名並執行testalias argtest我們獲得:
/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=) memberuid  testarg

這顯然不是期望的行為,因為提供的參數被附加在命令的末尾,而不是我們的命令被告知期望它(cn=$1

  • **好:**使用test_func argtest我們得到的函式:
/usr/bin/ldapsearch -LLL -x -h ldap.com -s sub -b ou=Groups,o=.com (cn=testarg) memberuid

**如您所見,我們聲明的函式能夠解析我們的命令行參數argtest,然後將其放置在我們命令中正確的所需位置,即作為cn=**的參數



3.您使用'了變數參數,並且兩者都bash遵守zsh規則,其中包含的變數'不會擴展,但包含在裡面的變數"會。

以下是您的命令(為清楚起見再次刪除管道) - 即使放置在函式內部 - 將如何根據使用的變數外殼進行解析:

  • '在函式內部的變數周圍使用單引號
test_func(){
   echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com'"  '(cn=$1)' memberuid 
}

執行test_func argtest

輸出不良

/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com' (cn=$1) memberuid

  • 改用雙引號重新格式化函式"(保留舊的不需要的'引號,以顯示 "將覆蓋它們)
test_func(){
   echo "/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com'"  "'(cn=$1)'" memberuid
}

執行test_func argtest

良好的輸出:

/usr/bin/ldapsearch -LLL -x -h ldap.com -s su -b 'ou=Groups,o=.com' '(cn=argtest)' memberuid


完整解決方案:

應該為您提供所需行為的完整函式聲明(echo已刪除、sed附加管道、使用雙引號)是:

ldap_userlookup () {
      /usr/bin/ldapsearch -LLL -x -h "ldap.com" -s "sub" -b "ou=Groups,o=.com" "(cn=$1)" memberuid | sed 's/memberuid://g'
}

一旦你測試它並且它可以工作,你可以將它附加到你的 main~/.zshrc中,它將被載入到每個zsh終端視窗中,或者你可以創建一個單獨的~/.zsh_functions文件,將這個和其他自定義函式定義放入其中,然後用於source ~/.zsh_functions載入它們根據需要進入你的外殼。

引用自:https://unix.stackexchange.com/questions/705484