csh中含空格的{}变量定义失败,求原因解析
csh中{}列表语法空格导致"Missing }"错误的原因
问题场景
我有一个仅包含一行内容的文件A.f:
Check something: {nameA nameB nameC}
执行命令定义变量var_A时:
set var_A = `grep "Check something" A.f | head -n 1`
出现错误提示:
Missing }.
我做了以下测试,结果更困惑:
echo {0}. # 输出:0 echo {0 1}. # 报错:Missing }. echo {0 }. # 报错:Missing }. echo "{0 1}" # 输出:{0,1}
已知csh中{}是列表形式的简写,想知道为什么{}内不能包含空格?
原因解析
csh的词法解析规则
csh里的大括号列表语法不允许内部加空格,这是由shell的解析优先级决定的:
- 当直接写
{0 1}时,csh会把{0识别成一个单独的词,1}是另一个词,此时shell认为左大括号没有对应的右大括号,所以抛出Missing }错误。 - 列表的正确写法是用逗号分隔元素,比如
{0,1},shell会识别这是完整的列表展开,展开后得到0 1。
测试结果的对应解释
echo {0}.:{0}是单个元素的列表,shell直接展开为0,最终输出0.。echo {0 1}.:shell拆分词后,{0和1}分离,左大括号无闭合,触发错误。echo {0 }.:同理,{0和}.被拆成两个词,左大括号未闭合,报错。echo "{0 1}":双引号会禁用shell对内部大括号的语法解析,把整个{0 1}当作普通字符串输出(注:此处测试输出{0,1}可能是笔误,正常应输出{0 1})。
解决原始问题
要正确读取文件内容到变量,需用引号包裹命令替换部分,避免shell提前解析大括号:
set var_A = "`grep "Check something" A.f | head -n 1`"
或者用sed转义大括号后再赋值:
set var_A = `grep "Check something" A.f | head -n 1 | sed 's/{/\\{/g; s/}/\\}/g'`
内容的提问来源于stack exchange,提问作者lizhiqing
相关产品推荐
相关产品推荐

