3 ms·
true once was, and IMO should be again, implemented as a 0 bytes executable. Since then, it has infinitely bloated on most systems. It actually began at AT&T,
by temac 8y ago
true once was, and IMO should be again, implemented as a 0 bytes executable.
Since then, it has infinitely bloated on most systems.
It actually began at AT&T, where they apparently decided to copyright the trueness. From there it went downhill, ever and ever.
http://trillian.mit.edu/~jc/humor/ATT_Copyright_true.html http://trillian.mit.edu/~jc/humor/ATT_Copyright_true.html
- gizmo686 8y agoDoesn't the 0 byte executable involve spawning a shell to run it? Better would be a tiny elf executable that just returns 0 (maybe hand written to avoid the compiler adding bloat)
- pcwalton 8y agoCorrect. true being a 0 byte shell script is a good example of classic Unix's bad habit of doing the overly-cute thing instead of the sensible thing.
- temac 8y agoIt would be a valid approach but it is less elegant and harder to maintain. Probably the kernel could special case 0 bytes executables, if you really want to optimize the scripted truth.
- gizmo686 8y agoIf you want maintainable, you should just compile "return 0" with your standard toolchain. A 0 byte file risks confusing developers who might see it and think their install is corrupted (surely the program just got truncated). If you want to use an empty program, the maintainable solution would be to comment it; but then it is not empty.
- anyfoo 8y agoSpecial casing 0-byte executables is not necessarily the best solution, either. It's a special case after all, and one that's essentially only there to support /bin/true. This may create security gotchas or inadvertent bugs resulting from the "codeless" address space that gets created (or not created if you implement it that way, with its own set of potential gotchas). I'm not saying it necessarily does create problems, but it can.
- temac 8y agoAnd it would actually change the historical and current behavior of exec returning ENOEXEC for 0 bytes executables (see also https://news.ycombinator.com/item?id=19081124 https://news.ycombinator.com/item?id=19081124 ) . So I am changing my mind: a binary true is better. I still prefer truths as small as possible, though :)
- burfog 8y agoIt can be an extra-special 0-byte executable though, running far faster than anything else, like so: /proc/bin/true /proc/bin/false The exec doesn't even need to create page tables or run any non-kernel code. This is a benchmark-winning design.
- aidenn0 8y agoNo it does not. The 0 byte executable involves first trying to execl() it, the OS returning ENOEXEC, and then spawning a shell. Of course "spawning a shell" can be very cheap, as you are already in a shell, it's just fork() plus some initialization code (compared to fork() plus exec() for running a non-shell program) Note that shells must try to interpret at least any text file for which the system returns ENOEXEC [1] 1: http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3_chap02.html#tag_18_09_01_01 http://pubs.opengroup.org/onlinepubs/9699919799/utilities/V3... Read subsection 1.e.i.b
- gizmo686 8y agoDoes this mean that putting #!/bin/sh at the head of scripts actually slows them down (assuming you are running from an sh like shell)?
- svnpenn 8y agohttps://stackoverflow.com/questions/25165808 https://stackoverflow.com/questions/25165808
- aidenn0 8y agoI suggest measuring; there's overhead to the failed exec() call certainly. It probably depends on a lot of other factors too (which, if any rc files are read in each mode, how fast your shell is to startup &c.).
- gizmo686 8y agoI just tested this. Files: 1.sh: true 2.sh: #!/bin/bash true test1.sh: for i in `seq 10000` do ./1.sh done test2.sh: for i in `seq 10000` do ./2.sh done Times for test1.sh: 11.484s 11.590s 11.405s Times for test2.sh: 14.273s 14.391s 13.847s So including the #! adds about 23% to the overhead of calling a shell script. Tested on Mint 19.1, bash. EDIT: for reference, sourcing the scripts instead takes an average of 0.0842s for test1 and 0897s for test2. (and all test2 trials were still slower than all test1 trials), which isn't particuarly suprising. Inlining true takes about 0.029s