繁体   English   中英

使用 shell 脚本遍历 $PATH 变量

[英]Iterate over $PATH variable using shell script

如果我在终端中输入echo $PATH ,我会得到以下结果:

/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/fnorbert/.local/bin:/home/fnorbert/bin

我想使用 shell 脚本遍历这些路径,但我不知道该怎么做。
我尝试了以下方法:

for i in 1 2 3  
do
    echo $PATH | cut -d':' -f$i
done

这将打印前三个路径,但如果可能的话,我想用变量i表示每个路径。

您可以使用分隔符设置为read :

while read -d ':' p; do
   echo "$p"
done <<< "$PATH:"

最简单的方法可能是将IFS更改为冒号并让单词拆分来完成:

IFS=:
for p in $PATH ; do 
    echo "$p"
done

但这可能会触发文件名 globbing,在奇怪的情况下,您的PATH包含像*?[]这样的字符。 您需要使用set -f来避免这种情况。

尽管无论如何更改IFS可能会被认为是有问题的,因为它会影响脚本的其余部分。 因此,在 Bash 中,我们可以使用read -a将路径拆分为数组,这对于 glob 字符也没有问题:

IFS=: read -a paths <<< "$PATH"
for p in "${paths[@]}" ; do
    echo "$p"
done

带回声:

echo "${PATH//:/$'\n'}"

sed:

sed 's/:/\n/g' <<< "$PATH"

时间:

tr ':' '\n' <<< "$PATH"

蟒蛇:

python -c "import os; print os.environ['PATH'].replace(':', '\n')"

迭代用于:

for i in ${PATH//:/ }; do echo $i; done

这是一个微不足道的解决方案,可以稍微扩展您的尝试

for i in $( echo "$PATH" | cut -d: -f 1- --output-delimiter=" " ) ; 
do 
   echo "$i" ; 
done

这里使用的一种技巧是-f 1-指定所有字段而不是一个字段。

另一个技巧是使用--output-delimiter选项。

此解决方案对目录名称中的特殊字符敏感。

考虑下面的例子

PATH="help me":\*:now
for i in $( echo "$PATH" | cut -d: -f 1- --output-delimiter=" " ) ; 
do 
   echo "$i" ; 
done

这将输出

help
me
foo
now

也就是说,

  • 目录名称中的空格将不会被正确处理
  • 特殊字符,例如*将被 shell 扩展为当前目录中的文件列表( foo是驻留在当前目录中的文件名)

但是,如果您的PATH不包含任何特殊内容,这将起作用。 否则,或者更确切地说,在所有情况下都采用使用read解决方案

您可以使用 awk 来满足要求,

echo $PATH | awk -F: '{ for (i=1; i<=NF; i++) {print $i}}'

这在性能上非常有效。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM