Each shell process has its own idea of what the command-line history is. When an interactive shell exits it will write its remembered history to
~/.bash_history for the next shell to pick up, but that's the extent of cooperation between shell processes.
In your command, the
() makes the shell fork a copy of itself to run
history -d command. The child process starts out with a copy of the parent's internal state, so it knows the history, and is able to make changes to its copy of it.
However, when the subshell exits, its copy of the history (which was just rewritten) is discarded together with the rest of its internal state). The subshell knows it is a subshell, so it doesn't even bother to write
A script that is not sourced usually cannot manipulate history at all, because it is interpreted by a fresh non-interactive shell that doesn't even read
~/.bash_history at startup.
You can get the shell to behave like an interactive shell by specifying it on the command line:
The shell that runs this script will append its commands (which includes both the shebang line and the
echo something) to the
~/.bash_history it finds on disk. But of course that doesn't affect the in-memory history copy of the shell process you invoke the script from, and when it exits the changes the script made to
~/.bash_history will be lost anyway.