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

Escape value in echo statement in Terminal on Mac

所以我一直在努力为 .bash_profile 添加一些别名,以便更容易地在我的 Mac.I 上设置作曲家 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'

进行转义

但是运气不好。

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

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

有很多方法可以解决这个问题,但它们很难看。 alias sp='touch ... $ '"'"'/vendor/... 之类的东西——这里,第一个单引号结束单引号段,然后是一个包含单引号的双引号段,然后是另一个单引号段的开头。呸。

真的,当定义别名变得如此复杂时,您最好还是改用函数。除其他事项外,它们不需要被引用,所以整个问题都没有实际意义:

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 和此处文档。您可以在函数内部执行此操作(与别名不同):

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

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

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

如果你想要更干净的缩进,你也可以使用<<-"EOF",然后用制表符(不是空格)缩进here-doc内容。