3

I want to use bash instead of sh when I use the open function. For instance:

sub run_cmd {
    my ($cmd) = @_;
    my $fcmd;

    print("Run $cmd\n");

    open($fcmd, "$cmd |");
    while ( my $line = <$fcmd> ) {
        print "-> $line";
    }
    close $fcmd;
}

eval{run_cmd('ps -p $$')};

Here, the output is:

Run ps -p $$
->    PID TTY          TIME CMD
-> 189493 pts/6    00:00:00 sh

We can see sh is used by default.

I have some constraints and I need (1) to use the open function and (2) to call bash instead of sh. I tried simply to add bash at the beginning of my command but it doesn't work:

Run ps -p $$
/bin/ps: /bin/ps: cannot execute binary file

What can I do to use bash with the open function?

zdim
  • 64,580
  • 5
  • 52
  • 81
Pierre
  • 1,942
  • 3
  • 23
  • 43
  • A related question that may help you: [Which shell does a Perl system() call use?](https://stackoverflow.com/q/4225102/7939871) – Léa Gris Oct 09 '20 at 11:00
  • @Pierre : Aside from the correct answer given by tripleee, the error you see comes probably from an incorrect setting of the `PATH` environment variable. I suggest that, for testing, you print its value before running the command. – user1934428 Oct 09 '20 at 11:06
  • @user1934428 No, putting `bash` immediately in front will simply cause `bash` to try to execute `ps` as a script file. – tripleee Oct 09 '20 at 15:14
  • @tripleee - Right, I should have read the error message properly. Or course the `-c` is missing. – user1934428 Oct 11 '20 at 07:40

2 Answers2

5

You can explicitly run bash instead.

open($fcd, "bash -c '$cmd' |");

The other answer indeed shows some important best practices for when cmd is not completely trivial, or not under your control.

tripleee
  • 175,061
  • 34
  • 275
  • 318
  • That will still call `sh -c` to run the `bash -c` (because of the single quotes). –  Oct 09 '20 at 15:10
4

Don't take your chances with quote injections:

open my $fcmd, '-|', qw(bash -c), $cmd;

(Also notice that you don't need to close $fcmd explicitly if you declared it with my; it will be automatically closed at the end of the block; perl is not java ;-))