通常在环境变量中有目录列表,用:
(like$PATH
和$LD_LIBRARY_PATH
许多其他) 分隔。
是否有任何工具或标准方法可以为列表中的每个目录应用命令?
就我而言,我需要检查它们是否存在,但许多其他命令也很有用,所以我正在寻找一种方法来轻松地迭代这些列表。
通常在环境变量中有目录列表,用:
(like$PATH
和$LD_LIBRARY_PATH
许多其他) 分隔。
是否有任何工具或标准方法可以为列表中的每个目录应用命令?
就我而言,我需要检查它们是否存在,但许多其他命令也很有用,所以我正在寻找一种方法来轻松地迭代这些列表。
在 bash 中执行此操作的正确方法是将其分隔为数组:
IFS=: read -ra PATHS <<< "$PATH"
for P in "${PATHS[@]}"; do
echo "$P"
done
使用这种形式会使循环内的任何变量赋值丢失:
echo "$PATH" | tr : '\n' | while read P; do
ALL=$ALL:$P
done
echo "$ALL" # => empty string
另一种更好的方法是通过:
while read P; do
ALL=$ALL:$P
done <<< "${PATH//:/$'\n'}"
而从 Bash 3.1 开始,ALL=$ALL:$P
可以进一步简化为ALL+=$P
.
那么我会做的最快的事情是
echo $PATH | tr : '\n' | while read dir; do
ls "$dir" > /dev/null
done
对于任何不存在(或不可读)的组件,您都会收到错误消息。这可能不是防弹的。
你可以这样做:
$ echo $PATH | tr : ' ' | xargs -n1 ls -d
/usr/local/bin
/usr/bin
/bin
/usr/local/sbin
/usr/sbin
/usr/local/sbin
/usr/sbin
ls: cannot access /a/b/c: No such file or directory
对于不存在的目录:
$ echo $PATH | tr : ' ' | xargs -n1 ls -d > /dev/null
ls: cannot access /a/b/c: No such file or directory
您还可以利用位置参数:
IFS=:
set -- $PATH
for dir in "$@"; do
: do something with "$dir"
done
for 循环也可以更简洁地编写来循环位置参数:
for dir; do ...
根据您在脚本中执行的其他操作,您可能希望在覆盖当前 IFS 之前保存它:
oldIFS=$IFS
IFS=:
# ...