Comprendi il file / etc / inittab
Su Febbraio 12, 2021 da admin Sto usando il seguente /etc/inittab
file (systemv):
# /etc/inittab: init(8) configuration. # $Id: inittab,v 1.91 2002/01/25 13:35:21 miquels Exp $ # The default runlevel. id:5:initdefault: # Boot-time system configuration/initialization script. # This is run first except when booting in emergency (-b) mode. si::sysinit:/etc/init.d/rcS # What to do in single-user mode. ~~:S:wait:/sbin/sulogin # /etc/init.d executes the S and K scripts upon change # of runlevel. # # Runlevel 0 is halt. # Runlevel 1 is single-user. # Runlevels 2-5 are multi-user. # Runlevel 6 is reboot. l0:0:wait:/etc/init.d/rc 0 l1:1:wait:/etc/init.d/rc 1 l2:2:wait:/etc/init.d/rc 2 l3:3:wait:/etc/init.d/rc 3 l4:4:wait:/etc/init.d/rc 4 l5:5:wait:/etc/init.d/rc 5 l6:6:wait:/etc/init.d/rc 6 # Normally not reached, but fallthrough in case of emergency. z6:6:respawn:/sbin/sulogin S0:12345:respawn:/sbin/getty -L 115200 ttyS0
Per capire come funzionano davvero le cose, apprezzerò se le tue risposte a 1-3 distinguerai tra due situazioni:
- Sono connesso al mio sistema tramite una porta seriale.
- Ho un PC desktop “normale”.
Domande:
-
Se aggiungo unaltra riga di getty, una volta avviato linux vedrò due terminali separati?
-
Se apro diverse righe di getty, come ho assegnato quale getty eseguirà il mio comando
si::sysinit:/etc/init.d/rcS
e quale getty eseguirà i comandi degli altri script? (quelli che eseguono gli script in base al livello di esecuzione del sistema)in altre parole: nel file
/etc/inittab
– posso assegnare comandi diversi a diversi gettys? (voglio dire ai terminali che si apriranno con questi gettys) -
viene eseguito lultimo script nella cartella /etc/init.d/rc5 il seguente comando:
su nobody -c /bin/sh
e loutput è:
sh: cannot set terminal process group (1618): Inappropriate ioctl for device sh: no job control in this shell sh-4.3$ whoami nobody
Quindi ho verificato che non sono nessuno ma perché scrive le prime due righe? anche perché il prompt è sh-4.3 $ e non nessuno @ …
-
Sto usando una connessione seriale. Posso cambiare il file / etc / inittab e lultimo script che verrà eseguito da init al fine di:
- eseguire un programma prima di accedere come utente con privilegi bassi (il processo di inizializzazione attenderà la terminazione)
- una volta terminato il programma ottenere prompt di login al mio sistema
- qual è il modo migliore per creare un utente con privilegi bassi e lasciargli eseguire questo programma durante il processo di inizializzazione (se non voglio usare lutente nessuno)
Risposta
Domanda 1:
Sì, aggiungendone altre getty
linee puoi ottenere più terminali in parallelo. È possibile associare un solo getty
a un dispositivo terminale alla volta, quindi è possibile un solo getty
per porta seriale. Su un normale PC desktop, il kernel Linux definisce un numero di console virtuali, accessibili usando le combinazioni di tasti Control + Alt + FX e corrispondenti a /dev/ttyX
dispositivi (X = un numero). La configurazione esatta può variare a seconda delle distribuzioni, ma di solito nelle distribuzioni tradizionali, i primi 6 dispositivi /dev/ttyX
hanno getty
configurati per loro quando il sistema funziona normalmente. Puoi utilizzare i comandi openvt
e deallocvt
per aggiungere o rimuovere console virtuali e avviare processi (che possono essere processi qualsiasi, non necessariamente getty
s) su di essi.
/dev/tty0
è speciale: si riferisce a qualsiasi console virtuale sia quella attualmente selezionata. /dev/console
è un dispositivo speciale simile, che punta a qualsiasi dispositivo TTY definito come console di sistema primaria a livello di kernel. Sui sistemi desktop, è effettivamente un alias di /dev/tty0
per impostazione predefinita, ma utilizzando lopzione di avvio console=
puoi passare a un seriale porta. Ad es. alcune architetture incorporate potrebbe essere una porta seriale per impostazione predefinita. Utilità come xconsole
possono anche fungere da output aggiuntivo per /dev/console
.
Ai tempi in cui i computer erano grandi cose multi-cabinet in aule computer dedicate, inviare un messaggio a /dev/console
sarebbe stato un modo per raggiungere loperatore di sistema in servizio fisicamente vicino al computer, che potrebbe essere stato utile per richieste ad es cambiare nastri o pacchi disco. Sui sistemi moderni, i messaggi inviati specificamente a /dev/console
sono solitamente messaggi di avvio / arresto o forse un canale di ultima istanza per allarmi urgenti su condizioni di errore che potrebbero influire sullaccesso alla rete o allo comportano un arresto anomalo del kernel: “una persona responsabile dellhardware fisico deve vederlo ei normali file di log sono inutilizzabili per qualche motivo.”
Domanda 2:
“Temo che tu abbia unidea sbagliata qui. La riga sysinit
e altre righe /etc/inittab
non sono associate a getty
viene elaborato. Ogni comando eseguito da inittab
, se non diversamente specificato, ha i propri flussi di input, output ed errore standard associati a /dev/console
.
Le righe getty
specificano effettivamente il dispositivo TTY che useranno e il processo getty
ha un codice integrato che assegnerà quel dispositivo TTY per se stessi e tutti i loro processi figli a meno che / finché lutente non esegue una shell e sceglie di reindirizzare quei flussi in qualche altro modo.Questo e linizializzazione delle impostazioni del dispositivo TTY sono la parte più importante dello scopo di getty
“: visualizzare /etc/issue
e il prompt di accesso, accettare il nome utente, limpostazione della variabile di ambiente TERM e lavvio del passaggio successivo del processo di accesso TTY (di solito /bin/login
ma personalizzabile) sono in effetti solo parti minori.
Nota che lì è una convenzione secondo cui per i dispositivi TTY, il campo ID di due caratteri nella prima colonna della riga inittab
deve corrispondere al nome del dispositivo TTY in questione dopo /dev/tty
, quindi /dev/ttyS0
otterrà un ID riga inittab di S0
e così via. Per cose che non è necessariamente associato a nessun TTY (o invia solo materiale di emergenza a / dev / console se necessario), lID può essere qualsiasi cosa che non sia in conflitto con gli ID di linea del dispositivo TTY.
(Indietro il giorno in cui i terminali collegati in serie erano i n rm, ottenere le impostazioni del dispositivo TTY giuste per il terminale allaltro capo della linea e reimpostare il terminale a uno stato noto per il login non erano attività banali, poiché cerano molti standard di tipo di terminale concorrenti.)
Se configuri una riga inittab
per eseguire uno script, potresti, ad esempio, vedere se una particolare /dev/ttyX
console virtuale dispositivo esiste. In caso contrario, puoi utilizzare openvt -c X <command>
per creare la console virtuale e avviare un comando su di essa; se il dispositivo della console virtuale esiste già, puoi semplicemente avviare qualsiasi comando desideri con input, output ed errore standard reindirizzati ad esso. Ad esempio, potresti specificare una riga inittab come questa:
6:345:respawn:/usr/local/sbin/myscript
e quindi /usr/local/sbin/myscript
con qualcosa di simile ( disclaimer: non testato, non ho un sistema con SysVinit a portata di mano in questo momento, sentiti libero di modificare se puoi migliorarlo):
#!/bin/sh if [ -c /dev/tty6 ]; then exec <some command> </dev/tty6 >/dev/tty6 2>&1 else exec openvt -c 6 -w <some command> fi
respawn
nella riga inittab
si assicura che il processo venga riavviato automaticamente se si interrompe per qualsiasi motivo. 345
è lelenco dei runlevel SysVinit su cui questo processo deve essere eseguito. Se è necessario che venga eseguito su tutti i runlevel regolari, immettere 12345
.
Nota, questo funziona come previsto solo se la riga inittab viene posizionata dopo la riga sysinit
, quindi si può presumere che linizializzazione di udev
sia completa. Se se si desidera farlo allinizio del processo di inizializzazione, potrebbe essere necessario occuparsi di creare i nodi dei dispositivi effettivi per i dispositivi che hanno i driver già caricati per primi; una volta che udev
è in esecuzione, dovrebbe creare automaticamente i nodi del dispositivo non appena i driver del dispositivo vengono inizializzati.
Se si utilizza una porta seriale, il openvt
il comando non verrà applicato.
Quindi sì, puoi sicuramente allegare diversi comandi a diversi dispositivi TTY. Aiuta se i comandi hanno funzionalità incorporate per quelle come getty
, ma puoi farlo anche con gli script.
(Se imposti qualcosa di più complicato di un semplice tail -f
per visualizzare permanentemente alcuni log in una console virtuale altrimenti inutilizzata, dovresti leggere man setsid
e vedi se è applicabile a ciò che stai “ripianificando”.
Domanda 3:
Cè di più per inizializzare una sessione TTY per un particolare utente non root piuttosto che avviare una shell con su
.
I messaggi di errore
sh: cannot set terminal process group (1618): Inappropriate ioctl for device sh: no job control in this shell
sono probabilmente causati dalla shell associata al dispositivo /dev/console
anziché a un dispositivo TTY specifico. Poiché /dev/console
è solo un alias per qualunque sia la console di sistema corrente, non avrà a disposizione il set completo di funzioni ioctl di controllo TTY.
Se non esiste uno script di accesso per assegnare un valore più utile alla PS1
variabile di ambiente, il prompt predefinito per /bin/sh
può essere semplicemente sh-<version>$
.
Domanda 4:
Sì, puoi. Devi specificare “lultimo script” come wait
-type riga in inittab
e posizionarlo prima la riga getty
corrispondente alla tua linea seriale.
Senza conoscere molti più dettagli sul tuo ambiente, sarà molto difficile dire quale sarebbe modo migliore per creare un utente con privilegi bassi per tali scopi.
Commenti
Risposta
-
Sì, supponendo che la linea riceve un identificatore univoco e la linea del terminale configurata è disponibile:
S1:12345:respawn:/sbin/getty -L 115200 ttyS1
aprirà un terminale sulla porta seriale collegata a
ttyS1
. -
Le righe in
inittab
non sono sequenziali o correlate a un accesso. Ogni riga descrive unazione da intraprendere in un dato insieme di runlevel. Pertantosi::sysinit:/etc/init.d/rcS
specifica cheinit
deve essere eseguito/etc/init.d/rcS
quando gestisce linizializzazione del sistema; questo accade prima che siano possibili gli accessi. (Vedere lainittab(5)
manpage per i dettagli).Per assegnare diversi comandi a diversi
getty
su terminali specifici, devi configurare la stessa invocazionegetty
, ad esempio modificandologin
programma avviato (lopzione-l
nella maggior parte dellegetty
implementazioni):S0:12345:respawn:/sbin/getty -L 115200 -l /bin/my-t0-login ttyS0 S1:12345:respawn:/sbin/getty -L 115200 -l /bin/my-t1-login ttyS1
-
/etc/init.d/rc 5
viene eseguito prima che siano possibili gli accessi e i programmi che esegue non sono collegati a un terminale (“correttamente”, che è ciò che fagetty
: apre il terminale e collega i programmi a cui si avvia), quindi quando viene richiamatosu nobody -c /bin/sh
, shell non trova la configurazione del terminale che si aspetta e di conseguenza disabilita il controllo del lavoro. Il promptsh-4.3$
è il prompt predefinito di Bash 4.3 quando viene eseguito come/bin/sh
. -
Se il tuo programma deve essere eseguito solo una volta che un utente inizia ad accedere, puoi agganciarlo alla sequenza di login usata da
getty
; ma un programma del genere verrebbe eseguito come root. A seconda di ciò che stai cercando esattamente, probabilmente faresti meglio a utilizzare un initscript anziché la/etc/inittab
personalizzazione osudo
e il script di avvio della shell.
Commenti
- grazie per la tua replica. Posso chiedere un chiarimento su smail riguardo la sec.2? come posso modificare il comando di login per ogni differente getty?
- Fatto, guarda laggiornamento.
- grazie! solo per verificare se ho capito bene: di default il processo getty eseguirà il comando / bin / login che esegue il processo responsabile del login di sistema. Ora il getty eseguirà un comando diverso, ogni comando che ‘ scelgo, e non chiamerà al processo di login del sistema come prima … ho ragione?
- Sì, è vero. La chiave è ottenere
getty
per aprire il TTY per te; il suo comportamento normale è aspettare un nome di login, quindi eseguirelogin
, connesso al TTY;login
attende la password, la controlla e avvia la shell, anchessa connessa al TTY. Se sostituisci la partelogin
, dovrai assicurarti che il tuo programma di sostituzione si comporti comelogin
. - Ad esempio, se voglio saltare la fase di accesso, per poter aprire il mio sistema con lutente root senza inserire alcun nome utente o password. Posso usare: S0: 12345: respawn: / sbin / getty -L 115200 -l – / bin / sh ttyS0 o usare: S0: 12345: respawn: / sbin / getty -L 115200 -l [my_script_path] ttyS0 e dentro lo script i ‘ eseguirà il comando – / bin / sh e altri?
Risposta
Solo ora un secondo (lungo!) la risposta è stata pubblicata. Devo dire che il primo spiega abbastanza bene. Al momento voglio commentare il punto tre: è meno una questione di tempismo, ma di processi che controllano un tty “virtuale reale”, e non solo un “manichino di console”.
Prima di poter avviare una shell “con job control”, è necessario impostare, ad esempio, aprire un ttyN. Il comando “generico” è getty
. Da quella tty-qualcosa che ottieni puoi avviare una shell, non solo dopo quella.
È come provare ad avviare prima un window manager, e poi xorg, invece di “avviarli” insieme a xinit. Credo. “session leader”.
A causa di
xx:12:...:program
e, al contrario:
aa:1:...:pr_1 bb:1:...:pr_2
… ottieni una relazione N: M (ottieni anche un pasticcio se abusi – molti RL ciascuno con molti prog diversi). Puoi andare lontano con questo, ma da allora diversi tipi di “standard” RC hanno preso il sopravvento. “Runcoms”. Con loro, inittab sembra semplice, ma tutta la complessità è in questi script.
Ma il tuo inittab sembra semplice e corretto – solo lultimo commento e la voce “z6” …
Forse il tuo “su nessuno” ha bisogno di un “getty … ttyN” prima / intorno. su
invece di login
e nessun respawn. Dovrebbe almeno fornire un messaggio di errore diverso da “inappropriato”.
Conclusione (dopo aver letto la seconda risposta): non hai bisogno di un complicato sistema init.d
, il grezzo inittab è abbastanza flessibile. Devi solo ottenere il concetto ei dettagli corretti.
È possibile impostare tre runlevel: uno con ttyNs, uno con ttySN e un RL che li avvia entrambi. È un parametro di avvio che puoi aggiungere con il boot loader. Runlevel “5” nel tuo caso è solo predefinito. Scegli un kernel, un root = e un runlevel in cui eseguire linizializzazione.
Lazione “respawn” è ciò per cui sysvinit era / è effettivamente necessario . Molto di più non fa e meno sarebbe stato possibile implementarlo in uno script. Ma se esci (o esci) dall “ultimo” livello di shell, hai bisogno di una rete di sicurezza.
sysvinit può persino rilevare un errore di configurazione con lerrore “spawn troppo veloce – ignorato per 5 minuti …”.
getty
è un processo; quello di cui stai parlando è un dispositivo TTY . Il kernel ha aperto il primo per te e per gli script di inizializzazione;/dev/console
è un alias per ” il primo dispositivo TTY che è stato aperto e utilizzato dal kernel “. Se il tuo account utente dispone delle autorizzazioni per laccesso in lettura e scrittura a un dispositivo TTY, puoi semplicemente iniziare a utilizzarlo (non è necessariogetty
), ma potrebbe essere una buona idea impostare Variabile TERM correttamente:TERM=linux top </dev/tty8 >/dev/tty8 2>&1 &
oTERM=vt100 top </dev/ttyS1 >/dev/ttyS1 2>&1 &
avvierà il comandotop
sullottava console virtuale o la seconda porta seriale.getty
, creerà un pasticcio di linput & output, poiché i due processi combatteranno per linput e i loro output si confonderanno. I processigetty
vengono avviati solo dopo che/etc/init.d/rc 5
e qualsiasi script da esso avviato sono terminati .