例如,我想在属于系统 $PATH 的所有目录中查找引用特定二进制文件的所有符号链接。这可以通过手动指定所有目录来成功实现:
sudo find ~/bin /home/samokat/.local/bin /home/samokat/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin -lname /opt/openoffice4/program/soffice
但是当我尝试使用带有 $PATH 扩展的命令时:
sudo find `echo $PATH | tr ':' ' '` -lname /opt/openoffice4/program/soffice
我得到错误和结果:
find: ‘~/bin’: No such file or directory
/usr/bin/soffice.link-to-openoffice-bak
echo $PATH | tr ':' ' '
输出正确路径:
~/bin /home/samokat/.local/bin /home/samokat/bin /usr/local/sbin /usr/local/bin /usr/sbin /usr/bin /sbin /bin /snap/bin
以下也不起作用:
sudo find `echo $PATH | tr ':' ' ' | xargs` -lname /opt/openoffice4/program/soffice
sudo find { `echo $PATH | tr ':' ' ' | xargs` } -lname /opt/openoffice4/program/soffice
sudo find eval "echo $PATH | tr ':' ' ' | xargs" -lname /opt/openoffice4/program/soffice
echo $PATH | tr ':' ' ' | xargs | sudo find -lname /opt/openoffice4/program/soffice # runs some long computation
如何将starting point
目录作为可计算参数传递给find
?这可能吗?
答案1
无需使用sudo
,因为您$PATH
必须包含您已经可以访问的目录。
该字符是Shell 和其他 shell 的~
主目录的内置快捷方式。bash
但它的评估还不够晚,您无法在示例中使用它。 (它也不会在带引号的表达式中求值。)
当您设置时$PATH
,不要使用类似的东西,而是PATH=~/bin:$PATH
考虑使用更明确的替代方案PATH="$HOME/bin:$PATH"
。
对于某些代码,这里有一个可以处理$PATH
目录名称中空格的替代解决方案:
( IFS=:; for p in $PATH; do [ -d "$p" ] && find "$p" -maxdepth 1 -lname '/opt/openoffice4/program/soffice'; done )
更具可读性,
(
IFS=:
for p in $PATH
do
[ -d "$p" ] && find "$p" -maxdepth 1 -lname '/opt/openoffice4/program/soffice'
done
)
答案2
您$PATH
确实包含~/bin
字面意思,因此它只会在当前工作目录中bin
名为字面意思的目录的子目录中找到可执行文件~
,就像您运行mkdir -p '~/bin'
.
那~/bin
是假的,应该被删除。
如果你运行:
PATH=~/bin:$PATH
如果~
没有引用,那么您会发现printf '%s\n' "$PATH"
输出:
/home/you/bin:~/bin:/home/samokat/.local/bin:/home/samokat/bin:...
这~/bin
将被正确地扩展到bin
您的主目录中,然后是~/bin
已经存在的虚假文件和您的PATH
.
但假设you
实际上是samokat
,这意味着该目录将出现两次,$PATH
其中之一是多余的。
将$PATH
,修复到 的find
所有目录组件中的文件后$PATH
,您需要的一切bash
(IFS=:; set -o noglob; find -H $PATH -lname /opt/openoffice4/program/soffice)
特殊参数$IFS
决定如何拆分未加引号的参数扩展。默认情况下,$IFS
包含空格字符(以及换行符和制表符),这解释了为什么将 s 更改:
为有效,但最好设置
IFS
为正确的值。另请注意set -o noglob
禁用其他不加引号的参数扩展的副作用。
另请注意,-H
如果没有它,find
则不会查看实际上是目录符号链接的目录。
或者,如果您可以切换到与数组绑定的zsh
位置(如 中),那么它只是:$PATH
$path
csh
find -H $path -lname /opt/openoffice4/program/soffice
在 中zsh
,您还可以使用 glob 代替find
.
例如:
print -rC1 -- $^path/*(N@e['[[ $REPLY:P = /opt/openoffice4/program/soffice ]]'])
将print
r
aw on olumn 实际ath为 的每个组件内的1
C
符号链接 () 的路径。@
$path
P
/opt/openoffice4/program/soffice