News for hackers. Stuff that matters.
Re:/usr/bin/time: not the command you think you know by jimrandomh on Monday March 06, 2017 @10:29PM (#13808054)
The reason 'time' is a builtin is because it can time a complete shell pipeline, not just a single command. If you type

    time foo |bar
Then the result is the total time taken by foo and bar together. This requires it to have special-case syntax. Whereas

    /usr/bin/time foo |bar
Would run foo and give its time statistics as input to bar.
Re:/usr/bin/time: not the command you think you know by jcoffland on Tuesday March 07, 2017 @02:16AM (#13808814)
Run these commands for a better demonstration:

    time echo | sleep 1
vs.

    /usr/bin/time echo | sleep 1
The former times the entire pipeline whereas the later only times the first command in the pipe.
Re:/usr/bin/time: not the command you think you know by fnord123 on Tuesday March 07, 2017 @05:09AM (#13809386)
This also gives the time of the entire pipeline (since the commands all begin together and only finish when the last command has completed):

echo | /usr/bin/time sleep 1

Re:/usr/bin/time: not the command you think you know by roblabla on Tuesday March 07, 2017 @07:31AM (#13809850)
I'm pretty sure this is wrong.

As an example :

sleep 2 | /usr/bin/time sleep 1

This gives an output of "1 second" even though the entire pipeline took 2 seconds.

Re:/usr/bin/time: not the command you think you know by fnord123 on Tuesday March 07, 2017 @08:15AM (#13810037)
Ok you can wangle your way out of it. But if you're doing something like `grep "$something" | /usr/bin/time some_job` then generally you're fine.
Re:/usr/bin/time: not the command you think you know by perennate on Tuesday March 07, 2017 @08:46AM (#13810227)
Wouldn't the system/user time be wrong though?
Re:/usr/bin/time: not the command you think you know by exprA on Tuesday March 07, 2017 @08:06AM (#13809997)
The sleep sub-process of time is not part of the pipeline, however. It will exit after the requested time has passed.
Re:/usr/bin/time: not the command you think you know by ramshorns on Monday March 06, 2017 @11:29PM (#13808292)
It looks like

  /usr/bin/time foo |bar
would actually give the output of foo as input to bar, since the time statistics go to stderr.
Re:/usr/bin/time: not the command you think you know by dotancohen on Tuesday March 07, 2017 @01:42AM (#13808704)
Since it is not an error, what we really need is a stdmeta file descriptor:

http://unix.stackexchange.com/questions/197809/propose-addit...

Re:/usr/bin/time: not the command you think you know by eriknstr on Tuesday March 07, 2017 @05:08AM (#13809383)
I've been thinking a bit about this before and I think that not just one but a whole lot of additional streams would be useful. By default all commands would still use stdout and stderr only but you would be able to tell them to use other streams as well for their various data.

Furthermore, each stream should be possible to pipe to a different process if you wish independently of the other streams.

To a small degree this might be possible already with named pipes.

Re:/usr/bin/time: not the command you think you know by ncw33 on Tuesday March 07, 2017 @09:03AM (#13810340)
It is possible already - you can do `command 2>&4` to separate the output from one command in a pipeline into its own stream, then do `command2 <&4` to pull from the further down the pipeline.
Re:/usr/bin/time: not the command you think you know by eriknstr on Tuesday March 07, 2017 @10:54PM (#13817752)
I would like more pipes for each process.

This would allow many things, for example searching for multiple terms across all files in the whole file system in one go without opening each file more than once, and then grouping the different results together in accordance with the term that they matched.

Re:/usr/bin/time: not the command you think you know by Klathmon on Tuesday March 07, 2017 @07:29AM (#13809839)
Honestly this is one area where PowerShell kind of nailed it.

I still don't use it enough, but when it comes to scripting PS's objects beat the hell out of these

Re:/usr/bin/time: not the command you think you know by MrQuincle on Tuesday March 07, 2017 @05:36AM (#13809476)
I just started playing around with IPC ideas with processes tellin each other which flags they would like: https://github.com/mrquincle/bipipes

I think socket pairs would be great for it.

Nothing implemented yet!

Re:/usr/bin/time: not the command you think you know by easytiger on Tuesday March 07, 2017 @03:42AM (#13809095)
Just think of it as std dbg, not err
Re:/usr/bin/time: not the command you think you know by Merovius on Tuesday March 07, 2017 @11:18AM (#13811569)
No, it wouldn't require special-case syntax. It could just pass it's argument to '/bin/sh -c'. You'd have to shell-escape the pipeline, though.
Re:/usr/bin/time: not the command you think you know by eridius on Tuesday March 07, 2017 @04:50PM (#13815325)
Yeah it does require special-case syntax. When using bash's built-in time, the command is executed exactly the same way as if you weren't using time, which means the command can set variables or define functions in the current shell. For example, you can say

  time foo=bar
  echo $foo
and it will correctly print out "bar". It can't do this if it executes the command in a subshell. Or similarly you can say `time cd /foo` and it will actually change the current working directory.
Re:/usr/bin/time: not the command you think you know by chubot on Monday March 06, 2017 @11:00PM (#13808165)
Yes, as a consequence, it also lets you do this:

    time {
      sleep 0.1
      sleep 0.2
    }
    # result is 0.3 seconds
 
which you obviously can't do with an external command. I wrote about that here:

https://lobste.rs/s/hwgt2h/usr_bin_time_not_command_you_thin...

Re:/usr/bin/time: not the command you think you know by arthur2e5 on Monday March 06, 2017 @11:35PM (#13808305)
The `time` syntax in combination with for loops or just shell functions is pretty useful as well.
Re:/usr/bin/time: not the command you think you know by jstimpfle on Tuesday March 07, 2017 @04:10AM (#13809189)
That is merely an optimization though. You can simply

    time sh -c 'foo | bar'
Re:/usr/bin/time: not the command you think you know by therein on Tuesday March 07, 2017 @04:35AM (#13809273)
But now you are timing the startup of `sh` as well.
Re:/usr/bin/time: not the command you think you know by aexaey on Tuesday March 07, 2017 @06:50AM (#13809711)
...which (surprisingly) is a measurable amount. About 1 ms for `dash` and a whooping 9.5 ms for `bash` on a relatively slow CPU:

  pi@pi:~ $ time (for x in {1..1000}; do time echo | sleep 0.01; done 2>/dev/null)
  real    0m24.173s

  pi@pi:~ $ time (for x in {1..1000}; do time sh -c 'echo | sleep 0.01'; done 2>/dev/null)
  real    0m25.170s

  pi@pi:~ $ time (for x in {1..1000}; do time bash -c 'echo | sleep 0.01'; done 2>/dev/null)
  real    0m33.643s
Re:/usr/bin/time: not the command you think you know by jstimpfle on Tuesday March 07, 2017 @11:50AM (#13811946)
1ms is on the order of process creation time, so not very relevant: The measured program itself requires process creation. Most programs run considerably longer than that (otherwise timing would not make much sense).

It's really not more than that: an optimization.

Re:/usr/bin/time: not the command you think you know by floatboth on Tuesday March 07, 2017 @12:02PM (#13812100)
Wow — that is extremely surprising. I did not expect that behavior at all. Who the hell thought it was a good idea to let a builtin command absorb the pipe symbol?!
Re:/usr/bin/time: not the command you think you know by inetknght on Tuesday March 07, 2017 @11:08AM (#13811482)
`/usr/bin/time -o foo_time.txt foo | bar`
Re:/usr/bin/time: not the command you think you know by graton on Tuesday March 07, 2017 @12:11AM (#13808414)
On bash you can do this to have it not use an alias or built-in command:

  $ \time echo

  0.00user 0.00system 0:00.00elapsed 100%CPU (0avgtext+0avgdata 1764maxresident)k
  0inputs+0outputs (0major+66minor)pagefaults 0swaps
The built-in version:

  $ time echo


  real    0m0.000s
  user    0m0.000s
  sys     0m0.000s
Re:/usr/bin/time: not the command you think you know by yrro on Tuesday March 07, 2017 @05:49AM (#13809503)
Is this behaviour documented anywhere? The closest I can find is https://www.gnu.org/software/bash/manual/bashref.html#Aliase... which remarks,

> The first word of each simple command, if unquoted, is checked to see if it has an alias.

I observe that t\ime works just as well as \time.

Re:/usr/bin/time: not the command you think you know by ptx on Tuesday March 07, 2017 @06:55AM (#13809729)
Just quoting it normally also works, apparently, as your excerpt from the man page suggests:

  $ help|head -1
  GNU bash, version 4.3.30(1)-release (x86_64-pc-linux-gnu)
  $ "time" --version
  GNU time 1.7
  $ time --version
  bash: --version: command not found
  
  real	0m0.001s
  user	0m0.000s
  sys	0m0.000s
Re:/usr/bin/time: not the command you think you know by sigjuice on Tuesday March 07, 2017 @10:31AM (#13811048)
t\ime is rather surprising. Is there any documentation or explanation on why it does what it does?
Re:/usr/bin/time: not the command you think you know by yrro on Tuesday March 07, 2017 @06:42PM (#13816381)
https://www.gnu.org/software/bash/manual/bashref.html#Escape...

I think it's because using the backslash to escape counts as quoting. So the following are all equivalent:

  $ \time foo
  $ t\ime foo
  $ 'time' foo
Re:/usr/bin/time: not the command you think you know by bobbyi_settv on Tuesday March 07, 2017 @11:08AM (#13811485)
The conventional way of forcing bash not to use a built-in is by using the full path (/usr/bin/time in this case).
Re:/usr/bin/time: not the command you think you know by eridius on Tuesday March 07, 2017 @04:52PM (#13815342)
The more obvious way of doing this is

  command time echo
The usage of the `command` keyword makes it ignore shell functions (including built-in shell keywords like time).
Re:/usr/bin/time: not the command you think you know by dredmorbius on Monday March 06, 2017 @11:09PM (#13808208)
Since the article doesn't clarify on shell command priority, commands are search in order:

1. Alias expansion.

2. Defined shell functions.

3. Built-in shell functions.

4. Command path.

If you provide an unqualified command that matches more than one of these elements, the first match wins.

Prepending a backstroke: "\command", will inhibit alias expansion. E.g.:

    alias date="echo no date"
    date
    \date
Should return "no date", and your current system date, respectively.

To invoke a system command directly, call the full path. If you don't feel like running the fish shell (not that there's anything wrong with that).

Some simple shells (e.g., dash, and IIRC the original Bourne shell, though that is not what you'll find as /bin/sh on most modern systems) don't include a time builtin, and can invoke the system time command directly.

Re:/usr/bin/time: not the command you think you know by yrro on Tuesday March 07, 2017 @05:52AM (#13809517)
You can also use the 'command' built-in to skip aliases and shell functions.

$ command time --version GNU time 1.7

Re:/usr/bin/time: not the command you think you know by knome on Tuesday March 07, 2017 @07:42AM (#13809893)
Perhaps, but time is a syntactic form, like `if` or `case`.

https://www.gnu.org/software/bash/manual/html_node/Pipelines...

Re:/usr/bin/time: not the command you think you know by dredmorbius on Tuesday March 07, 2017 @02:33PM (#13813851)
I'm sorry, that's not clear to me. What's the significance exactly?
Re:/usr/bin/time: not the command you think you know by knome on Tuesday March 07, 2017 @11:19PM (#13817860)
A command takes a series of arguments, stdin/out/err pipes and returns an error code on completion.

time prefixes a pipeline ( the most basic case being a single command without a pipe into another ), a command block { ... } a subshell block ( ... ), a for statement, an if statement, just whatever really.

This "time" would output how long "a" took to run:

    /usr/bin/time a b c | { d e ; f g ; } | h i ;
This "time" outputs how long the pipeline "a", "d", "f", and "h" took to run:

    time a b c | { d e ; f g ; } | h i ; 
This is a syntax error:

    /usr/bin/time { d e ; f g ; }
This returns how long the command group takes to run:

    time { d e ; f g ; }
Further examples:

    $ time sleep 10 | sleep 1 ;
    
    real	0m10.073s
    user	0m0.000s
    sys	0m0.000s
    $ time sleep 1 | sleep 10 ;
    
    real	0m10.003s
    user	0m0.000s
    sys	0m0.000s
    $ /usr/bin/time sleep 10 | sleep 1 ;
    0.00user 0.00system 0:10.00elapsed 0%CPU (0avgtext+0avgdata 1796maxresident)k
    0inputs+0outputs (0major+80minor)pagefaults 0swaps
    $ 
    $ /usr/bin/time sleep 1 | sleep 10 ;
    0.00user 0.00system 0:01.00elapsed 0%CPU (0avgtext+0avgdata 1808maxresident)k
    0inputs+0outputs (0major+82minor)pagefaults 0swaps
Note the two /usr/bin/time's output their timing information as soon as the first command is done, but the pipeline doesn't return until both commands have exited.

> hope this rant helps in some way

Re:/usr/bin/time: not the command you think you know by dredmorbius on Wednesday March 08, 2017 @06:04PM (#13824819)
Thanks, that does raise some interesting points.

What of:

    /usr/bin/time ( sleep 1 | sleep 10 )
Explicitly invvoking a subshell. Which I understand the builtin to be doing.
Re:/usr/bin/time: not the command you think you know by metafunctor on Tuesday March 07, 2017 @05:55AM (#13809527)
A more interesting command is /bin/[.

Yep, it's the same as /bin/test, but basically requires the last argument to be a ]. Typically /bin/test and bin/[ are hard links, that is, they are physically the same file and share the same inode(s).

You know, so you can type

  if [ $foo = $bar ]; then
    yes
  else
    exit
  fi
This actually runs the command /bin/[, except most of the time it doesn't, because it's built-in to the shell.

As as side-note, an article like this should at least mention which OS and shell the author is using.

Re:/usr/bin/time: not the command you think you know by Elrac on Tuesday March 07, 2017 @06:27AM (#13809625)
> As as side-note, an article like this should at least mention which OS and shell the author is using.

Very much agree! I just tried this on my 2.6.32 RHEL system, and it's never heard of "-l". It outputs very similar-looking information as in the article, though, when given "-v" .

Re:/usr/bin/time: not the command you think you know by halostatue on Monday March 06, 2017 @11:07PM (#13808192)
In both bash and zsh, you can force the shell to use $PATH for lookup (bypassing functions and shell builtins) by calling a builtin name with 'command' ('command time -l ls'). You can equivalently force a builtin with 'builtin', but that does not work with reserved words (and 'time' is a shell reserved word).
Re:/usr/bin/time: not the command you think you know by ramshorns on Tuesday March 07, 2017 @02:01AM (#13808772)
TIL that a shell reserved word is different from a shell builtin.

http://unix.stackexchange.com/questions/267761/differences-b...

Re:/usr/bin/time: not the command you think you know by xelxebar on Tuesday March 07, 2017 @10:07PM (#13817535)
Yeah. Shell semantics can be pretty unintuitive sometimes. I often find it helpful to translate these ideas to standard programming language terms.

* Commands are like functions * Commands in /bin etc. are like library functions * Builtins are like a language's primitive functions * Keywords are keywords

Re:/usr/bin/time: not the command you think you know by halostatue on Tuesday March 07, 2017 @11:05AM (#13811437)
Me, too. I was surprised because I was trying to use `builtin time`. :)
Re:/usr/bin/time: not the command you think you know by LeoPanthera on Tuesday March 07, 2017 @12:26PM (#13812419)
You can also just prefix the command with a backslash. "\time" will run the version in the path.
Re:/usr/bin/time: not the command you think you know by hobarrera on Monday March 06, 2017 @10:26PM (#13808042)

    $ which time
    time: shell reserved word
    $ ls /usr/bin/time /bin/time
    ls: cannot access '/usr/bin/time': No such file or directory
    ls: cannot access '/bin/time': No such file or directory
Looks like something specific to the author's distribution.
Re:/usr/bin/time: not the command you think you know by dredmorbius on Monday March 06, 2017 @11:11PM (#13808215)
On my Android system with Termux installed, the system 'time' is the Busybox implementation, so yes, YMMV.

Which gives new meaning to the relativity and vagueries of time....

Re:/usr/bin/time: not the command you think you know by kylek on Monday March 06, 2017 @11:00PM (#13808168)
Exists on a debian(/testing?) system I've:

$ time ls / bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

real 0m0.004s

user 0m0.000s

sys 0m0.000s

$ /usr/bin/time ls /

bin boot dev etc home lib lib64 lost+found media mnt opt proc root run sbin srv sys tmp usr var

0.00user 0.00system 0:00.00elapsed 0%CPU (0avgtext+0avgdata 2304maxresident)k

0inputs+0outputs (0major+109minor)pagefaults 0swaps

Edit: formatting

Re:/usr/bin/time: not the command you think you know by kevinoid on Monday March 06, 2017 @11:06PM (#13808190)
Sometimes. It depends whether you have the time[1] package installed.

1. https://packages.debian.org/sid/time

Re:/usr/bin/time: not the command you think you know by ams6110 on Monday March 06, 2017 @10:51PM (#13808132)
It's a BSD thing.
Re:/usr/bin/time: not the command you think you know by ramshorns on Monday March 06, 2017 @11:35PM (#13808302)
There's a GNU time as well, but it appears not to always be installed by default.
Re:/usr/bin/time: not the command you think you know by voltagex_ on Tuesday March 07, 2017 @12:10AM (#13808412)
Re:/usr/bin/time: not the command you think you know by myrandomcomment on Monday March 06, 2017 @10:31PM (#13808070)
He is on MacOS.
Re:/usr/bin/time: not the command you think you know by pmontra on Tuesday March 07, 2017 @03:12AM (#13808983)
It's time -l on BSD derivatives and time -v on GNU userlands.
Re:/usr/bin/time: not the command you think you know by 7171u on Tuesday March 07, 2017 @02:33AM (#13808863)
I had to use "--verbose" instead of "-l" in my RHEL7

  \time --verbose  echo
Re:/usr/bin/time: not the command you think you know by aij on Tuesday March 07, 2017 @11:04AM (#13811427)
I bet you're using GNU time rather than BSD time.

It did seem odd to me that the author didn't bother to mention which OS he is using, though from the hostname I have a pretty good guess.

Re:/usr/bin/time: not the command you think you know by lucb1e on Tuesday March 07, 2017 @03:28AM (#13809047)
Same on Debian Stretch
Re:/usr/bin/time: not the command you think you know by ffjffsfr on Tuesday March 07, 2017 @03:27AM (#13809038)
same on my ubuntu
Re:/usr/bin/time: not the command you think you know by brendangregg on Monday March 06, 2017 @10:33PM (#13808078)
No, /usr/bin/time is indeed what I know, and its extended stats is why I suggested using it in my last perf book (time -v).

"/usr/bin/time: not the command you think you know" -> "/usr/bin/time: may not be the command you think you know"

There, I fixed the title.

Re:/usr/bin/time: not the command you think you know by inopinatus on Tuesday March 07, 2017 @12:32AM (#13808467)
Or even "may not be the command I think you know".
Re:/usr/bin/time: not the command you think you know by an_account on Monday March 06, 2017 @11:48PM (#13808342)
/r/iamverysmart
Re:/usr/bin/time: not the command you think you know by d4l3k on Monday March 06, 2017 @10:15PM (#13808004)
/usr/bin/time doesn't seem to be a thing on my Arch Linux install. ¯\_(ツ)_/¯
Re:/usr/bin/time: not the command you think you know by fbernier on Monday March 06, 2017 @10:18PM (#13808013)
Same here. I had to fetch it via pacman. Also, the -l option doesn't exist on the non-bsd version.
Re:/usr/bin/time: not the command you think you know by tomsmeding on Tuesday March 07, 2017 @02:13AM (#13808801)
I love arch. Sudo doesn't exist until you install it (directly or indirectly).
Re:/usr/bin/time: not the command you think you know by jcoffland on Tuesday March 07, 2017 @02:18AM (#13808818)
That's the same on Debian.
Re:/usr/bin/time: not the command you think you know by ajsalminen on Tuesday March 07, 2017 @06:06AM (#13809561)
Yeah, I don't think it's all that rare for sudo to be an optional package not installed by default in distributions. At least that used to be the case back when I used try various ones a lot more.
Re:/usr/bin/time: not the command you think you know by wkz on Tuesday March 07, 2017 @02:12AM (#13808797)
`-v` (--verbose) Seems to give the same (although differently formatted) output on GNU's implementation.
Re:/usr/bin/time: not the command you think you know by majewsky on Tuesday March 07, 2017 @05:47AM (#13809499)

  $ pacman -Fo /usr/bin/time
  usr/bin/time is owned by extra/time 1.7-8
If that command doesn't work for you, try adding "-y". `man pacman` for details.
Re:/usr/bin/time: not the command you think you know by devnonymous on Tuesday March 07, 2017 @10:11AM (#13810866)
So also are /usr/bin/{cd,[,echo,pwd,fg,..etc} a lot of them having subtle differences with their corresponding shell builtins. Most of the time the differences are not worth the hassle to remember, unless you somehow end up on a system with a broken filesystem (for example where /lib or /usr/lib is destroyed) and need to rescue stuff.
Re:/usr/bin/time: not the command you think you know by cmurf on Tuesday March 07, 2017 @10:15AM (#13810903)
On Fedora Linux, '/usr/bin/time -v <command>' rather than -l.
Re:/usr/bin/time: not the command you think you know by saagarjha on Tuesday March 07, 2017 @12:39AM (#13808498)
So it's just like /usr/bin/cd–a builtin that also has a binary.
Re:/usr/bin/time: not the command you think you know by tyingq on Tuesday March 07, 2017 @01:09AM (#13808601)
How would that work? A forked/execed subprocess somehow forcing chdir() in it's parent?

Guessing it isn't terribly useful.

Re:/usr/bin/time: not the command you think you know by cperciva on Tuesday March 07, 2017 @01:37PM (#13813226)
Guessing it isn't terribly useful.

You guess correctly. The issue is that POSIX states that

    ... all of the standard utilities [...] shall be implemented in a manner
    so that they can be accessed via the exec family of functions as defined
    in the System Interfaces volume of POSIX.1-2008 and can be invoked
    directly by those standard utilities that require it (env, find, nice,
    nohup, time, xargs).
Note however that /usr/bin/cd isn't completely useless: It has the same diagnostics (error message and exit code) as the command, so `env cd $FOO` is a way to check if you can change to that directory without actually doing it.
Re:/usr/bin/time: not the command you think you know by zwp on Tuesday March 07, 2017 @03:09AM (#13808973)
I too don't see how it is useful but it's certainly a thing. The Solaris implementation looks like this:

    #!/bin/ksh -p
    # ...
    cmd=`basename $0`
    $cmd "$@"
I just noticed that the what(1)-string (I haven't seen on of those for a long time) references "alias.sh", perhaps this is a clue?

    #ident  "@(#)alias.sh   1.2     00/02/15 SMI"
Were builtins actually aliases in an early shell? I still don't understand how this works though.
Re:/usr/bin/time: not the command you think you know by tyingq on Tuesday March 07, 2017 @08:29AM (#13810103)
That's a funny implementation. It would end up being an infinite loop for any command that wasn't a builtin, or didn't have an identically named thing higher up the PATH. Like if you renamed it from /usr/bin/cd to /usr/bin/mycd.
Re:/usr/bin/time: not the command you think you know by saagarjha on Tuesday March 07, 2017 @11:12AM (#13811522)
On my Mac, it's

  #!/bin/sh
  # $FreeBSD: src/usr.bin/alias/generic.sh,v 1.2 2005/10/24 22:32:19 cperciva Exp $
  # This file is in the public domain.
  builtin `echo ${0##*/} | tr \[:upper:] \[:lower:]` ${1+"$@"}