循环遍历Bash中的pathvariables的元素

我想通过echo $VARIABLE命令获得的path列表进行循环。

例如:

echo $MANPATH将会返回

/usr/lib:/usr/sfw/lib:/usr/info

这是三条不同的path,每条path都以冒号分隔。 我想循环每个path。 有没有办法做到这一点? 谢谢。

感谢所有答复到目前为止,看起来我实际上不需要循环。 我只需要一个方法来取出冒号,这样我就可以在这三条path上运行一个ls命令。

你可以使用Bash的模式替换参数扩展来填充你的循环变量。 例如:

 MANPATH=/usr/lib:/usr/sfw/lib:/usr/info # Replace colons with spaces to create list. for path in ${MANPATH//:/ }; do echo "$path" done 

注意:不要将替换扩展放在引号中。 您希望来自MANPATH的扩展值被for循环解释为单独的单词,而不是单个字符串。

您可以设置内部字段分隔符:

 ( IFS=: for p in $MANPATH; do echo "$p" done ) 

我使用了一个子shell,所以IFS的变化并没有反映在我当前的shell中。

在Bash中这样做的规范方法是适当地使用内置read

 IFS=: read -r -d '' -a path_array < <(printf '%s:\0' "$MANPATH") 

这是唯一可靠的解决方案:将完成你想要的:在分隔符上拆分字符串:并且相对于空格,换行符和全角字符(如*[ ]等)是安全的(不同于其他答案:它们是全部坏了)。

在这个命令之后,你将有一个数组path_array ,你可以循环它:

 for p in "${path_array[@]}"; do printf '%s\n' "$p" done 

通过这种方式,您可以安全地通过$PATH循环,而$IFS将在循环内部或外部保持不变。

 while IFS=: read -d: -r path; do # `$IFS` is only set for the `read` command echo $path done <<< "${PATH:+"${PATH}:"}" # append an extra ':' if `$PATH` is set 

你可以检查$IFS的值,

 IFS='xxxxxxxx' while IFS=: read -d: -r path; do echo "${IFS}${path}" done <<< "${PATH:+"${PATH}:"}" 

和输出将是这样的事情。

 xxxxxxxx/usr/local/bin xxxxxxxx/usr/bin xxxxxxxx/bin 

参考StackExchange上的另一个问题 。

你可以在$ {}中使用Bash的X来实现这个功能:

 for p in ${PATH//:/$'\n'} ; do echo $p; done 
 IFS=: arr=(${MANPATH}) for path in "${arr[@]}" ; do # <- quotes required echo $path done 

…它确实照顾空间:o)但是如果你有这样的东西,也会添加空的元素:

 :/usr/bin::/usr/lib: 

…那么索引0,2将是空的(''),不能说为什么索引4没有设置

 for p in $(echo $MANPATH | tr ":" " ") ;do echo $p done