Come interrompere l'esecuzione di uno script se non è root (ed echo "Non in esecuzione come root! Uscita ...")


17

Ecco la mia fonte:

#!/bin/bash

echo "Running script to free general cached memory!"
echo "";
echo "Script must be run as root!";
echo "";
echo "Clearing swap!";
swapoff -a && swapon -a;
echo "";
echo "Clear inodes and page file!";
echo 1 > /proc/sys/vm/drop_caches;
echo "";

Cancella cache e roba e fa eco che deve essere eseguito come root nel terminale. Fondamentalmente voglio solo che lo script cessi di funzionare se rileva che non viene eseguito come root.

Esempio:

"Running script to free general cached memory!"
"Warning: script must be run as root or with elevated privileges!"
"Error: script not running as root or with sudo! Exiting..."

Se eseguito con privilegi elevati, funziona normalmente. Qualche idea? Grazie!



2
@muru, tranne che l'altra domanda è per il contrario: fallire lo script se eseguito come root.
— Stéphane Chazelas,

3
@ StéphaneChazelas ah, il mio male. Ritirato
— muru,

Un'alternativa è limitare la quantità di lavoro eseguita come rootprefisso prefisso tutti i comandi che devono essere eseguiti come rootcon sudo.
— reinierpost,

Risposte:


46
#!/bin/sh

if [ "$(id -u)" -ne 0 ]; then
        echo 'This script must be run by root' >&2
        exit 1
fi

cat <<HEADER
Host:          $(hostname)
Time at start: $(date)

Running cache maintenance...
HEADER

swapoff -a && swapon -a
echo 1 >/proc/sys/vm/drop_caches

cat <<FOOTER
Cache maintenance done.
Time at end:   $(date)
FOOTER

L'utente root ha UID 0 (indipendentemente dal nome dell'account "root"). Se l'UID effettivo restituito id -unon è zero, l'utente non sta eseguendo lo script con i privilegi di root. Utilizzare id -ruper verificare l'ID reale (l'UID dell'utente che richiama lo script).

Non utilizzare $EUIDnello script poiché potrebbe essere modificato da un utente non privilegiato:

$ bash -c 'echo $EUID'
1000

$ EUID=0 bash -c 'echo $EUID'
0

Se un utente facesse questo, ovviamente non porterebbe a un'escalation privilegiata, ma potrebbe portare a comandi nello script che non sono in grado di fare ciò che dovrebbero fare e file creati con il proprietario sbagliato ecc.


1
Nota: su Solaris 5.10, /bin/id -ufornisce/bin/id: illegal option -- u Usage: id [-ap] [user]
— jrw32982 supporta Monica il

1
@ jrw32982 Dovresti avere in /usr/xpg4/binanticipo il tuo $PATHaccesso per accedere alle utility POSIX su Solaris.
— Kusalananda

1
Il punto è che l' -uopzione di idnon è universale e quindi questa soluzione è universale solo con l'avvertenza che una versione POSIX di iddeve verificarsi prima nel tuo PERCORSO.
— jrw32982 supporta Monica il

1
@ jrw32982 Affinché lo script raccolga le utilità POSIX corrette su Solaris, modificare $PATHnella parte superiore dello script in modo che /usr/xpg4/binsia precedente /bin. Se insisti nell'utilizzare non POSIX id, ovviamente dovrai trovare una soluzione più portatile.
— Kusalananda

1
@Harry Sì, quindi lo script potrebbe utilizzare PATH=$( getconf PATH )o impostare un altro percorso predefinito esplicito oppure utilizzare un percorso esplicito per la chiamata id.
— Kusalananda

19

Penso che ciò che desideri sia piuttosto verificare di disporre dei privilegi di superutente, ovvero che il tuo ID utente effettivo sia 0.

zshe bashrenderlo disponibile nella $EUIDvariabile, in modo da poter fare:

if ((EUID != 0)); then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

Con qualsiasi shell simile a POSIX, è possibile utilizzare il idcomando standard:

if [ "$(id -u)" -ne 0 ]; then
  echo >&2 "Error: script not running as root or with sudo! Exiting..."
  exit 1
