简体   繁体   English

使用 shell 脚本遍历 $PATH 变量

[英]Iterate over $PATH variable using shell script

If I type echo $PATH in the terminal I get the following result:如果我在终端中输入echo $PATH ,我会得到以下结果:

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

I want to iterate over these paths using a shell script, but I do not know how to do that.我想使用 shell 脚本遍历这些路径,但我不知道该怎么做。
I tried the following:我尝试了以下方法:

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

This prints the first three paths, but I want to represent every path with the variable i if it is possible.这将打印前三个路径,但如果可能的话,我想用变量i表示每个路径。

You can use read with delimiter set as :您可以使用分隔符设置为read :

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

Simplest way is probably to change IFS to a colon and let the word splitting do it:最简单的方法可能是将IFS更改为冒号并让单词拆分来完成:

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

But that might trigger file name globbing, in the weird case that your PATH contained characters like *?[] .但这可能会触发文件名 globbing,在奇怪的情况下,您的PATH包含像*?[]这样的字符。 You'd need to use set -f to avoid that.您需要使用set -f来避免这种情况。

Though changing IFS might be considered problematic anyway, since it affects the rest of the script.尽管无论如何更改IFS可能会被认为是有问题的,因为它会影响脚本的其余部分。 So in Bash, we could just split the paths to an array with read -a , this doesn't have a problem with glob characters either:因此,在 Bash 中,我们可以使用read -a将路径拆分为数组,这对于 glob 字符也没有问题:

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

with echo:带回声:

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

sed: sed:

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

tr:时间:

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

python:蟒蛇:

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

for iterate use for:迭代用于:

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

Here is a trivial solution, that extends your attempt a little这是一个微不足道的解决方案,可以稍微扩展您的尝试

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

One trick that is used here is -f 1- to specify all fields instead of just one.这里使用的一种技巧是-f 1-指定所有字段而不是一个字段。

Another trick is to use the --output-delimiter option.另一个技巧是使用--output-delimiter选项。

This solution is suffers from sensitivity to special characters in directory names.此解决方案对目录名称中的特殊字符敏感。

Consider the following example考虑下面的例子

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

This would output这将输出

help
me
foo
now

That is,也就是说,

  • spaces in directory names will not be treated correctly目录名称中的空格将不会被正确处理
  • special characters, such as * will be expanded by the shell into a list of files in the current directory ( foo is the name of a file residing in the current directory)特殊字符,例如*将被 shell 扩展为当前目录中的文件列表( foo是驻留在当前目录中的文件名)

But if your PATH does not contain anything special, this would work.但是,如果您的PATH不包含任何特殊内容,这将起作用。 Otherwise or rather in all cases take the solution that uses read .否则,或者更确切地说,在所有情况下都采用使用read解决方案

You can use awk for the requirement,您可以使用 awk 来满足要求,

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

This is well efficient in performance.这在性能上非常有效。

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

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