Allow bash script to be run as root, but not sudo

The only way I could think of is to check one of the SUDO_* environment variables set by sudo:

#!/usr/bin/env sh

if [ "$(id -u)" -eq 0 ]
then
    if [ -n "$SUDO_USER" ]
    then
        printf "This script has to run as root (not sudo)\n" >&2
        exit 1
    fi
    printf "OK, script run as root (not sudo)\n"
else
    printf "This script has to run as root\n" >&2
    exit 1
fi

Notice that of course this solution is not future proof as you cannot stop anyone from setting a variable before running the script:

$ su
Password:
# SUDO_USER=whatever ./root.sh
This script has to run as root (not sudo)
# ./root.sh
OK, script run as root (not sudo)

Another option would be to check if the grandparent process name is "sudo":

#!/bin/sh
if [ "$(id -u)" -eq 0 ]
then
  if [ $(ps -o comm= -p $(ps -o ppid= -p $$)) = "sudo" ]
  then
    echo Running under sudo
  else
    echo Running as root and not via sudo
  fi
else
  echo Not running as root
fi

The information about which user logged in is available in /proc/self/loginuid. EDIT due to comments: That file does not seem to exist on all systems. I tested and it is available on Centos 6, Fedora 32, Fedora 33 and Ubuntu 20.04, all in standard x86_64 setups. If we login as our user and than use sudo or su to become root, this will not change /proc/self/loginuid and it will be some non-zero value. If we directly log in as root, then cat /proc/self/loginuid will return 0. Note that this file can NOT be modified, even root cannot do this. EDIT due to Stéphane Chazelas' comment: Root can overwrite this file using echo 0 > /proc/self/loginuid. However, this can be prevented by setting auditctl --loginuid-immutable.

The script to check for real root (if auditctl --loginuid-immutable is set) could look like

#!/bin/bash
loginuid=$(cat /proc/self/loginuid)
echo $loginuid
if [[ $loginuid -ne 0 ]]; then
    echo "You did not log in as root."
    exit
fi