1

I want to obtain names of owners of files, that are in specified directory (2 in the loops is just for testing, there are only 2 files in my /media anyways). So, if user's input is "/media", i get the following output:

sh: 2: /kuba: not found sh: 2: /sf_Shared: not found root:kuba 

So it seems, that the script works, but displays "not found" anyways.

my $directory =<STDIN>; #"/media"; my @ls = qx(ls $directory); chomp @ls; my @fow; for(my $i = 0; $i < 2; $i++ ) { $fow[$i] = qx(stat -c '%U' $directory/$ls[$i]); #say $fow[$i]; } chomp @fow; print "$fow[0]:$ls[0]\n"; 

BTW, When I remove user's input and just declare $directory as "/media", it works perfectly fine.

3
  • You must chomp the $directory data. Commented Jun 4, 2021 at 9:22
  • my $directory =<STDIN>; will give you /media\n, without stripping \n your OS will not find the directory. Commented Jun 4, 2021 at 9:37
  • Using chomp() to remove the newline from data read from <STDIN> is, in general, a very good idea. But in this case, it's not necessary as the string (with the newline attached) is passed to qx(ls $directory). And the shell that executes the command doesn't care that there's a newline on the end. Try perl -lE '$dir = ".\n"; say qx(ls $dir)' Commented Jun 6, 2021 at 14:32

3 Answers 3

3

Why do not use perl instructions instead of shell calls which is an expensive on resources?

use strict; use warnings; my $dir = shift || die "Provide a directory name"; my($file, $owner); while( glob("$dir/*") ) { $file = $_; $owner = getpwuid((stat($_))[4]); write; } $~ = 'STDOUT_BOTTOM'; write; exit 0; format STDOUT_TOP = +----------------------------------------------------------+-----------------+ | File | User | +----------------------------------------------------------+-----------------+ . format STDOUT = | @<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< | @<<<<<<<<<<<<<< | $file, $owner . format STDOUT_BOTTOM = +----------------------------------------------------------+-----------------+ . 

Reference: shift, glob, stat, getpwuid, write, format

Sign up to request clarification or add additional context in comments.

11 Comments

Could you add more comments to the code? I've first started using perl yesterday
Do you really want to recommend people use formats in 2021? :-)
@Dave Cross -- did I recommended use formats? I do not recall it, I just used format to show result -- if it exists and does the job then why not to use it. You could post your answer with more modern solution if you inclined in doing so. I still find that for perl newcomers format is very easy to comprehend and does not require deep perl experience.
@DaveCross -- your comment would have more value if you suggested something as a replacement of format, just to prove your point.
|
2

I think the easiest approach is something like this:

#!/usr/bin/perl use strict; use warnings; use feature 'say'; use File::stat; # Default to the current directory if one isn't given on # the command line. # Note: "defined-or" operator so we don't fail on a # directory called "0" my $dir = shift // '.'; # Use \Q...\E around the directory name to make life easier while (my $file = glob("\Q$dir\E/*")) { say $file; # File::stat changes the behaviour of stat() and makes # it far easier to use my $uid = stat($file)->uid; my $user = getpwuid($uid); # Simple output option :-) say "$file / $user"; } 

Comments

2

Use the chomp function to remove trailing newline (\n) from the user input.

my $directory = <STDIN>; #"/media"; chomp($directory); 

3 Comments

Can't modify <HANDLE> in chomp at test.pl line 9, near "<STDIN>)" Execution of test.pl aborted due to compilation errors (#1) (F) You aren't allowed to assign to the item indicated, or otherwise try to change it, such as with an auto-increment. Uncaught exception from user code: Can't modify <HANDLE> in chomp at test.pl line 9, near "<STDIN>)" Execution of test.pl aborted due to compilation errors
@row chomp(my $dir = <STDIN>) works though.
@row: You're right that you usually need to chomp() input in order to remove the newline. But that's not the problem here. As the value of $directory (with its newline attached) is passed to qx(ls $directory), the extra newline is effectively ignored. Try it for yourself - perl -lE '$dir = ".\n"; say qx(ls $dir)'

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.