fi

Si noti che tutti id -uno whoamio $USERNAMEvariabile zshsi arriva la prima nome utente per l'UID. Sui sistemi che hanno altri utenti con ID 0, ciò potrebbe non essere possibile rootanche se il processo è un discendente di uno che è stato autenticato come root.

$USERdi solito ti darebbe l'utente che è autenticato, ma fare affidamento su di esso è piuttosto fragile. Non è impostato dalla shell, ma di solito è impostato dal comando di autenticazione (come login, su(su sistemi GNU / Linux, non necessariamente altri) sudo, sshd(almeno quello di openssh) ...). Non sempre però (la modifica di uid non imposta automagicamente quella variabile, deve essere fatta esplicitamente dall'applicazione che modifica l'uid) e potrebbe anche essere stata modificata da qualche altro processo negli antenati della shell. $LOGNAME, con lo stesso avvertimento è più affidabile di quanto specificato da POSIX (originariamente da FIPS 151-2)


12

È possibile utilizzare $USERo whoamiper verificare l'utente corrente.

if [[ "$USER" != "root" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

if [[ $(whoami) != "root" ]]; then
    echo "Warning: script must be run as root or with elevated privileges!"
    exit 1
fi

if [[ $(id -u) != "0" ]]; then
    echo "Error: script not running as root or with sudo! Exiting..."
    exit 1
fi

1
NP. Suggerisco letteralmente di leggere direttamente il manuale di bash [ gnu.org/software/bash/manual/bashref.html] . In realtà è un pronto sorprendentemente facile. Per questa risposta in particolare suggerisco di fare riferimento: 3.2.4.2 Conditional Constructs 3.5.4 Command Substitution
— Jesse_b

9
Il comando id -ucon o senza -nun'opzione è un'alternativa all'utilizzo di whoami. Senza un -n e confrontandolo con zero è una corrispondenza migliore con il test che il kernel sta effettivamente facendo. Tutto ciò che interessa al kernel è l'id, non il nome dal file della password.
— Icaro,

6
Credo che usare $(id -u)sia meglio. In alcuni casi (dannosi), $USERpotrebbe essere sbagliato.
— Basile Starynkevitch,

1
Per coloro che sono interessati al link fornito da @Jesse_b: c'è un errore di battitura. Dovrebbe essere gnu.org/software/bash/manual/bashref.html
— Kryten,

1
Alcuni sistemi non usano "root" come nome dell'account privilegiato con uid 0. QNAP viene in mente come uno. Quindi dovresti controllare solo uid 0 e non il nome dell'account di root.
— roaima,

10

Quello che vuoi effettivamente è determinare se hai accesso a queste operazioni. È considerata una cattiva pratica verificare se si è root al posto di quello.

Se il sistema è stato configurato per consentire a un utente non root di modificare lo scambio e di eliminare la cache della pagina, perché l'utente non dovrebbe eseguire lo script?

Invece, puoi semplicemente provare l'operazione e uscire con un messaggio utile se fallisce:

if ! ( swapoff -a && swapon -a )
then
  echo "Failed to clear swap (rerun as root?)" >&2
  exit 1
fi

if ! echo 1 > /proc/sys/vm/drop_caches
then 
  echo "Failed to free page cache (rerun as root?)" >&2
  exit 1
fi

Un utente non root che disattiva lo swap?
— Kusalananda

2
Sì. Puoi configurarlo con SELinux. Allo stesso modo, è possibile disabilitare un processo di root dal farlo.
— quell'altro ragazzo il

1
Potresti non volerlo fare exitdopo che qualcosa non riesce, nel caso in cui l'utente voglia fare il più possibile con i propri privilegi attuali. (Ma per un sistema tipico in cui tutto ciò richiede il root, uscire sarebbe più utile / meno rumoroso.)
— Peter Cordes

2
Non andrei fino al punto di dire che è "cattiva pratica" per verificare se si è root. Soprattutto se è esattamente quello che vuoi sapere. Ritengo che sia meglio verificare se si dispone di autorizzazioni sufficienti per fare ciò che si desidera.
— Erik Bennett,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.