AND-OR列表中的多个重定向是否在POSIX shell语法中有效?

时间:2015-03-08 09:28:40

标签: shell posix grammar

我想知道在AND-OR list中使用重定向是否是有效的POSIX shell语法。

if cat foo > foo.txt && cat bar > bar.txt
then
    echo true
else
    echo false
fi

我一直在阅读Shell Grammar Rules以确定这一点,但我不确定我是否理解正确。

这是我到目前为止所理解的。

if_clause        : If compound_list Then compound_list else_part Fi
                 | If compound_list Then compound_list           Fi
                 ;

因此,要使我的代码示例有效if_clausecat foo > foo.txt && cat bar > bar.txt必须为compound_list

compound_list    :              term
                 | newline_list term
                 |              term separator
                 | newline_list term separator
                 ;

因此,要使cat foo > foo.txt && cat bar > bar.txt成为有效compound_list,它必须也是term

term             : term separator and_or
                 |                and_or
                 ;

newline_list     :              NEWLINE
                 | newline_list NEWLINE
                 ;

linebreak        : newline_list
                 | /* empty */
                 ;

separator_op     : '&'
                 | ';'
                 ;

separator        : separator_op linebreak
                 | newline_list
                 ;

由于separator中没有cat foo > foo.txt && cat bar > bar.txt,因此它是有效的term,它必须是有效的and_or

%token  AND_IF    OR_IF    DSEMI
/*      '&&'      '||'     ';;'    */

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline
                 ;

AND_IF中有cat foo > foo.txt && cat bar > bar.txt,因此,让我们看看cat foo > foo.txt && cat bar > bar.txt是否与and_or AND_IF linebreak pipeline匹配。

要使cat foo > foo.txt && cat bar > bar.txt成为有效的and_or AND_IF linebreak pipelinecat foo > foo.txt必须是有效的and_orcat bar > bar.txt必须是有效的pipeline。< / p>

由于AND_IF中没有cat foo > foo.txt,因此它是and_or,它也必须是pipeline

换句话说,要使cat foo > foo.txt && cat bar > bar.txt成为有效的and_or AND_IF linebreak pipelinecat foo > foo.txtcat bar > bar.txt都必须有效pipeline

现在,让我们看看我们是否可以将cat foo > foo.txt证明为有效pipeline。如果我们可以这样做,那么cat bar > bar.txt也会被证明是有效的pipeline,因为它们在构造方面相似。

%token  Lbrace    Rbrace    Bang
/*      '{'       '}'       '!'   */

pipeline         :      pipe_sequence
                 | Bang pipe_sequence
                 ;

由于cat foo > foo.txt中没有!,因此它是有效的pipeline,它也必须是有效的pipe_sequence

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command
                 ;

由于cat foo > foo.txt中没有|,因此它是有效的pipeline_sequence,它也必须是有效的command

command          : simple_command
                 | compound_command
                 | compound_command redirect_list
                 | function_definition
                 ;

function_definition : fname '(' ')' linebreak function_body
                     ;

%token  If    Then    Else    Elif    Fi    Do    Done
/*      'if'  'then'  'else'  'elif'  'fi'  'do'  'done'   */

%token  Case    Esac    While    Until    For
/*      'case'  'esac'  'while'  'until'  'for'   */
%token  Lbrace    Rbrace    Bang
/*      '{'       '}'       '!'   */

brace_group      : Lbrace compound_list Rbrace
                 ;

subshell         : '(' compound_list ')'
                 ;

for_clause       : For name linebreak                            do_group
                 | For name linebreak in          sequential_sep do_group
                 | For name linebreak in wordlist sequential_sep do_group
                 ;

if_clause        : If compound_list Then compound_list else_part Fi
                 | If compound_list Then compound_list           Fi
                 ;

while_clause     : While compound_list do_group
                 ;

until_clause     : Until compound_list do_group
                 ;

由于cat foo > foo.txt没有{(forcaseifwhileuntil,不能是compound_command redirect_listcompound_command redirect_listfunction_definition。因此,对于cat foo > foo.txt到有效command,它必须是有效的simple_command

simple_command   : cmd_prefix cmd_word cmd_suffix
                 | cmd_prefix cmd_word
                 | cmd_prefix
                 | cmd_name cmd_suffix
                 | cmd_name
                 ;
%token  DLESS  DGREAT  LESSAND  GREATAND  LESSGREAT  DLESSDASH
/*      '<<'   '>>'    '<&'     '>&'      '<>'       '<<-'   */


%token  CLOBBER
/*      '>|'   */

cmd_prefix       :            io_redirect
                 | cmd_prefix io_redirect
                 |            ASSIGNMENT_WORD
                 | cmd_prefix ASSIGNMENT_WORD

io_redirect      :           io_file
                 | IO_NUMBER io_file
                 |           io_here
                 | IO_NUMBER io_here
                 ;

io_file          : '<'       filename
                 | LESSAND   filename
                 | '>'       filename
                 | GREATAND  filename
                 | DGREAT    filename
                 | LESSGREAT filename
                 | CLOBBER   filename
                 ;

io_here          : DLESS     here_end
                 | DLESSDASH here_end
                 ;

由于cat foo > foo.txt不是以IO_NUMBER(数字),io_file(重定向符号),<<-<<-ASSIGNMENT_WORD开头(=中的WORD),不能是cmd_prefix cmd_word cmd_suffixcmd_prefix cmd_wordcmd_prefix

因此,要使cat foo > foo.txt成为有效simple_command,必须为cmd_name cmd_suffix

由于cmd_name定义为WORD,因此cat foo > foo.txt为有效命令,foo > foo.txt必须为cmd_suffix

cmd_suffix       :            io_redirect
                 | cmd_suffix io_redirect
                 |            WORD
                 | cmd_suffix WORD
                 ;

要使foo > foo.txt成为有效的cmd_suffixfoo必须是有效的cmd_suffix,而> foo.txt必须是有效的io_redirect

确实foo是有效的cmd_suffix,因为它是有效的WORD

io_redirect      :           io_file
                 | IO_NUMBER io_file
                 |           io_here
                 | IO_NUMBER io_here
                 ;

要使> foo.txt有效io_redirect,它必须是有效的io_file

io_file          : '<'       filename
                 | LESSAND   filename
                 | '>'       filename
                 | GREATAND  filename
                 | DGREAT    filename
                 | LESSGREAT filename
                 | CLOBBER   filename
                 ;

要使> foo.txt有效io_filefoo.txt必须是有效的filename

filename         : WORD                      /* Apply rule 2 */
                 ;

确实foo.txt是有效的filename,因为它是有效的WORD。这证明cat foo > foo.txt是有效的simple_command,因此cat foo > foo.txt && cat bar > bar.txt是有效的and_or,因此,我提供的代码示例是有效的if_clause

我说错了吗?

1 个答案:

答案 0 :(得分:2)

你声称:

  

... AND_IF

中没有OR_IFcat foo > foo.txt && cat bar > bar.txt

但很明显,因为AND_IF是令牌&amp;&amp; 的名称。该运算符的操作数是管道,可以是简单的命令,包括重定向。所以表达完全有效。

编辑:现在问题已被编辑,这个答案几乎毫无意义(或者至少需要调查修订历史记录)。据我所知,修订后的问题中的推理是正确的。