我在Unix中创build一个别名,并发现以下命令失败..
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }''
我得到以下内容:
awk: cmd. line:1: {print awk: cmd. line:1: ^ unexpected newline or end of string
有关为什么pipe道awk命令失败的任何想法…
谢谢,肖恩。
补充@ Dropout的有用答案 :
问题在于OP试图使用'
内部 '
(包括单引号)的字符串。
在这种情况下, 最健壮的解决方案是用'\''
(原文如此) 替换每个内部 :
alias logspace='find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '\''{print $5, $9 }'\'''
'...'
…'-enclosed)字符串内部使用字符 – 甚至不用转义 。
"
\"
,就像在@ Droput的答案中一样,你可以直接在里面嵌入字符,但是在下面可以看到陷阱。 '\''
表示:“关闭字符串”,“转义单引号”,“开始新字符串”。 其他解决方案及其缺陷 :
以下讨论替代解决方案,基于以下别名:
alias foo='echo A '\''*'\'' is born at $(date)'
请注意,如何将*
有效地用单引号引起来 – 使用上述技术 – 以防止别名稍后被调用时的路径名扩展。
当被调用的时候,这个别名会打印A * star is born
文字 ,然后是当前的日期和时间,例如: A * is born at Mon Jun 16 11:33:19 EDT 2014
。
使用一个叫做ANSI C的特性来引用支持它的shell: bash
, ksh
, zsh
ANSI C引用的字符串, 包含在$'...'
,允许转义嵌入'
字符。 如\'
:
alias foo=$'echo A \'*\' is born at $(date)'
陷阱 :
\n
, \t
等转义序列也被解释(事实上,这是该功能的目的)。 使用交替的引用样式 ,如@ Dropout的答案:
陷阱 :
'...'
和"..."
具有不同的语义 ,所以用一个替代另一个可能会产生意想不到的副作用:
alias foo="echo A '*' is born at $(date)" # DOES NOT WORK AS INTENDED
虽然在语法上是正确的,但这不会按预期工作,因为使用双引号会导致shell立即扩展命令替换$(date)
,从而将别名定义时的日期和时间硬连接到别名中 。
如上所述:在定义别名时 ,通常需要围绕其定义使用单引号 ,以便延迟对命令的评估 ,直到调用别名为止。
最后,一个警告 :
在类似Bourne的shell环境中,棘手的事情是, 在单引号字符串中嵌入'
有时 – 错误地 – 嵌入'
来工作 (而不是像在问题中那样产生语法错误)
alias foo='echo a '*' is born at $(date)' # DOES NOT WORK AS EXPECTED.
这个定义被接受了 (没有语法错误),但是不能按预期工作 – 定义的右边被有效地解析为3个字符串 – 'echo a '
, *
和' is born at $(date)'
,由于shell解析字符串的方式(合并相邻的字符串,引用移除),结果是以下单个字符串: a * is born at $(date)
。 由于*
在生成的别名定义中未加引号 ,因此它将展开到当前目录(路径名扩展)中的所有文件/目录名称的列表。
你应该使用不同的引号围绕整个文本和内部的字符串。
尝试改变它
alias logspace="find /apps/ /opt/ -type f -size +100M -exec ls -lh {} \; | awk '{print $5, $9 }'"
换句话说,你的外部报价应该与内部报价不同,所以他们不会混合。
社区wiki更新 :
'
) 。 注意:代码片段是伪代码 ,而不是shell语言。
基本字符串:您不能在字符串中使用相同的引号,因为整个字符串是以下列字符分隔的:
foo='hello, 'world!''; ^--start string ^-- end string ^^^^^^^^--- unknown "garbage" causing syntax error.
你必须逃避内部的字符串:
foo='hello, \'world!\''; ^--escape
世界上几乎所有的编程语言都是如此。 如果他们不提供逃避机制,如\
,那么你必须使用替代手段,例如
quotechar=chr(39); // single quote is ascii #39 foo='hello ,' & quotechar & 'world!' & quotechar;