1

In Windows 7, running php.exe from C:\wamp64\bin\php\php5.6.25\php.exe, I find that the following prints the PHP usage instructions.

echo 4;|php -r <-- prints php usage instructions

C:\wamp64\bin\php\php5.6.25>echo 4;|php -r
Usage: php [options] [-f] <file> [--] [args...]
   php [options] -r <code> [--] [args...]

However, a friend claims that the same command echo 4;|php -r (or perhaps he means echo '4;'|php -r works for him using Linux.

How can I get this behaviour in windows?

Note I'm aware of php -r used to run some code passed as a parameter following it, i'm asking about it running a file or accepting stdin.

barlop
  • 12,887
  • 8
  • 80
  • 109
  • 1
    What's the point of the `echo 4` part? That seems entirely useless as `php -r` doesn't take any input. – tadman Feb 25 '18 at 19:08
  • 3
    Is there piping in windows? Last time I checked there wasn't.... – man0v Feb 25 '18 at 19:08
  • @man0v There is with PowerShell if you want to go down that road. – tadman Feb 25 '18 at 19:09
  • @tadman I'll refrain for the time being. – man0v Feb 25 '18 at 19:10
  • @tadman he is talking about the default terminal of windows, I can't recall its name. But it doesn't support piping. – Naresh Feb 25 '18 at 19:12
  • @Naresh You wrote "he is talking about the default terminal of windows, I can't recall its name. But it doesn't support piping." <-- what are you talking about.. Windows has such a thing as CMD.EXE which absolutely supports pipes! It's standard usage! – barlop Feb 25 '18 at 19:12
  • @Naresh There's `cmd.exe` which is barely better than DOS 1.0. PowerShell has been shipping with Windows for about ten years, though. – tadman Feb 25 '18 at 19:13
  • @tadman cmd.exe supports pipes and i'm sure I can demonstrate the same probelm in powershell too if you prefer – barlop Feb 25 '18 at 19:13
  • oh, I thought PowerShell was some third party SW, my bad. – Naresh Feb 25 '18 at 19:14
  • @tadman php -r Does take input `php -r "4;"` – barlop Feb 25 '18 at 19:14
  • @barlop This appears to be an XY Problem. What's the motivation between trying to pipe here when piping does nothing useful? – tadman Feb 25 '18 at 19:14
  • @tadman I want to run php -r on a file,(php does -r lets the input run without php tags), and `php -r -f aa.php` doesn't work either (the -r has no effect) – barlop Feb 25 '18 at 19:14
  • @barlop There's a difference between "takes input" as in *requires an argument* and "takes input" as in *reads from STDIN*. The first one requires command-line interpolation, which in bash is `php -r \`echo 4\``. The second is like `echo 4 | php -r` but which is entirely different. – tadman Feb 25 '18 at 19:15
  • @tadman I agree they're different but apparently both work in linux so php in linux supports both. – barlop Feb 25 '18 at 19:17
  • When I do `echo 4 | php -r` it errors out with the usage information because `-r` *requires an argument*. It's not valid, it doesn't work. – tadman Feb 25 '18 at 19:17
  • @tadman What OS are you using tadman to test that ? As I said. I have a friend with linux that said it worked for him – barlop Feb 25 '18 at 19:18
  • Tested on both Ubuntu (Linux) and macOS. If it "worked" you'll have to be more specific about what it did because I can't see that command doing anything useful. – tadman Feb 25 '18 at 19:21
  • 2
    did't work for me in Ubuntu 14... same usage error – Naresh Feb 25 '18 at 19:21
  • @Naresh ok thanks, I guess i had wrong info from the friend that said it worked for them – barlop Feb 25 '18 at 19:22
  • @man0v Sideline: *both* cmd.exe ( https://ss64.com/nt/syntax-redirection.html ) and PS ( https://stackoverflow.com/questions/11447598/redirecting-standard-input-output-in-windows-powershell ) support basic STDOUT-STDIN pipes. – user2864740 Feb 25 '18 at 19:23
  • 1
    I think your friend is misrepresenting what actually happened or isn't conveying what they actually did. `echo 4; | php -r` is a syntax error at the shell level. `echo 4 | php -r` does nothing useful. – tadman Feb 25 '18 at 19:23
  • @tadman Does `echo 4 | php -r` for you in linux, print nothing or print usage info? (there is a big difference there because if it prints nothing, it works and if it prints usage info it doesn't) – barlop Feb 25 '18 at 19:24
  • @barlop It prints usage info because `-r` requires an argument that isn't given. – tadman Feb 25 '18 at 19:25
  • @tadman thanks for testing, and yes now we have established that, thanks – barlop Feb 25 '18 at 19:36

2 Answers2

1

There's a few points of confusion here, so I'll do my best to itemize what's wrong.

First, the original command can't work on Linux/POSIX shell because it's not valid:

echo 4; | php -r

Where ; has significant meaning, it's a command separator, and a command can't begin with |.

Fixing this, you get:

echo '4;' | php -r

Where that is at least valid as far as the shell is concerned, but it's still not enough for PHP to deal with. The -r argument requires a second term, code, which is the code to be evaluated. This needs to be supplied inline, not externally as you usually would.

Specifically the -r flag does not mean "run the input file as if it has <?php ... ?> surrounding it" but instead it means "run this bit of code in PHP mode".

For example:

echo '4;' | php

Technically works, but it's not evaluated as PHP code, so it's pointless.

The version that does work in POSIX shell is this:

php -r `echo '4;'`

Where that inlines the output of echo '4;' into the command-line argument itself. I'm not sure Windows can do that without PowerShell involved.

The -r flag is intended for quick little snippets like:

php -r 'echo 5 * 9;'

Where that prints 45 as expected.

tadman
  • 208,517
  • 23
  • 234
  • 262
  • Thanks, I see that -r doesn't accept stdin, and if you do pass a file with -f, it won't apply -r to it, and the info I had from the friend was incorrect. Though one could use xargs – barlop Feb 25 '18 at 19:43
  • @barlop `xargs` is a whole other can of worms. – tadman Feb 25 '18 at 19:44
  • Why a can of worms? – barlop Feb 25 '18 at 19:44
  • Let's tackle one problem at a time per question. If you have another related to `xargs` you can open that up independently. – tadman Feb 25 '18 at 19:46
-1

Try

echo 4 | php -r

instead of terminating echo 4 and piping nothing into php.

Not that it should matter, "-r" means nothing to php. Nor does 4 (apart from rhyming).

Gerard H. Pille
  • 2,528
  • 1
  • 13
  • 17
  • 1
    The `-r` flag requires an argument, which in this case is omitted. Also STDIN is apparently ignored in `-r` mode. – tadman Feb 25 '18 at 19:16
  • 1
    @tadman so why has gerard written it with STDIN with -r as if it's not ignored? is gerard incorrect? What OS have you tested this in tadman? And Gerard, what OS have you tested this in? – barlop Feb 25 '18 at 19:17
  • I can't test it, i have currently no Windows. Piping does work in Windows CMD, but php needs a php command, and I've never seen the command "4" or "4;" in php. – Gerard H. Pille Feb 25 '18 at 19:20
  • 2
    @GerardH.Pille In the original question it's `echo 4; | php -r` which I think is a mangling of `php -r '4;'` which actually is valid PHP code. On Linux `;` is a command separator, though, so running that you get "syntax error near unexpected token `|`". – tadman Feb 25 '18 at 19:22
  • @barlop thanks for testing, it's what I thought. Try piping something sensible to php, like " echo " | php" – Gerard H. Pille Feb 25 '18 at 19:23
  • @tadman, pleas enlighten me, what does "4;" do in Windows php? – Gerard H. Pille Feb 25 '18 at 19:26
  • @GerardH.Pille You haven't understood the question. the -r argument means no php tags needed. So a file with just `4;` in php would do nothing, not give an error. – barlop Feb 25 '18 at 19:26
  • @GerardH.Pille I don't think it doesn't do anything there, either. This whole thing is a red herring. – tadman Feb 25 '18 at 19:26
  • 1
    @barlop The argument is documented as `-r ` which means `code` is required. Without any code it errors out with usage info because the argument is wrong. – tadman Feb 25 '18 at 19:27
  • @tadman doing nothing means it worked. Giving usage info means it didn't work. I have not given any red herrings. This answer was untested and when tested, failed. – barlop Feb 25 '18 at 19:27
  • 1
    @barlop I think we've firmly established that the original `echo 4; | php -r` cannot possibly work for two specific reasons: `;` is a special character to bash, so that's wrong, and `-r` requires an argument, so that's wrong as well. That it doesn't work in Windows is a consequence of both those things. – tadman Feb 25 '18 at 19:28
  • @tadman `;` is not special in cmd it gets passed literally. For linux it'd be echo '4;' but php -r only takes a file and not stdin so it doesn't work. Windows has no issue with the semicolon. Linux does and needs quotes. – barlop Feb 25 '18 at 19:30
  • This does work on Linux: "echo "print 'boe';" | php" – Gerard H. Pille Feb 25 '18 at 19:30
  • @barlop `php -r` is one of the few arguments that does not take a file. It *must* have the code supplied immediately following the `-r` argument. Note how the `-r` usage is documented on its own line in the usage because of how unusual it is. – tadman Feb 25 '18 at 19:32
  • @GerardH.Pille `echo asdf|php` also works but it's not what I was asking about.. Maybe I should delete my question 'cos it was based on misinformation – barlop Feb 25 '18 at 19:34
  • @tadman If you want you can write an answer explaining that it's not possible and that -r doesn't accept stdin, and if you do pass a file with -f, it won't apply -r to it, and the info I had from the friend was incorrect. (The ; was irrelevant in the windows case because windows doesn't consider the ; to be special.. the linux equivalent quoting the ; didn't work for the above mentioned reason) – barlop Feb 25 '18 at 19:34