在Mac上终端的echo语句中转义值

时间:2017-11-12 14:41:23

标签: macos terminal macos-sierra

所以我一直在努力为.bash_profile添加一些别名,以便更容易在我的Mac上设置作曲家PHP / Composer项目。我已经非常接近完成这个但我遇到了问题。我正在尝试将字符串输出到我正在创建的文件中,但单引号会被删除。

我正在设置的别名如下:

alias sp='touch index.php; echo "<?php  \n\n  require_once __DIR__ . $ '/vendor/autoload.php' ?>;" >> index.php; open/Applications/TextWrangler.app index.php;'

我在php文件中输入的输出是:

<?php  \n\n require_once __DIR__ . $ /vendor/autoload.php \n\n ?>

我尝试使用\ e和$'string'

转义

但是没有运气。

1 个答案:

答案 0 :(得分:3)

简短回答:做任何不重要的事情时,请使用函数而不是别名printf代替echo

答案很长:当前的问题是报价不会嵌套。您试图在包含单引号的别名周围使用单引号,但这不会起作用。 shell将您的命令解析为包含单引号段'touch index.php; echo "<?php \n\n require_once __DIR__ . $ ',然后是未引用的段/vendor/autoload.php,然后是单引号段' ?>;" >> index.php; open/Applications/TextWrangler.app index.php;' - 它会删除引号,mashes它们在一起,并将结果指定为别名。

有办法解决这个问题,但它们很丑陋。像alias sp='touch ... $ '"'"'/vendor/...这样的东西 - 这里,第一个单引号结束单引号段,然后是包含单引号的双引号段,然后是另一个单引号段的开头。的Bleh。

真的,当定义别名变得复杂时,你最好切换到一个功能。除了其他东西,他们不需要被引用,所以这整个问题没有实际意义:

sp() {
    touch index.php
    echo "<?php  \n\n  require_once __DIR__ . $ '/vendor/autoload.php' ?>;" >> index.php
    open/Applications/TextWrangler.app index.php
}

但只要我提出建议,我就会做出其他一些改变。首先,touch命令不会执行重定向无论如何都要执行的操作,因此我不予理会。其次,将\necho一起使用是不可预测的;某些版本的echo会将其转换为换行符,有些版本则不会。它实际上在OS X的不同版本之间进行了更改。尽管使用正确,但使用printf会更好。 printf的第一个参数是一个格式字符串,用于控制其余参数的打印方式。与echo的另一个重大区别是,它不会自动添加换行符,因此您必须自己执行此操作。我假设你想把它放到index.php文件中:

<?php

require_once __DIR__ . $ '/vendor/autoload.php'

?>

使用printf有几种方法可以做到这一点。可能最简单的方法是将每一行作为一个参数,并使用格式字符串在每一行之后添加换行符:

printf '%s\n' "<?php" "" "require_once __DIR__ . \$ '/vendor/autoload.php'" "" "?>"

但在这种情况下,我将cat与here-document一起使用。您可以在函数内部执行此操作(与别名不同):

sp() {
    cat <<"EOF" >>index.html
<?php

require_once __DIR__ . $ '/vendor/autoload.php'

?>
EOF
    open/Applications/TextWrangler.app index.php
}

如果您想要更简洁的缩进,您还可以使用<<-"EOF",然后使用制表符(空格)缩进here-doc内容。