-
-
Save githubhjs/56c97d7107715314fb85abfff9870fec to your computer and use it in GitHub Desktop.
| #!/bin/zsh | |
| # | |
| # Function: Removes duplicate, colon-separated entries from a specified | |
| # environment variable. | |
| # Usage: dedup_env_var <VARIABLE_NAME> | |
| # Example: dedup_env_var PATH | |
| # | |
| dedup_env_var () { | |
| # Store the first argument (the environment variable's name) in a local variable. | |
| local var_name="$1" | |
| # Check if the target environment variable is unset or empty. | |
| # (P)var_name is Zsh's parameter indirection, which gets the value of the | |
| # variable whose name is stored in the var_name variable. | |
| if [ -z "${(P)var_name}" ]; then | |
| # Print the error message to standard error (stderr). | |
| echo "Error: Environment variable '$var_name' is not set." >&2 | |
| return 1 | |
| fi | |
| # Declare a local (-a for array) array with unique (-U) elements. | |
| # This is a more explicit way of writing 'typeset -U array'. | |
| local -aU array | |
| # This is the updated, robust line: | |
| # 1. `${(P)var_name}`: Gets the content of the environment variable (e.g., the value of $PATH). | |
| # 2. `(@s/:/)`: Splits the string by colons. The `@` flag ensures proper array | |
| # treatment and preserves empty fields. | |
| # 3. `("...")`: The outer double quotes prevent word splitting, ensuring that | |
| # paths with spaces are treated as a single, complete element. | |
| # 4. Because 'array' was declared as unique (-U), duplicates are automatically | |
| # removed during this assignment. | |
| array=("${(@s/:/)${(P)var_name}}") | |
| # `(j/:/)` joins the array elements back into a single string, separated by colons. | |
| # Finally, export the cleaned-up string, overwriting the original environment variable. | |
| export "$var_name"="${(j/:/)array}" | |
| } |
Of course. Here is an explanation of the Zsh function in English.
This Zsh function, dedup_env_var, is designed to remove duplicate entries from a colon-separated environment variable, such as $PATH.
It's a useful utility for cleaning up variables that may have accumulated redundant paths after sourcing multiple configuration files.
Line-by-Line Code Analysis
Here is a breakdown of what each line in the function does:
Bash
dedup_env_var () {
# Declares a local variable 'var_name' and assigns it the value of the
# first argument passed to the function.
# For example, if you run dedup_env_var PATH, then $var_name becomes "PATH".
local var_name="$1"
# Declares a local array variable named 'array'.
local array
# This 'if' block checks if the target environment variable is empty or not set.
# `${(P)var_name}` is a Zsh-specific feature called "parameter indirection".
# It takes the value of var_name (e.g., "PATH") and uses it as the name of
# another variable to expand (effectively becoming $PATH).
# `[ -z "..." ]` tests if the resulting string is empty.
if [ -z "${(P)var_name}" ]
then
# If the variable is empty, it prints an error and exits with a non-zero status.
echo "Environment variable '$var_name' is not set."
return 1
fi
# This is the core of the de-duplication logic.
# `typeset -U array` declares 'array' as an array that holds only unique elements.
# Any duplicate values assigned to it will be automatically discarded.
typeset -U array
# This line populates the array.
# 1. `(P)var_name`: Gets the value of the environment variable (e.g., the content of $PATH).
# 2. `(s/:/)`: This is a Zsh expansion flag that splits the string by a delimiter,
# in this case, the colon ':', creating an array of paths.
# 3. `array=(...)`: The resulting array of paths is assigned to the `array` variable.
# Because `array` was declared as unique (`-U`), this step automatically removes all duplicates.
array=(${(s/:/)Pvar_name})
# This line rebuilds the environment variable from the cleaned-up array.
# 1. `${(j/:/)array}`: This joins the elements of the `array` back into a single
# string, using a colon ':' as the separator between them.
# 2. `export "$var_name"=...`: Using parameter indirection again, it assigns the
# newly joined, de-duplicated string back to the original environment variable
# (e.g., `PATH=...`) and exports it, making it available to subprocesses.
export "$var_name"="${(j/:/)array}"
}
Explanation of the Commands in the Screenshot
which dedup_env_var: The user runs which to find the location of the dedup_env_var command. Since it is a shell function and not an executable file in the system's PATH, the shell responds by printing the function's source code.
dedup_env_var PATH: The user then calls the function, passing PATH as the argument. This triggers the function to:
Read the current value of the $PATH environment variable.
Split it into an array, removing any duplicate path entries in the process.
Join the unique paths back together into a single, colon-delimited string.
Export the cleaned-up string as the new value for the $PATH variable.
Summary
In essence, dedup_env_var is an elegant and efficient Zsh script that leverages Zsh's advanced parameter expansion and unique array features to clean up environment variables.
好的,這張圖片展示了一個名為 dedup_env_var 的 Zsh function 以及它的使用範例。
這個 function 的主要功能是移除指定環境變數中,以冒號 (:) 分隔的路徑/值中的重複項目。
這對於清理像 $PATH 或 $LD_LIBRARY_PATH 這樣可能因多次 source 設定檔而累積了重複路徑的環境變數非常有用。
功能逐行分析
讓我們來逐行解析這個 function 的程式碼:
Bash
dedup_env_var () {
# 宣告一個名為 var_name 的本地變數,其值為傳入 function 的第一個參數。
# 例如,如果執行 dedup_env_var PATH,那麼 var_name 的值就是 "PATH"。
local var_name="$1"
}
圖片中的指令流程
which dedup_env_var: 使用者執行 which 指令來查看 dedup_env_var 這個指令的定義。因為它是一個 shell function,所以 shell 直接印出了它的原始碼。
dedup_env_var PATH: 使用者呼叫了這個 function,並傳入 PATH 作為參數。
function 內部會讀取當前的 $PATH 環境變數。
將 $PATH 的值(例如 /usr/local/bin:/usr/bin:/bin:/usr/local/bin)按冒號分割。
利用 typeset -U 的特性,移除重複的項目(/usr/local/bin)。
將處理後不重複的路徑重新用冒號組合成一個新字串(/usr/local/bin:/usr/bin:/bin)。
最後,將這個乾淨的字串重新 export 成新的 $PATH 環境變數。
總結
總而言之,dedup_env_var 是一個非常實用的 Zsh 工具函式,它利用了 Zsh 強大的參數擴展 (Parameter Expansion) 和陣列特性,以一種高效且簡潔的方式來清理和整理環境變數中重複的路徑。