
$ cmd='time sleep 2'
$ $cmd
bash: time: command not found
O que está acontecendo aqui? Não é uma questão de os recursos internos do shell não funcionarem, porque isso funciona:
$ cmd2='echo wef'
$ $cmd2
wef
Alguma ideia?
Editar: encontrei uma diferença:
$ type time
time is a shell keyword
Contra:
$ type echo
echo is a shell builtin
Então a questão agora é: por que um builtin funciona em uma string e uma palavra-chave não?
Responder1
time
como umGNU Bashpalavra-chave tem um local muito específico onde é aceito, veja, por exemplo, a sintaxe para uma construção de pipeline de comando:
O formato de um pipeline é
[time [-p]] [!] command1 [| command2 ...]
Isso codifica a posição da palavra-chave fora das expansões (comocomandoNserá onde os parâmetros e variáveis serão expandidos). Na verdade, a semântica também se aplica a todo o pipeline, não ao comando, então é provavelmente por isso que deve ser uma palavra-chave.
Existe um shell embutido times
(no POSIX umespecial embutido), para isso a expansão funciona já que a primeira palavra pode ser um executável ou um shell embutido.
alternativamenteCoreutils GNU contém um /bin/time
executável.
Na verdade time
não épalavra reservadaemConcha POSIX(embora o bash o reconheça emmodo positivode qualquer maneira (a menos que -
siga por razões não óbvias)).
Dentro de uma eval
expressão, as palavras-chave são reconhecidas porfesta, portanto, isso pode ser usado para aprimorar comandos dinamicamente com perfil de tempo. (No entanto, por outro lado, requer uma rodada adicional de cotação)
Responder2
Em vez de usar cmd='time sleep 2' tente usá-lo como cmd='/usr/bin/time sleep 2' para obter o comando em tempo real.
Você pode ler o seguinte no man time:
Os usuários do shell bash precisam usar um caminho explícito para executar o comando de tempo externo e não a variante interna do shell. No sistema onde o horário está instalado em /usr/bin, o primeiro exemplo seria /usr/bin/time wc /etc/hosts