If I want to view root's bash history, why can I not just run sudo history? when I do it says command history not found, but if I run it without the sudo it runs fine.

Edit: it's a duplicate answer, but not a duplicate question to the one linked. The person asking either question will not know that it's a shell builtin command as opposed to a binary.


Solution 1:

history is a bash shell builtin command, and sudo doesn't work with shell builtins.


What's a builtin command and what's not?

I used the command which that "returns the pathnames of the files (or links) which would be executed in the environment" to confirm that history was not an external (to bash) command.

For example, running

$ which history
$

returns nothing and the exit code is 1 (one or more specified commands is nonexistent or not executable) [FYI see the exit code with echo $?], while running

$ which ls
/bin/ls
$

and the exit code 0 (all specified commands are found and executable).

Also, in bash you can look up help for builtin commands with help (or searching the man bash page). For example, typing

$ help history
history: history [-c] [-d offset] [n] or history -anrw [filename] or history -ps
arg [arg...]
   Display or manipulate the history list.
...

shows bash's help info. Running help non-bash-command returns something similar to this:

$ help ls
bash: help: no help topics match `ls'.  Try `help help' or `man -k ls' or
`info ls'.

and the exit code 1


So what has sudo been doing?

You can search your own history for sudo commands your user has run (and not skipped saving it to history) with grep '^sudo' .bash_history or history|less or similar.

Or, on Ubuntu the file /var/log/auth.log keeps records of what sudo has been doing for all users, search for "sudo" in there (other distros may use the file /var/log/secure), or could use

sudo grep sudo /var/log/auth.log

or run sudo journalctl _COMM=sudo if you've got systemd.

See the question "Details about sudo commands executed by all user" on Unix & Linux for more details

Solution 2:

history is a bash builtin, not a regular command; sudo doesn't start a shell to execute the command you give it, it just tries to execute it directly (as a regular command), so it's not available.

You can use sudo bash to open a root shell command and then run history, but if you want a one-liner, well it's a little complicated. bash only enables its history mechanism when it's run in interactive mode, and if you do something like sudo bash -c history (the -c tells bash "here's the command I want you to execute:"), it treats it as non-interactive mode and doesn't actually display any history. Even adding -i (for interactive mode) didn't work when I tested it. But this did:

sudo bash -i <<<history

Note that <<< is a bash-only feature; in other shells you might have to use echo history | sudo bash -i instead.