Os arquivos do dispositivo AFAIK são a única opção para que os processos do usuário tenham acesso aos dispositivos. O kernel não se importa se esse processo é um shell.
Os programas C têm a opção de ajustar o acesso ao dispositivo: a ioctl
call:
man 2 ioctl
:
int ioctl(int d, unsigned long request, ...);
Talvez haja um invólucro de shell para isso, mas não conheço nenhum.
> strace fdisk -l /dev/sda
[...]
open("/dev/sda", O_RDONLY|O_CLOEXEC) = 3
[...]
ioctl(3, BLKGETSIZE64, 500107862016) = 0
[...]
ioctl(3, CDROM_GET_CAPABILITY or SNDRV_SEQ_IOCTL_UNSUBSCRIBE_PORT, 0) = -1 ENOTTY (Inappropriate ioctl for device)
ioctl(3, BLKALIGNOFF, 0) = 0
ioctl(3, BLKIOMIN, 4096) = 0
ioctl(3, BLKIOOPT, 0) = 0
ioctl(3, BLKPBSZGET, 4096) = 0
ioctl(3, BLKSSZGET, 512) = 0
ioctl(3, BLKSSZGET, 512) = 0
uname({sys="Linux", node="inno", ...}) = 0
ioctl(3, BLKGETSIZE64, 500107862016) = 0
ioctl(3, HDIO_GETGEO, {heads=255, sectors=63, cylinders=60801, start=0}) = 0