How to circularly shift a signal by a fraction of a sample?
If you want the shifted output of the IFFT to be real, the phase twist/rotation in the frequency domain has to be conjugate symmetric, as well as the data.  This can be accomplished by adding an appropriate offset to your complex exp()'s exponent, for the given phase slope, so that the phase of the upper (or negative) half, modulo 2 Pi, mirrors the lower half in the FFT aperture.  The complex exponential shift function can also be made conjugate symmetric by indexing it from -N/2 to N/2 with a phase of zero at index 0.

It just so happens that the appropriate offset for phase twists or spirals, that complete an exact integer multiples of 2 Pi rotations in aperture, to be conjugate symmetric in aperture, is zero.

With a conjugate symmetric phase twist vector, the result should then end up as a circular Sinc interpolation for non-integer shifts.

Elaboration by OP:

Your choice of k = [0, 1, 2, 3, 4, 5, 6, 7, 8] is producing an asymmetrical complex exponential:



If you use k = [0, 1, 2, 3, 4, -4, -3, -2, -1] instead, you get a Hermite-symmetric complex exponential:

plot(fftshift(exp(-1j * 2*pi * 0.5/N * k)))




and now when you use the same exponential formula to shift by 0.5 or 3.5 samples, you get a real result:

plot ifft(fft(a)*exp(-1j * 2 * pi * 0.5/N *k))
plot ifft(fft(a)*exp(-1j * 2 * pi * 3.5/N *k))