close and shutdown are not the same
With sockets, close(fd) sometimes does not deliver a FIN and the connection sits half-open. Usually another reference to the descriptor exists — a forked child, a dup — so the reference count never reaches zero and the kernel sends nothing.
shutdown(fd, SHUT_WR) sends FIN immediately regardless of references, and ends only the write direction; reads continue. That is the half-close HTTP servers use to say "I am done" and still read.
The other difference: shutdown applies to sockets, close to every descriptor. They are only comparable when the descriptor is a socket.
For half-open connections, the FIN-WAIT-1 and CLOSE-WAIT states in ss -tan show which side failed to close.