列出$ PATH中的所有二进制文件


Answers:


38

这不是答案,而是显示二进制文件,您可以运行该命令

compgen -c

(假设bash

其他有用的命令

compgen -a # will list all the aliases you could run.
compgen -b # will list all the built-ins you could run.
compgen -k # will list all the keywords you could run.
compgen -A function # will list all the functions you could run.
compgen -A function -abck # will list all the above in one go.

1
很高兴知道此命令,我实际上需要可执行文件才能完成。也许我改用这个命令。
jcubic 2014年

请注意,这还包括内建命令,函数,关键字(例如in{...)和别名。
斯特凡Chazelas

主席先生,我已经更新了..我已经保存在我的草案,在很久以前,我在此网站上发现..
拉胡尔·帕蒂尔

@ jcubic,shell已经完成命令完成了,为什么要手工呢?
vonbrand 2014年

@vonbrand我正在使用javascript / php开发shell,并且正在以非交互模式执行shell。
jcubic 2014年

14

使用zsh:

whence -pm '*'

要么:

print -rl -- $commands

(请注意,对于出现在的多个组件中的命令$PATH,它们将仅列出第一个组件)。

如果您希望这些命令不包含完整路径,并且进行了合理排序:

print -rl -- ${(ko)commands}

(也就是说,获取该关联数组的键而不是值)。


我没有提到我正在使用bash。
jcubic 2014年

5

在任何POSIX Shell中,除了最后的排序外,不使用任何外部命令(假定printf是内置的,如果不退回echo),并假定没有可执行文件名称包含换行符:

{ set -f; IFS=:; for d in $PATH; do set +f; [ -n "$d" ] || d=.; for f in "$d"/.[!.]* "$d"/..?* "$d"/*; do [ -f "$f" ] && [ -x "$f" ] && printf '%s\n' "${x##*/}"; done; done; } | sort

如果您没有$PATH(使用.)空组件,也没有以开头的组件-,也没有\[?*PATH组件或可执行文件名称中的通配符,也没有以开头的可执行文件.,则可以简化为:

{ IFS=:; for d in $PATH; do for f in $d/*; do [ -f $f ] && [ -x $f ] && echo ${x##*/}; done; done; } | sort

使用POSIX findsed

{ IFS=:; set -f; find -H $PATH -prune -type f -perm -100 -print; } | sed 's!.*/!!' | sort

如果您愿意在路径中列出稀有的非可执行文件或非常规文件,则有一种更简单的方法:

{ IFS=:; ls -H $PATH; } | sort

这会跳过点文件;如果需要它们,请添加-A标志到(ls如果有),或者如果您想坚持使用POSIX:ls -aH $PATH | grep -Fxv -e . -e ..

在bashzsh中有更简单的解决方案。


假定$PATH已设置并且不包含空组件,并且这些组件看起来不像find谓词(或ls选项)。其中一些也将忽略点文件。
斯特凡Chazelas

@StephaneChazelas是的,好的。除了空的组件外,它完全属于“请勿这样做”类别-PATH在您的控制之下。
吉尔(Gilles)'所以

如果空元素是最后一个(通常是),它仍然不起作用。(在sh仿真中yashzshin中除外)。
斯特凡Chazelas

在你find一个。-prune将阻止列出目录。您可能想要-L而不是-H想要包括符号链接(对于可执行文件是常见的)。-perm -100不保证您可以执行该文件(并且可能(不太可能)排除可执行文件)。
斯特凡Chazelas

4

我想出了这个:

IFS=':';for i in $PATH; do test -d "$i" && find "$i" -maxdepth 1 -executable -type f -exec basename {} \;; done

编辑:看来这是唯一的命令,不会在由Apache用户读取bin目录中的某些文件时触发SELinux警报。


5
为什么for呢?IFS=:; find $PATH -maxdepth 1 -executable -type f -printf '%f\n'
manatwork 2014年

@manatwork可以用于不存在的路径吗?
jcubic 2014年

@manatwork不知道您可以这样做。需要阅读有关IFS的更多信息。
jcubic 2014年

3
假定$PATH已设置并且不包含通配符,也不包含空组件。这也假设GNU的实现find
斯特凡Chazelas

2
由于-type f而不是(特定于GNU)-xtype f,这也将省略符号链接。这也不会列出作为$PATH符号链接的组件的内容。
斯特凡Chazelas

3

这个怎么样

find ${PATH//:/ } -maxdepth 1 -executable

字符串替换与Bash一起使用。


3
假定$PATH已设置,不包含通配符或空白字符,不包含空组件。假设GNU也找到了。请注意,这${var//x/y}ksh语法(zsh和bash也支持)。严格来说,这也假定$ PATH组件也不是find谓词。
斯特凡Chazelas

1
这也假定$PATH组件不是符号链接。
斯特凡Chazelas

@StephaneChazelas:谢谢!换句话说,通常情况。

设置IFS=:比执行此替换更健壮。带空格的路径在Windows上并不少见。符号链接相当普遍,但是使用可以轻松解决-H
吉尔斯(Gilles)'“ SO-不要邪恶”

@吉尔斯:当然。但是,对于该问题,我认为没有任何合理的用例,因此不需要防弹的答案。

1

如果您可以在shell中运行python,那么也可以使用以下(非常长)的单行代码:

python -c 'import os;import sys;output = lambda(x) : sys.stdout.write(x + "\n"); paths = os.environ["PATH"].split(":") ; listdir = lambda(p) : os.listdir(p) if os.path.isdir(p) else [ ] ; isfile = lambda(x) : True if os.path.isfile(os.path.join(x[0],x[1])) else False ; isexe = lambda(x) : True if os.access(os.path.join(x[0],x[1]), os.X_OK) else False ; map(output,[ os.path.join(p,f) for p in paths for f in listdir(p) if isfile((p,f)) and isexe((p,f)) ])'

对于我自己来说,这主要是一个有趣的练习,看看是否可以使用一行python代码完成操作而无需诉诸'exec'函数。以更易读的形式并带有一些注释,代码如下所示:

import os
import sys

# This is just to have a function to output something on the screen.
# I'm using python 2.7 in which 'print' is not a function and cannot
# be used in the 'map' function.
output = lambda(x) : sys.stdout.write(x + "\n")

# Get a list of the components in the PATH environment variable. Will
# abort the program is PATH doesn't exist
paths = os.environ["PATH"].split(":")

# os.listdir raises an error is something is not a path so I'm creating
# a small function that only executes it if 'p' is a directory
listdir = lambda(p) : os.listdir(p) if os.path.isdir(p) else [ ]

# Checks if the path specified by x[0] and x[1] is a file
isfile = lambda(x) : True if os.path.isfile(os.path.join(x[0],x[1])) else False

# Checks if the path specified by x[0] and x[1] has the executable flag set
isexe = lambda(x) : True if os.access(os.path.join(x[0],x[1]), os.X_OK) else False

# Here, I'm using a list comprehension to build a list of all executable files
# in the PATH, and abusing the map function to write every name in the resulting
# list to the screen.
map(output, [ os.path.join(p,f) for p in paths for f in listdir(p) if isfile((p,f)) and isexe((p,f)) ])

0
#!/usr/bin/env python
import os
from os.path import expanduser, isdir, join, pathsep

def list_executables():
    paths = os.environ["PATH"].split(pathsep)
    executables = []
    for path in filter(isdir, paths):
        for file_ in os.listdir(path):
            if os.access(join(path, file_), os.X_OK):
                executables.append(file_)
    return executables
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.