16

less complains about my value of $TERM, whereas more doesn’t. Which would be fine except for the fact that more is less.

Originally I was puzzled by tools suddenly disliking my $TERM value (I thought I configured Tmux to use tmux as $TERM a few system restarts ago), but a bigger question just entered the room: how come two byte for byte identical binaries behave differently?

❯ less
WARNING: terminal is not fully functional
Missing filename ("less --help" for help)

❯ more Missing filename ("less --help" for help)

❯ echo (which less) (which more) /usr/bin/less /usr/bin/more

❯ ls -Al /usr/bin/less -rwxr-xr-x 2 root wheel 384848 May 13 06:29 /usr/bin/less*

❯ ls -Al /usr/bin/more -rwxr-xr-x 2 root wheel 384848 May 13 06:29 /usr/bin/more*

❯ openssl dgst -sha256 /usr/bin/less SHA2-256(/usr/bin/less)= 8567f60723d396cb9c6e8d0a5f5206f321adbb2982d71e75cd6ec32be4256591

❯ openssl dgst -sha256 /usr/bin/more SHA2-256(/usr/bin/more)= 8567f60723d396cb9c6e8d0a5f5206f321adbb2982d71e75cd6ec32be4256591

❯ echo $TERM tmux

❯ tmux -V tmux 3.3a

❯ echo $SHELL /opt/local/bin/fish

This is in macOS. If it is some Mac-specific dark magic I will move this to Ask Different, of course.

1 Answers1

25

The same program can behave differently if it is being run with different parameters: in your first command it receives argv[] = {"less", NULL} as the command-line argument array, while the second one calls it with argv[] = {"more", NULL}, with the 0th item in argv always being the program's own name (the "normal" args begin at 1).

This is sometimes used to create "multi-call" programs, most famously BusyBox which provides almost the entire /bin in small systems (e.g. in your Wi-Fi router).

If the 'less' program is invoked as more, its argument array will have argv[0] == "more", which enables "POSIX more(1) compatibility" code within Less. (For example, instead of looking for additional options in the LESS environment variable it instead looks for them in MORE.)

grawity
  • 501,077