1

通常在环境变量中有目录列表,用:(like$PATH$LD_LIBRARY_PATH许多其他) 分隔。

是否有任何工具或标准方法可以为列表中的每个目录应用命令?

就我而言,我需要检查它们是否存在,但许多其他命令也很有用,所以我正在寻找一种方法来轻松地迭代这些列表。

4

4 回答 4

4

在 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.

于 2013-09-26T18:50:44.333 回答
2

那么我会做的最快的事情是

echo $PATH | tr : '\n' | while read dir; do
  ls "$dir" > /dev/null
done

对于任何不存在(或不可读)的组件,您都会收到错误消息。这可能不是防弹的。

于 2013-09-26T18:39:18.607 回答
1

你可以这样做:

$ 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
于 2013-09-26T18:41:40.730 回答
0

您还可以利用位置参数:

IFS=:
set -- $PATH
for dir in "$@"; do
    : do something with "$dir"
done

for 循环也可以更简洁地编写来循环位置参数:

for dir; do ...

根据您在脚本中执行的其他操作,您可能希望在覆盖当前 IFS 之前保存它:

oldIFS=$IFS
IFS=:
# ...
于 2013-09-26T19:35:55.047 回答