管道和重定向绑定优先级与分词,合词等有关?


8

我知道运算符';','&','&&'或'||'的相对绑定优先级

http://www.gnu.org/software/bash/manual/bashref.html#Lists

但是当管道与“ &&”一起出现在图片中时,我很难理解绑定强度,或者偶然发现了正确的命令,或者只是放弃了。

'|'的绑定优先级是什么 和“>”与上述相比?

我感到困惑的示例:

ls _thumbnails/video.mp4.jpg 2>/dev/null 
    && echo "thumbnail already generated. Not regenerating" \
    && exit \
    || ffmpeg_thumbnail_create video.mp4 2>/dev/null \
    && ls _thumbnails/video.mp4.jpg \
    && echo "Thumbnail successfully created" \
    && exit \
    || echo "Thumbnail creation failed" \
    | tee ~/thumbnails.log

上面的目标是在且仅当一个缩略图不存在时创建缩略图(我每天运行一次cronjob)。而且我不喜欢没有错误时ffmpeg的大量输出(这不是Unix方式)。还有其他情况,所以不要开始给我建议,这些建议使用单独的语句或特定于这些程序的特殊选项。我想了解绑定优先级。


很有帮助-如果是回应,我会将此标记为正确。还有一个问题-如何更改优先级?从理论上讲,我认为{... }应该有效。我可能没有系统地尝试过,但没有得到预期的结果。
Sridhar Sarnobat 2014年

Answers:


12

简短的回答是<>和它们的变体具有最高优先级的结合(紧密的结合),随后|,其次是&&||,其次是;&。因此,仅将echo "Thumbnail creation failed"传送到tee

稍长一点的答案将指出,最高优先级实际上是分组,可以用括号或大括号表示。例如,

A  &&  (B; C)

A  &&  { B; C;}

大约等于

if A
then
    B
    C
fi

笔记:

  • 括号给你一个子壳。即命令BC在子进程中运行。因此,诸如变量赋值之类的命令或cd 对父外壳无效。花括号中的A命令与命令运行的过程相同。因此,支架结构A && { B; C;}更接近if- then- else结构。
  • 在支架的语法,存在必须是后一个空间{和一个;(或一个&,或换行)之前}

有关更多信息,请参阅外壳程序的控制和重定向运算符是什么?当是“如果”没有必要?(特别是我的答案)。

有关更多信息,请参见bash(1)手册页Shell命令语言的POSIX规范/定义,特别是第2.9节“ Shell命令”第2.10.2节“ Shell语法规则”。这是为上述内容提供一些背景的尝试:

    • myVar=42
    • IFS= read a
    • date
    • cd /some/directory
    • ls -laR dir1 dir2
    • cat foo* > /tmp/allfoo
    • ls -laR dir{1,2}
    • find . -type f -name "foo*" -print > /tmp/output 2> /dev/null
    • > newfile
    • [ -f catfood ]
    • exit

    都被认为是“简单命令”。

    • simple_command 1   |   simple_command 2   |   simple_command 3
    是“管道”。语法建立了构建块并在其上构建,这对于像这样的形式语法(以及对于像C这样的编程语言)来说是典型的,因此,单个“简单命令”被视为“管道”,即使它不包含管道。变量赋值成为管道的组成部分(语义)是没有意义的,但是类似x=1 | od -abls -laR | z=0在语法上有效的事情。
    • 管道1   &&   管道2   ||   管道3
      被bash称为“列表”,而被POSIX称为“与或列表”。同样,即使单个“管道”或什至单个“简单命令”也被视为“与或列表”,即使它不包含“与”或“或”。
    • 当您遇到诸如
        AND-OR列表1   AND-OR列表2  ;   AND-OR清单3
        命名开始变得有点不一致。Bash也称这些“列表”;POSIX称它们为“列表”,“化合物列表”和(很少)“术语”。同样,即使单个“ AND-OR列表”,“管道”甚至单个“简单命令”也被视为“列表”,即使其中不包含&;
        • compound_list 
            {  compound_list ;}
            和流控制命令for(  ifthen- - else,  while等)被称为“复合命令”。 
          • 在上面的例子中,它可能是很有道理的解释AB以及C为管道。记住,“管道”可以是单独的“简单命令”。它不需要包含管道。


            1
            感谢您对(.. ){.. 角色的详细解释}。我从以前的不良经验得出的结论是,圆括号仅在“动态命令”(即$(.. ))的上下文中使用,因为就关联性而言,我几乎无法使它们做任何事情。
            Sridhar Sarnobat 2014年
            By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
            Licensed under cc by-sa 3.0 with attribution required.