Parece haver alguma inconsistência que não consigo entender sobre o shell bash.
Se eu executar:
ls;date;time
os resultados das três consultas são mostrados em sequência.
No entanto, na troca de posição de data e hora, uma mensagem de erro é exibida.
Então, se eu executar:
ls;time;date
a mensagem de erro diz: bash: syntax error near unexpected token 'date'
.
Alguém pode explicar isso?
time;date
vsdate;time
. Isso parece ser um problema com o pipelinebash
e o último caractere gerado com atime
saída. Os resultados testados em diferentes emuladores de terminal são: - [Bash] $ date; time # [OK] $ time; date # [ NotOK ] bash: erro de sintaxe próximo ao token inesperado `date '$ time # apenas o erro não parece ser o resultado de qualquer data. - [Csh] $ data; hora # [OK] $ hora; data # [OK] - [Tcsh] $ data; hora # [OK] $ hora; data # [OK] - [Ksh] $ data; hora # [ OK] $ time; date # [OK]Respostas:
O
time
comando no seu pipeline não é o/usr/bin/time
binário, mas o bashtime
embutido. Compareman time
comhelp time
. O erro que você vê é o bash falhando ao analisartime
o argumento. Isso deve estar presente ou ser uma nova linha. É uma nova linha no seu primeiro exemplo, mas ausente no segundo.Por outro lado, se você fosse correr
ou
onde as aspas ao redor
'time'
revogam seu status como uma palavra reservada, o bash não tem problemas ao analisar a linha. Agora ele analisa três comandos em uma lista, os quais serão executados em sequência e,/usr/bin/time
em ambos os casos , reportará um erro de uso.Termo aditivo
Observou-se que, embora
time ; date
produza um erro,time ; ; date
não. A explicação provável é quetime ;
é interpretado pelo bash como equivalente atime <newline>
. A expressãotime ; ; date
é então analisada como a lista detime ;
edate
.Isso é consistente com a observação de que
time ;
e tambémtime ; ;
é legal, sendo o segundo analisado como a lista de singleton contendotime ;
seguida pelo ponto-e-vírgula opcional permitido após as listas.Portanto, outra maneira de explicar por que
time ; date
o errobash: syntax error near unexpected token 'date'
ocorre é quetime
consome o ponto e vírgula que o separadate
. Só pode fazer isso porquetime
é uma palavra reservada do bash.fonte
time
deve permitir um comando NULL e o ponto e vírgula deve delimitar as listas, portanto, o IMOtime
não deve "consumir" o ponto e vírgula após ele. Outros comandos internos (que podem receber argumentos) não exibem esse tipo de comportamento.time;date
fato, está sintaticamente errado em qualquer interpretação. No entanto,time ;
etime ; ;
também seria ilegal. Pode-se debater setime
o comportamento é um bug ou apenas não documentado ( é consistente internamente), mas um relatório de bug definitivamente estaria em vigor. Você gostaria de arquivá-lo?time by itself can time a null command
e depois o faz$$ = make_simple_command (x, (COMMAND *)NULL);
. Quanto a registrar um bug, não tenho certeza. 8)time ; date
obras emksh93
emksh
sem erros, mesmo que emksh
hátime
palavras-chave.O Bash trata o interno
time
como um caso especial ao analisar linhas de comando.Como pode ser lido na página de manual do bash, a linha digitada é primeiro dividida em uma lista:
onde um pipeline é:
ou no nosso caso, simplesmente:
ou seja, se o tempo estiver presente, o comando também deverá estar presente.
[Há um caso especial que permite
time
ser seguido por uma nova linha, mas que não se aplica aqui]Então, no nosso caso, temos:
sendo dividido em dois pipelines:
e o pipeline 1 não está bem formado, pois temos
time
sem um comando. Daí o erro.Observe que a linha de comando
time
também não funciona aqui:bash analisa isso conforme o esperado, em 2 pipelines:
e
/usr/bin/time
depois se recusa a executar sem nenhum argumento. Observe que este é um erro e/usr/bin/time
não um erro do bash.O motivo pelo qual o back-tick funciona é que o back-tick deixa de
time
ser interpretado como um elemento especial dentro do pipeline.ou seja, com o back-tick:
é analisado como dois pipelines:
Lembre-se de que um pipeline, no nosso caso, é:
e o problema inicialmente era que tínhamos
time
sem comando, o que não é permitido. Mas agora simplesmente temos o comando:sem o anterior
time
, pois os back-ticks significam quetime
é interpretado como o comando, não como uma palavra anterior.Então, o bash executa seu built
time
-in sem argumentos, o que é aceito. Não produz saída e não vemos erro.Observe que:
realmente executa o resultado do
time
built-in, ou seja, executa o que otime
built-in produz no stdout. Mas como,time
por si só, não escreve nada para o stdout, parece funcionar.Por fim, observou-se que isso funciona:
o que não posso explicar, infelizmente :)
fonte
;date
dábash: syntax error near unexpected token ;
, mastime ;date
dábash: syntax error near unexpected token date
, então parece que o bash não trata o comando após o tempo incorporado como "; data". Curiosamente,time ; ; date
funciona.'time'
, perde seu significado como uma palavra reservada. Fazendo backticking, ele é executado em um subshell cuja saída é unida ao comando. Isso não tem nada a ver com a discussão. De fato, seu exemplo`time\';date
prova o contrário de sua afirmação: isso deve gerar um erro no seu raciocínio, pois/usr/bin/time
requer um argumento. A razão pela qual isso não ocorre é porque, no subshell em que é executado, é a palavra reservadatime
mais uma vez.