用于遍历 $PATH 文件夹并查看系统上可用的可执行文件的脚本

用于遍历 $PATH 文件夹并查看系统上可用的可执行文件的脚本

这是我到目前为止所拥有的:

#!/bin/bash

for file in $PATH ; do # Scanning files in $PATH

        if [ -x ] ; then #Check if executable
                echo "Executable File"
        else
                echo "Not executable"
        fi
done

输出是“文件可执行”

我认为它没有正确循环所有文件夹

答案1

如果您想要的是可执行文件的列表,find就足够了:

IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')'

这将列出完整路径您的$PATH.确保在冒号 ( )IFS=':'$PATH分割:,冒号是该变量的分隔符。

如果你不想要完整路径,但只是可执行文件名称,你可能会做

IFS=':'
find $PATH -type f '(' -perm -u+x -o -perm -g+x -o -perm -o+x ')' -exec basename {} \; | sort

如果你的系统find是 GNU 兼容的,那么条件就简化了很多:

IFS=':'
find $PATH -type f -executable -exec basename {} \; | sort

正如@StephenHarris 指出的那样,这存在一些问题:如果您的 存在子目录$PATH,则即使$PATH无法访问这些子目录中的文件,也可能会报告它们。为了解决这个问题,你实际上会需要具有find比 POSIX 要求更多的选项。 GNU 兼容的可以通过以下方式解决这个问题:

IFS=':'
find $PATH -maxdepth 1 -type f -executable -exec basename {} \; | sort

告诉-maxdepth 1不要find进入任何这些子目录。

答案2

一方面,$PATH给出目录列表。如果您想检查 中的每个文件$PATH,则需要查看每个目录中的每个文件,而不仅仅是检查 中的每个项目$PATH

接下来,您将用来-x查看该文件是否可执行,但您没有指定要检查哪个文件。我写了一个修改后的版本如下:

IFS=':'
for directory in $PATH; do
    for file in $directory/*; do
        if [ -x $file ]; then
            echo "Executable File: " $file
        else
            echo "Not executable: " $file
        fi
    done
done

福克斯的答案是一个更好的解决方案,但我只是认为你会对你的问题感兴趣。

答案3

特别是对于 bash,您也许可以利用compgen内置的:

  • compgen -cTab列出所有可用的命令、内置命令、函数、别名等(基本上是在空提示符下按下时可以显示的所有内容)。
  • compgen -b列出所有内置函数,类似的d目录、f文件、a别名等。

compgen所以你可以使用和 滥用的输出which

$ compgen -c | xargs which -a
/bin/egrep
/bin/fgrep
/bin/grep
/bin/ls
/bin/ping
/usr/bin/time
/usr/bin/[
/bin/echo
/bin/false
/bin/kill

compgen在我的例子中,前五个实际上是别名遮蔽命令,然后我们有关键字和内置命令,因此的输出似乎有一些顺序。

答案4

IFS=:; set -f;
find -- $PATH -type d -prune -exec sh -c '
cd "$1" && \
find . -type d ! -name . -prune \
           -o \
-type f \( -perm -u+x -o -perm -g+x -o -perm -o+x \) -exec echo Executable File: \{\} \; \
           -o \
-type f  ! -perm -u+x  ! -perm -g+x  ! -perm -o+x    -exec echo Not executable: \{\} \;
' {} {} \;

IFS 设置为冒号,PATH 分隔符和 glob 匹配也被禁止,以防止对 PATH 中找到的名称中的 glob 字符进行任何拆分。

然后 $PATH 被分割并在find任何选项到达之前作为主要参数呈现。我们只从目录中选择那些参数。 (如果我们也想要链接到 dir,则给出 -L 选项)。然后我们只需深入到这些目录的第一层并获取可由某人(即用户/组/其他)可执行的文件

相关内容