我想知道在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_clause
,cat 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 pipeline
,cat foo > foo.txt
必须是有效的and_or
且cat 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 pipeline
,cat foo > foo.txt
和cat 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
没有{
,(
,for
,case
,if
,while
或until
,不能是compound_command redirect_list
,compound_command redirect_list
或function_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_suffix
,cmd_prefix cmd_word
或cmd_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_suffix
,foo
必须是有效的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_file
,foo.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
。
我说错了吗?
答案 0 :(得分:2)
你声称:
...
中没有AND_IF
OR_IF
或cat foo > foo.txt && cat bar > bar.txt
但很明显,因为AND_IF
是令牌&amp;&amp; 的名称。该运算符的操作数是管道,可以是简单的命令,包括重定向。所以表达完全有效。
编辑:现在问题已被编辑,这个答案几乎毫无意义(或者至少需要调查修订历史记录)。据我所知,修订后的问题中的推理是正确的。