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

在POSIX shell语法中,AND-OR列表中的多个重定向是否有效?,shell,posix,grammar,Shell,Posix,Grammar,我想知道在POSIX shell语法中使用重定向是否有效 if cat foo > foo.txt && cat bar > bar.txt then echo true else echo false fi 我一直在阅读文章以确定这一点,但我不太确定我是否正确理解了它 这是我到目前为止所理解的 if_clause : If compound_list Then compound_list else_part Fi

我想知道在POSIX shell语法中使用重定向是否有效

if cat foo > foo.txt && cat bar > bar.txt
then
    echo true
else
    echo false
fi
我一直在阅读文章以确定这一点,但我不太确定我是否正确理解了它

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

if_clause        : If compound_list Then compound_list else_part Fi
                 | If compound_list Then compound_list           Fi
                 ;
因此,要使我的代码示例成为有效的
if_子句
cat foo>foo.txt&&cat bar>bar.txt
必须是
复合_列表

compound_list    :              term
                 | newline_list term
                 |              term separator
                 | newline_list term separator
                 ;
因此,要使
cat foo>foo.txt&&cat bar>bar.txt
成为有效的
复合列表
,它还必须是一个
术语

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
                 ;
由于
cat foo>foo.txt和&cat bar>bar.txt中没有
分隔符
,因此它必须是有效的
术语
,并且_或

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

and_or           :                         pipeline
                 | and_or AND_IF linebreak pipeline
                 | and_or OR_IF  linebreak pipeline
                 ;
cat foo>foo.txt和&cat bar>bar.txt
中有
和\u IF
,所以让我们看看
cat foo>foo.txt和&cat bar>bar.txt
是否匹配
和\u or和\u IF linebreak pipeline

若要使
cat foo>foo.txt和&cat bar>bar.txt
成为有效的
和_或and _iflinebreak pipeline
cat foo>foo.txt
必须是有效的
和_或
cat bar>bar.txt
必须是有效的
管道

由于在
cat foo>foo.txt
中没有进一步的
和_IF
,因此它必须是
和_或
管道

换句话说,要使
cat foo>foo.txt&&cat bar>bar.txt
成为有效的
和_或_iflinebreak pipeline
,则
cat foo>foo.txt
cat bar>bar.txt
都必须是有效的
pipeline
s

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

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

pipeline         :      pipe_sequence
                 | Bang pipe_sequence
                 ;
因为
cat foo>foo.txt
没有
在其中,要使其成为有效的
管道
,它还必须是有效的
管道序列

pipe_sequence    :                             command
                 | pipe_sequence '|' linebreak command
                 ;
由于
cat foo>foo.txt
中没有
,因此它必须是有效的
管道序列
,也必须是有效的
命令

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
                 ;
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
没有
{
for
case
if
while
,或
直到
,它不能是
复合命令重定向列表
复合命令重定向列表
函数定义
。因此,对于
cat foo>foo.txt
到有效的
命令
,它必须是有效的
>简单命令

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
                 ;
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
                 ;
要使
foo>foo.txt
成为有效的
cmd\u后缀
foo
必须是有效的
cmd\u后缀
>foo.txt
必须是有效的
io\u重定向

实际上,
foo
是一个有效的
cmd\u后缀
,因为它是一个有效的
WORD

io_redirect      :           io_file
                 | IO_NUMBER io_file
                 |           io_here
                 | IO_NUMBER io_here
                 ;
要使
>foo.txt
有效
io\u重定向
必须是有效的
io\u文件

io_file          : '<'       filename
                 | LESSAND   filename
                 | '>'       filename
                 | GREATAND  filename
                 | DGREAT    filename
                 | LESSGREAT filename
                 | CLOBBER   filename
                 ;
事实上,
foo.txt
是一个有效的
filename
,因为它是一个有效的
WORD
。这证明了
cat foo>foo.txt
是一个有效的
simple_命令
,因此,
cat foo>foo.txt&&cat bar>bar.txt
是一个有效的
,因此,我提供的代码示例是一个有效的
>if_子句

我说得对吗?

你声称:

…在
cat foo>foo.txt&&cat bar>bar.txt

但显然存在,因为
和_IF
是标记的名称&。该运算符的操作数是管道,可能是包含重定向的简单命令。因此表达式完全有效


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

谢谢!这是我问题中的一个严重错误。我已经修正了我的问题,并再次解决了整个问题,它看起来确实是一个有效的
if_子句
,但我希望有人检查我的推导,并确认它是否正确。@LoneLearner:e构造在任何shell上都能工作,似乎人类的确认有些多余,但我编辑了我的答案以提供一些。