On Apache 2.2 on CentOS 6.4 with perl 5.10.1.
I'm trying to get a remote directory listing from within a mod_perl script, which apparently (if I die qx(id)
) is running as apache
. But I'm not even getting as far as being able to run ssh
without parameters, just to have it print its help info. So that's what I'm asking how to do in this question--it's not about ssh
not being able to connect.
die qx(which ssh);
dies with:
/usr/bin/ssh
and:
die qx(ls -al /usr/bin/ssh);
dies with:
-rwxr-xr-x. 1 root root 376920 Feb 21 2013 /usr/bin/ssh
Okay, so, it can find it, and see it, and has execute rights on it (which is true for /usr/bin and /usr as well.) But then:
die qx(/usr/bin/ssh); # or just 'ssh'
dies with an empty array, so I tried:
system("ssh") == 0 or die "failed: $! (code $?)"; # or '/usr/bin/ssh'
...which dies with:
No such file or directory (code 65280)
Why is this? How can I get die qx(ssh)
or die qx(/usr/bin/ssh)
to die with the expected value of:
usage: ssh [-1246AaCfgKkMNnqsTtVvXxYy] [-b bind_address] [-c cipher_spec]
[-D [bind_address:]port] [-e escape_char] [-F configfile]
[-i identity_file] [-L [bind_address:]port:host:hostport]
[-l login_name] [-m mac_spec] [-O ctl_cmd] [-o option] [-p port]
[-R [bind_address:]port:host:hostport] [-S ctl_path]
[-W host:port] [-w local_tun[:remote_tun]]
[user@]hostname [command]
Interestingly, from a bash prompt I get this:
$ sudo su apache ssh
This account is currently not available.
So...how can I run ls
from an account that's not available, yet not ssh
? They're both programs, why do they behave differently here?
Update: It's not just ssh
, but I can't figure out the pattern: gawk
, tar
, and ping
also don't work. Yet df
, ls
, dir
, and pwd
all do. But:
$ ls -al /bin/ls
-rwxr-xr-x. 1 root root 109208 May 23 07:00 /bin/ls
$ ls -al /usr/bin/dir
-rwxr-xr-x. 1 root root 109208 May 23 07:00 /usr/bin/dir
$ ls -al /bin/pwd
-rwxr-xr-x. 1 root root 28008 May 23 07:00 /bin/pwd
$ ls -al /bin/df
-rwxr-xr-x. 1 root root 73808 May 23 07:00 /bin/df
$ ls -al /bin/gawk
-rwxr-xr-x. 1 root root 375360 Aug 7 2012 /bin/gawk
$ ls -al /bin/tar
-rwxr-xr-x. 1 root root 390616 Feb 21 2013 /bin/tar
$ ls -al /usr/bin/ssh
-rwxr-xr-x. 1 root root 376920 Feb 21 2013 /usr/bin/ssh
$ ls -al /bin/ping
-rwsr-xr-x. 1 root root 40760 Jun 5 06:39 /bin/ping
So they all have all the 'x' bits set (except ping with its one 's', yet see below its error code), and for example, ssh
and dir
have identical ACLs. So why should ssh
and gawk
fail to give any output but dir
and ls
succeed? (Full paths or no.)
Update: even more perplexingly, /bin/gawk
fails with the same message but code 256, and /bin/tar
and /bin/ping
similarly but code 512.
Update: OK, this part makes sense: If I run the failing binaries from the command line and then run echo $?
immediately after, ssh
gives 255, ping
and tar
give 2, and gawk
gives 1. Those are scaled-down versions of what I get in mod_perl2. So, it seems to be that anything with a return code other than 0 doesn't work. Possibly it's outputting to STDERR, and so STDOUT doesn't capture anything, hence the blank return.
Aha, that's the answer--will post.
If you redirect STDERR to also capture it in your qx, like so:
die qx(ssh 2>&1);
...you'll get the output you get on the command line. So it's not that it's not running, it's just that it doesn't write anything to STDOUT.