这是我到目前为止所拥有的:
#!/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 -c
Tab列出所有可用的命令、内置命令、函数、别名等(基本上是在空提示符下按下时可以显示的所有内容)。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 选项)。然后我们只需深入到这些目录的第一层并获取可由某人(即用户/组/其他)可执行的文件