5

When I use the shell builtin time, I can pass any command I would pass to the shell without time. But when I use the external /usr/bin/time, I cannot pass a shell alias, because /usr/bin/time is naturally not aware of those:

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

How can I convince the shell to expand the alias for ll before passing it on to /usr/bin/time? Parsing the output of alias ll is tricky, in particular since the definition of the alias contains other aliases.


My reason for using /usr/bin/time is to measure peak memory usage.

2

You can define an alias for /usr/bin/time as:

alias 'ubtime=/usr/bin/time '

Or

alias 'ubtime=command time '

if you don't want to hard code the path to the time executable.

The trick is in the trailing space in the alias definition that tells the shell that aliases must be substituted after that alias so that

ubtime ll

Will actually be expanded to

/usr/bin/time ls -l

(assuming ll is an alias to ls -l).

In any case, /usr/bin/time being a standalone executable, it cannot time pipelines or compound commands or functions or shell builtins, so it cannot time the expansion of arbitrary aliases.

If the reason for using /usr/bin/time is because you prefer its default output format over the one for the time keywork, note that in many shells, the format can be modified. For instance, in zsh:

$ TIMEFMT=$'\e[31;1m%J\e[m: U:%U S:%S (%*E total) [avgtext:%X avgdata:%D maxmem:%M]'
$ time ls -l | head -n1
total 288072444
ls -l: U:0.00s S:0.01s (0.017 total) [avgtext:0 avgdata:0 maxmem:3]
head -n1: U:0.00s S:0.00s (0.015 total) [avgtext:0 avgdata:0 maxmem:3]

(the \e[31;m for coloured (bold red) output).

  • Ah ok, this seems to work even for nested aliases, but still not if functions are involved or if the expanded alias does not start with a binary name. – rudimeier Sep 27 '16 at 14:26
  • This appears to expand a single 'layer', thus it works if ll itself does not contain other aliases. My ll alias is actually alias ll='LANG='\''en_GB.UTF8'\'' l --full-time --almost-all --reverse --sort=time --time-style='\''+%9A %Y-%m-%d %H:%M:%S'\''', and alias l='ls --format=long'. The command works for my l but not for my ll. – gerrit Sep 27 '16 at 14:28
  • @gerrit, that's because of your LANG=.... That gets expanded to /usr/bin/time LANG=... ls ... as expected (so it works), but /usr/bin/time doesn't know what to do about that LANG=.... It tries to run it as a command. – Stéphane Chazelas Sep 27 '16 at 14:37
  • Well, actually this is the correct answer to the question: "How to expand the alias before passing it on to /usr/bin/time?" Unfortunately /usr/bin/time can't work on arbitrary alias expansions at all. – rudimeier Sep 27 '16 at 14:42
  • @rudimeter, see also my edit to make the time keyword output more information like /usr/bin/time (at least the GNU one) does. – Stéphane Chazelas Sep 27 '16 at 14:45
0

This may work in bash:

/usr/bin/time  $(alias "ll" | sed "s/^alias [^=]*='\(.*\)'/\1/")

but not yet fully safe for arbitrary aliases, regarding spaces, escaped characters, nested aliases and functions etc.

I guess there is no non-ugly solution possible. That's why shells have a built-in time. Even if alias expansion would be easier, the next problem would be how to time functions. Note that aliases may even use shell functions.

If your aliases are defined in bash's configuration files and if you don't care about the timed overhead you could try

/usr/bin/time bash -l -i -c "ll"
  • This doesn't expand nested aliases; my alias ll refers to yet other aliases. I see that this is more complex than I thought. \time bash --login -c ll does not work either. – gerrit Sep 27 '16 at 13:56
  • The -i flag works where I thought --login would! I see that bash does not inherit aliases, but for my present use case it is good enough. – gerrit Sep 27 '16 at 14:02
  • -i (interactive) is required for shopt expand_aliases being enabled. --login may be required too to read all config files (~/.profile). I've added both to the answer. – rudimeier Sep 27 '16 at 14:10

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.