Linux - C SHELL报错提示“Missing }.“

54 篇文章 22 订阅
23 篇文章 1 订阅

Linux - C SHELL报错提示"Missing }."

问题描述

Last login: Mon Aug  9 20:07:43 2021

Welcome to Alibaba Cloud Elastic Compute Service !

[thesre@centos8 ~]$ source .cshrc
Missing }.
[thesre@centos8 ~]$ 

问题分析

为了便于演示,本案例将二分法定位故障域、source(间接)语句以及其余无关语句都移除。

.cshrc文件备份,source备份文件。第一次无报错,第二次source时会报错,如下

[thesre@centos8 ~]$ mv .cshrc .cshrc_bak20210809
[thesre@centos8 ~]$ exit #exit and log in again.
Last login: Mon Aug  9 20:09:09 2021 from 219.134.115.231

Welcome to Alibaba Cloud Elastic Compute Service !

[thesre@centos8 ~]$ source .cshrc_bak20210809 #第一次无报错
[thesre@centos8 ~]$ source .cshrc_bak20210809 #第二次报错
Missing }.
[thesre@centos8 ~]$ 

查看.cshrc文件

[thesre@centos8 ~]$ cat .cshrc_bak20210809 
set set_result=`set|grep ^set`
alias grep 'grep -r'

使用简单的二分排除法,

注释第一行:

[thesre@centos8 ~]$ cat .cshrc_bak20210809 
# set set_result=`set|grep ^set`
alias grep 'grep -r'
[thesre@centos8 ~]$ source .cshrc_bak20210809 #第一次无报错
[thesre@centos8 ~]$ source .cshrc_bak20210809 #第二次无报错

注释第二行:

[thesre@centos8 ~]$ cat .cshrc_bak20210809 
set set_result=`set|grep ^set`
# alias grep 'grep -r'
[thesre@centos8 ~]$ source .cshrc_bak20210809 #第一次无报错
[thesre@centos8 ~]$ source .cshrc_bak20210809 #第二次无报错

观察到上述任何一行单独存在时,都无报错。

我们仔细分析下这两句命令,第一句看起来没什么特别,执行set然后过滤一下以set开头的字符串。第二句我们看下,是设置grep别名,默认加上-r选项。

[thesre@centos8 ~]$ man grep
       -r, --recursive
              Read all files under each directory, recursively, following symbolic links only  if  they are on the command line.  This is equivalent to the -d recurse option.

在ssh登陆进来后,被第二遍source时该grep别名是生效的。由于CWD为家目录,

set set_result=`set|grep ^set`

命令就会从家目录递归地过滤,并将结果赋值给set_result。我们将这两句放到一个脚本,并在解析器那一行加上-x选项,打开调试模式:

[thesre@centos8 ~]$ cat debug_missing_closing_curly_brace.csh 
#!/bin/csh -x

alias grep 'grep -r'
set set_result=`set|grep ^set`
[thesre@centos8 ~]$ ./debug_missing_closing_curly_brace.csh 
alias grep grep -r
set set_result=`set|grep ^set`
grep -r ^set
set
Missing }.

可以看到是执行set命令时报了错。

错误解决

经确认,该别名是错误设置的,因为一般情况下都不会默认使用当前文件夹来递归过滤字符串。将该别名去掉即可解决问题。

知识延伸

在这里复现一种引起Missing }报错的场景。定义一个变量,赋值字符串,然后使用echo打印它。

[ben@centos8 ~]$ set set_result='{"key01":"", "key02":""}'
[ben@centos8 ~]$ echo $set_result
Missing }.

根据资料,可以使用variable modifier来打印变量的值。

5.3.2 Variable Modifiers Except for $? var , $$ , $?0 , and $< , the variable substitutions above may be followed by one of these modifiers. When braces are used, the modifier goes inside them. docstore.mik.ua/orelly/unix/unixnut/ch05_03.htm

 :q Quote a wordlist variable, keeping the items separate. Useful when the variable contains filename metacharacters that should not be expanded. docstore.mik.ua/orelly/unix/unixnut/ch05_03.htm

效果:

[ben@centos8 ~]$ set set_result='{"key01":"", "key02":""}'
[ben@centos8 ~]$ echo $set_result
Missing }.
[ben@centos8 ~]$ echo $set_result:q
{"key01":"", "key02":""}

心得

在定位时,经常会遇到这样的情况:在第一次source时正常,第二次source时却报错。这个时候应该朝“两个或两个语句以上综合引起报错”的方向定位,因为很明显,第一次source不会报错。

参考资料

https://docstore.mik.ua/orelly/unix/unixnut/ch05_03.htm

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

王万林 Ben

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值