Skip to content
Advertisement

Redirect STDERR to a file from Perl in Linux

So, I was trying to catch the error messages from running some basic Linux command, using Perl. For example, I try to catch the STDERR when running the ldd command:

JavaScript

But, even if the output of the ldd command does contain error messages such as ldd: warning: you do not have execution permission for, it won’t print them in to the $stderr_file, and I wonder why.

Then I tried to run the command myself: ldd /some/path/to/file 2>./error.log and it failed with: ldd: ./2: No such file or directory.

I suspect that the reason is due to the fact my Linux uses Tcsh because if I switch to Bash, the command works.

How should I approach this issue and solve it?

Also, I read some previous thread but didn’t find any related thread or method to solve it.

Advertisement

Answer

When interpolating strings into shell commands that are intended to be single arguments, you should always use String::ShellQuote to avoid bugs where the shell parses unintended metacharacters in your strings (including space characters). It only implements bourne shell quoting though, so it may not be compatible with tcsh either – but Perl is usually configured to use /bin/sh, which should be bourne shell compatible.

JavaScript

As an alternative, you can avoid the shell entirely by using the list form of system() and redirecting STDERR within Perl. Capture::Tiny makes this easy.

JavaScript

(Path::Tiny is just an example, you can also use File::Slurper or open the file and write to it yourself with appropriate error checking.)

The core module IPC::Open3 can also be used to capture STDERR separately and avoid the shell, somewhat more manually.

JavaScript

This can run into deadlocks if the process outputs a sufficient amount to STDERR. I highly recommend making use of Capture::Tiny instead as above, or IPC::Run or IPC::Run3 for more flexibility.

User contributions licensed under: CC BY-SA
9 People found this is helpful
Advertisement