Note that the 'report' that you are describing is merely the value returned by the (defun) expression - per the documentation:
This is no different to typing (+ 1 1) at the command line and observing 2 as the return value of the + function; that is, there is nothing special about running a custom command and seeing a return value versus evaluating an arbitrary LISP expression and seeing a return value.
Given this, the documentation for the (princ) function reveals why two outputs are observed:
Hence, when typing (princ "Hello World!") to the command line, you'll obtain:
Command: (princ "Hello World!")
Hello World!"Hello World!"
The first being the operation (aka side effect) of the (princ) function, the second being the value returned by the (princ) function.
Now, given that (defun) returns the value returned by the last evaluated expression, and (princ) returns the value of the evaluated expression, if you define a function such as:
(defun c:test ( )
(princ "Hello World!")
)
You will obtain the following output:
Command: TEST
Hello World!"Hello World!"
Since (princ) has printed the string to the command line and returned "Hello World!" to the (defun) expression, and the (defun) expression has in turn returned "Hello World!" as its own return value.
Therefore, by modifying the function definition to:
(defun c:test ( )
(princ "Hello World!")
(princ)
)
The first (princ) expression still returns "Hello World!" to the (defun) expression, but it is no longer the last evaluated expression - the second (princ) with no arguments will return a null symbol to the (defun) expression, which will then be returned by the (defun) expression, resulting in no visible output to the command line.