Não existe esse arquivo ou diretório ao executar / usr / bin / time

11

Estou construindo minha própria ROM Android. Para construí-lo, preciso executar

mka -j8 bacon

No entanto, eu queria medir o tempo que levou para construí-lo, então usei

/usr/bin/time -f "User\t%U\nSys\t%S\nReal\t%E\nCPU\t%P" mka -j8 bacon

Isso não vai funcionar, porque está dizendo

/usr/bin/time: cannot run mka: No such file or directory

Qualquer ajuda para contornar isso, é apreciado! Estou executando o xubuntu.

Editar:

Por alguma razão, usar make em vez de mka funciona, no entanto, usar mka é melhor.

/usr/bin/time -f "User\t%U\nSys\t%S\nReal\t%E\nCPU\t%P" make -j8 bacon

Edição 2: no site cyanogenmod

A chamada $ source build/envsetup.shou a $ . build/envsetup.shpartir do seu shell executa o script envsetup.sh no diretório de construção. O envsetup.sh adiciona muitas funções ao ambiente de construção, as mais importantes listadas abaixo.

source build/evnsetup.shé o comando que eu executo antes da hora de executar. Uma dessas funções adicionadas pelo evnsetup.sh é mka: é possível chamar isso de dentro do timecomando?

Edit 3: Saída do tipo mka

$ type mka
mka is a function
mka () 
{ 
    case `uname -s` in 
        Darwin)
            make -j `sysctl hw.ncpu|cut -d" " -f2` "$@"
        ;;
        *)
            schedtool -B -n 1 -e ionice -n 1 make -j$(cat /proc/cpuinfo | grep "^processor" | wc -l) "$@"
        ;;
    esac
}
P1nGu1n
fonte
Você tentou colocar todo o caminho do mka (algo como / usr / bin / mka)?
desgua
O problema é que o evnsetup.sh inicializa algumas coisas. No terminal, tenho que executar esse arquivo antes de poder chamar mka. Aparentemente, não é reconhecido ao chamá-lo como um parâmetro do comando time.
P1nGu1n
Como posso reproduzir isso?
Braiam
Depois de executar o seu source build/evnsetup.sh, no ponto em que deseja chamar time mka -j8 bacon, você pode postar a saída do comando type mka?
Malte Skoruppa
@MalteSkoruppa output added, mka parece ser uma função bash?
P1nGu1n

Respostas:

11

O problema é que mkaé uma função bash exportada pelo seu script e não um executável (ao contrário de make), portanto /usr/bin/time, não o encontra, pois procura um executável.

Há duas soluções possíveis.

Primeiro, observe que há uma diferença entre a função interna do bash timee o executável /usr/bin/time. Estes são comandos diferentes, que usam parâmetros diferentes e geram saídas diferentes:

$ time sleep 1

real    0m1.001s
user    0m0.000s
sys     0m0.001s

$ /usr/bin/time sleep 1
0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 664maxresident)k
0inputs+0outputs (0major+215minor)pagefaults 0swaps

Digite help timepara obter ajuda para o bash embutido time. Digite man timepara obter ajuda para o executável /usr/bin/time.

A primeira solução usa time, enquanto a segunda solução usa /usr/bin/time.

Primeira solução: usando a função interna do bash time

A função timeinterna do bash reconhece as funções declaradas do bash e você pode usá-lo imediatamente para medir o tempo de tais funções.

$ foo() {
    sleep 1;
    echo "Hello World"
  }
$ time foo
Hello World

real    0m1.002s
user    0m0.000s
sys     0m0.001s

No seu caso, o seguinte comando deve funcionar:

$ time mka -j8 bacon

Este seria o meu caminho preferido. No entanto, pode não gerar exatamente a saída desejada. Em particular, ele não mede ou imprime o uso da CPU.

Segunda solução: usando o executável /usr/bin/time

Você não pode medir diretamente o tempo de uma função bash interna usando /usr/bin/time(até onde eu sei), mas o que você pode fazer é medir o tempo do /bin/bashexecutável executando essa função bash. Isso é um pouco hacky e gera um pouco de sobrecarga quando você inicia uma instância extra do bash. Mas essa sobrecarga pode ser insignificante quando confrontada com uma função que leva alguns minutos para ser calculada, por isso ainda pode atender melhor às suas necessidades.

Para poder iniciar o /bin/bashexecutável em uma função bash, precisamos exportar a função primeiro.

$ foo() {
    sleep 1;
    echo "Hello World"
  }
$ export -f foo
$ echo foo | /usr/bin/time /bin/bash
Hello World
0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1476maxresident)k
0inputs+0outputs (0major+707minor)pagefaults 0swaps

Portanto, no seu caso, para poder usar /usr/bin/timee gerar o formato de saída desejado, você pode proceder da seguinte maneira:

$ export -f mka
$ echo 'mka -j8 bacon' | /usr/bin/time -f "User\t%U\nSys\t%S\nReal\t%E\nCPU\t%P" /bin/bash
Malte Skoruppa
fonte
Obrigado, eu realmente entendo por que não estava funcionando! Duas perguntas curtas, qual é o -fparâmetro, não consegui encontrar isso. Segundo, o que / bin / bash? Realmente aprecio isso!
P1nGu1n
11
O -fparâmetro para exportinforma exportpara exportar uma função shell. Veja help export. O -fparâmetro to /usr/bin/timediz /usr/bin/timepara esperar uma string de formato, mas presumo que você saiba. A /bin/bashparte do último comando é o executável bash, cujo tempo de execução é realmente medido, quando ele próprio executa a mkafunção exportada . Ele executa a mkafunção porque lê e executa o mka -j8 baconcomando a partir da entrada padrão, e é por isso que usamos echoum canal. Desculpe pela resposta tardia, basta ler isso. :)
Malte Skoruppa