在POSIX shell语法中,AND-OR列表中的多个重定向是否有效?
我想知道在POSIX shell语法中使用重定向是否有效在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
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上都能工作,似乎人类的确认有些多余,但我编辑了我的答案以提供一些。