in reply to Re: How to get screenshort using PERL?
in thread How to get screenshort using PERL?

#!/usr/local/bin/perl use strict; use warnings; my $file = '/root/Desktop/'; sleep 5; $file = system("import -window root MyScreenshot.png"); print $file, "\n";

Ouch! That really hurts my eyes!

At least, you use strict and warnings.

use strict; use warnings; system("import -window root MyScreenshot.png");

Better, but still problematic: You still invoke the default shell, begging for trouble. All error checks are missing. Yes, system() may fail. For example, because there is no import utility -- e.g. when ImageMagick is not installed. Or because there is some other tool named import, with completely different parameters a and a completely different purpose.

Alexander

--
Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)

Replies are listed 'Best First'.
Re^3: How to get screenshort using PERL?
by almut (Canon) on Apr 28, 2010 at 15:13 UTC
    You still invoke the default shell

    Actually, this particular example wouldn't invoke a shell, because there are no shell metacharacters in the command.

    $ strace -f -eexecve perl -e 'system("import -window root MyScreenshot +.png")' execve("/usr/local/bin/perl", ["perl", "-e", "system(\"import -window +root MySc"...], [/* 31 vars */]) = 0 Process 20945 attached (waiting for parent) Process 20945 resumed (parent 20944 ready) [pid 20945] execve("/home/almut/bin/import", ["import", "-window", "ro +ot", "MyScreenshot.png"], [/* 31 vars */]) = -1 ENOENT (No such file +or directory) [pid 20945] execve("/usr/local/sbin/import", ["import", "-window", "ro +ot", "MyScreenshot.png"], [/* 31 vars */]) = -1 ENOENT (No such file +or directory) [pid 20945] execve("/usr/local/bin/import", ["import", "-window", "roo +t", "MyScreenshot.png"], [/* 31 vars */]) = -1 ENOENT (No such file o +r directory) [pid 20945] execve("/usr/sbin/import", ["import", "-window", "root", " +MyScreenshot.png"], [/* 31 vars */]) = -1 ENOENT (No such file or dir +ectory) [pid 20945] execve("/usr/bin/import", ["import", "-window", "root", "M +yScreenshot.png"], [/* 31 vars */]) = 0

    As you can see, the import is being run directly.

    (Add a ';' (metacharacter) at the end of the command, and it will run the command via a shell...)

      Actually, this particular example wouldn't invoke a shell ...

      Right. But the next logical step will probably cause both invoking a shell and opening a security hole:

      Depending on the beginners experience, the call may change to system("import -window root $filename") (very naive) or system("import -window root '$filename'") (a little bit of experience, but still wrong).

      With a proper multi-argument system() (i.e. system('import','-window','root','MyScreenshot.png')), it is very unlikely to happen. We may see some cargo cult, like putting the filename in quotes (system('import','-window','root',"$filename")), but that does not cause any problems (except perhaps some wasted CPU cycles).

      And for extra bonus points, the import utility would be called with an absolute path, to avoid the dependancy on $ENV{'PATH'}. That would also save a lot of CPU cycles trying to find import.

      Alexander

      --
      Today I will gladly share my knowledge and experience, for there are no sweeter words than "I told you so". ;-)