tags:

views:

43

answers:

2

It may help if you are on a Mac and use TextMate, though not entirely necessary.

My php location:

$which php  
/opt/local/bin/php

The script:

#!/opt/local/bin/php 
<?php
    shell_exec("echo -n 'my-string' > out.txt");
?>

The -n to echo suppress the newline that is automatically added to all shell echo commands.

If I run the above php code from the shell:

chmod u+x myfile.php
./myfile.php

I end up with 'out.txt', the contents of which being:

-n my-string

If I run the exact same code within TextMate, the contents of 'out.txt' will be correct:

my-string

I can't figures out what php is up to with putting the literal string '-n' in the output. I really wonder why TextMate does the correct thing. I have checked that both are using the same php, php -i shows mostly the same stuff, of course there are differences as one is run within TextMate, the other in the shell, so one output has pointers to the file whereas the other doesn't. As far as I can tell, $PATH and $ENV are the same.

I have tried a handful of different methods to work around this none of which are working. I actually will not be able to use a workaround, as this has been distilled down to a simple case for posting to SO. My use case for this pipes to pbcopy, which I believed was a Mac OS X only feature, so I used >> redirection here because that is universal.

Ultimately, I want a result on my clipboard that does not have a trailing newline, which is dangerous as pasting that in a shell will execute whatever preceded it.

Thanks

+6  A: 

Is it possible that php is calling a different echo than your shell built in echo? Many versions of echo do not support -n and will output it as part of your string.

You could try shell_exec("which echo"); to find out which it is running.

Note that printf will not display the new line unless you explicitly add it. So you can use which printf to figure out where this resides and call it instead.

shell_exec("/usr/local/bin/printf '%s' 'mystring' > out.txt");

Brandon Horsley
Nice, I came back here to post that I finally stopped banging my head on the wall and figrued it out, but you got it as well. I forced an error on the line so I could see what the shell was calling and I got sh -n not found, which led me to a duh moment. So, added full path to echo and all is well. Thanks everyone.
A: 

PHP just defers the call to popen in Unix platforms. See the manual page for Mac OS X:

The command argument is a pointer to a null-terminated string containing a shell command line. This command is passed to /bin/sh, using the -c flag; interpretation, if any, is performed by the shell.

So it should be the same as running /bin/sh -c "echo -n 'my-string' > out.txt"

Artefacto