Reputation: 2647
So i've been working on adding a few aliases to the .bash_profile to make it easier to set up composer PHP/Composer projects on my Mac.I've gotten very close to completing this but i'm having an issue. I'm trying to output a string to a file i'm creating but the single quotes keep getting removed.
The alias i'm setting up is as follows:
alias sp='touch index.php; echo "<?php \n\n require_once __DIR__ . $ '/vendor/autoload.php' ?>;" >> index.php; open/Applications/TextWrangler.app index.php;'
The output i'm getting in the php file is:
<?php \n\n require_once __DIR__ . $ /vendor/autoload.php \n\n ?>
I've tried escaping using \e and $'string'
But have had no luck.
Upvotes: 1
Views: 843
Reputation: 126013
Short answer: When doing anything nontrivial, use functions instead of aliases and printf
instead of echo
.
Long answer: the immediate problem is that quotes don't nest. You're trying to use single-quotes around an alias that contains single-quotes, and that won't work. The shell is parsing your command as containing the single-quoted segment 'touch index.php; echo "<?php \n\n require_once __DIR__ . $ '
, followed by the unquoted segment /vendor/autoload.php
, followed by the single-quoted segment ' ?>;" >> index.php; open/Applications/TextWrangler.app index.php;'
-- it removes the quotes, mashes them together, and assigns the result as the alias.
There are ways to fix this, but they're ugly. Things like alias sp='touch ... $ '"'"'/vendor/...
-- here, the first single-quote ends the single-quoted segment, then there's a double-quoted segment containing a single-quote, then the beginning of another single-quoted segment. Bleh.
Really, when defining an alias gets this complicated, you're better off switching to a function. Among other things they don't need to be quoted, so this whole problem is moot:
sp() {
touch index.php
echo "<?php \n\n require_once __DIR__ . $ '/vendor/autoload.php' ?>;" >> index.php
open/Applications/TextWrangler.app index.php
}
But as long as I'm making suggestions, I'd make a couple of other changes. First, the touch
command isn't doing anything that the redirect isn't going to do anyway, so I'd leave it out. Second, using \n
with echo
is unpredictable; some versions of echo
convert it to newlines, some don't. It's actually changed between different versions of OS X. You're much better off using printf
for this, although it's more complicated to use properly. The first argument to printf
is a format string that's used to control how the rest of the arguments are printed. The other big difference from echo
is that it doesn't automatically add a newline to the end, so you have to do that yourself. I'm assuming you want to put this into the index.php file:
<?php
require_once __DIR__ . $ '/vendor/autoload.php'
?>
There are several ways to do this with printf
. Probably the simplest would be to make each line an argument, and use the format string to put a newline after each one:
printf '%s\n' "<?php" "" "require_once __DIR__ . \$ '/vendor/autoload.php'" "" "?>"
But In this case I'd use cat
with a here-document. You can do that inside a function (unlike an alias):
sp() {
cat <<"EOF" >>index.html
<?php
require_once __DIR__ . $ '/vendor/autoload.php'
?>
EOF
open/Applications/TextWrangler.app index.php
}
If you want cleaner indentation, you can also use <<-"EOF"
, and then indent the here-doc content with tabs (not spaces).
Upvotes: 4