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.