首页 > 解决方案 > 如何在 perl 脚本中使用 find 命令(带 sudo)?

问题描述

我在 pwd 中有这些文件:

$pwd
/home/user/Desktop/perl
$ls
file.txt   foo.c   bar.c

现在,找到命令:

$sudo find / -type f -name foo.c
/home/user/Desktop/perl/foo.c
find: ‘/proc/1764/task/1764/net’: Invalid argument
find: ‘/proc/1764/net’: Invalid argument
/run/live/persistence/sda5/rw/home/user/Desktop/perl/foo.c
/usr/lib/live/mount/persistence/sda5/rw/home/user/Desktop/perl/foo.c

所以匹配的是第一个路径,find找到了什么。现在我想在 perl 脚本中捕获两个文件(foo.c和):bar.c

#!/usr/bin/perl -w

@ar=("foo.c", "bar.c");
@ar2=`sudo find / -type f -name $_ | head -n1` for @ar;
print "$_\n" for @ar2

输出

find: ‘/proc/1764/task/1764/net’: Invalid argument
find: ‘/proc/1764/net’: Invalid argument
find: ‘/proc/29943’: No such file or directory
find: ‘/proc/1764/task/1764/net’: Invalid argument
find: ‘/proc/1764/net’: Invalid argument
find: ‘/proc/30037’: No such file or directory
/home/user/Desktop/perl/bar.c

如您所见,我可以在 perl中使用sudoinside of ?(backticks), but the result will not assign to the array properly (it gets only one of the files from the list, not both) even in list context. So how to properly find files in perl from `root` (and thus must with sudo privileges) via

标签: bashperlfindfilesystems

解决方案


最好的办法是一开始就不掏钱。File::Find::Rule非常适合这样的事情。

use warnings;
use strict;

use File::Find::Rule;

my $search_dir = '/';
my @files = qw (
    foo.c
    bar.c
);
 
my @results = File::Find::Rule->file()
                            ->name(@files)
                            ->in($search_dir);

print "$_\n" for @results;

结果:

$ sudo perl find.pl
/root/foo.c

请注意,如果您在使用 时没有使用系统 perl sudo,则可能必须确保您的sudoers文件具有正确的 perl 路径集。这是我的系统perlbrew在我的主目录中运行 5.26.1 的示例:

Defaults secure_path="/home/steve/perl5/perlbrew/perls/perl-5.26.1/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"

本质上,我只是在现有条目的前面添加了 perl bin 路径secure_path以及一个尾随冒号(使用visudo)。


推荐阅读