bash:意外令牌附近的语法错误`|'

时间:2015-09-15 10:19:27

标签: linux bash shell awk

此命令在命令提示符下运行良好:

 ]$ ls -ltr ../cmxserver.log*|grep "`date | awk '{print $2" "$3}'`"|cut -d "/" -f2
 cmxserver.log.2
 cmxserver.log.1
 cmxserver.log

但是,在for循环中使用this会产生错误bash:意外标记附近的语法错误`|'

   ]$for y in `ls -ltr ../cmxserver.log*|grep "`date | awk '{print $2" "$3}'`"|cut -d "/" -f2`

 -bash: syntax error near unexpected token `|'

有什么想法吗?

由于

2 个答案:

答案 0 :(得分:4)

整行可以通过find命令解决:

find .. -maxdepth 1 -mtime -1 -daystart -name 'cmxserver.log*' -printf "%f\n"
  • .. - 搜索目录
  • -maxdepth 1 - 不要递归到子目录
  • -mtime -1 - 仅限今天的文件
  • -daystart - 计算午夜以来的一天,而不是过去24小时
  • -name 'cmxserver.log*' - 文件名
  • -printf "%f\n" - 仅打印basename

答案 1 :(得分:0)

您可能理解键入时的含义:

for y in `ls -ltr ../cmxserver.log*|grep "`date | awk '{print $2" "$3}'`"|cut -d "/" -f2`

但是你已经设法完全混淆了bash。 Bash(和其他炮弹)不会反击(`),除非内部反击。如上所述,第二个反引号被认为是关闭第一个反引号,从而产生命令ls -ltr ../cmxserver.log*|grep "。由于您没有在date之前放置空格,因此将单词date解析为包含命令替换的单词的一部分。同样,单引号'{print $2"$3}'被解析为前缀为反引号命令"|cut -d "/" -f2

当然,这两个反引号命令都是语法错误,因为它们包含未闭合的双引号,但在bash到达解析和执行命令之前,它留下的内容粗略地说:

for y in word1 | awk word2

这是一个语法错误,因为管道符号只能出现在完整的命令之间,而for y in word1不是一个完整的命令。

不推荐使用反引号。停止使用它们。

如果你写了:

   for y in $(ls -ltr ../cmxserver.log* |
              grep "$(date | awk '{print $2" "$3}')" |
              cut -d "/" -f2)

bash和人类读者都会发现表达式更容易解析,而bash会按照你的预期解析它。

话虽如此,尝试解析ls输出是never a good idea,并且永远不需要解析date输出,因为你可以specify a format字符串;在这种情况下,您可以使用date +"%b %d"来获取月和日。 (第一个链接由Charles Duffy的评论提供。)