Controllo di integrità:per quanto ho capito, la shell è l'interfaccia attraverso la quale l'utente può interagire con il sistema operativo, ovvero:eseguire altri processi.
Sì, ma una "shell" è specificatamente un utente interfaccia, non un'interfaccia di programmazione. Altri programmi non sono tenuti a interagire con esso:possono utilizzare direttamente le stesse chiamate di sistema per creare nuovi processi.
Quindi la shell della riga di comando è allo stesso livello di altri programmi, ad es. gestori di servizi o interfacce utente grafiche (shell grafiche).
Anche se la shell (ad esempio Bash) è solo un altro processo.
Sì. Sui sistemi Unix-like è un processo completamente normale e senza privilegi.
C'è un modo per eseguire un processo che non sarà figlio di un processo shell?
Dal punto di vista dell'utente:sì, ci sono diversi modi.
-
La maggior parte delle shell ha un
exec
parola chiave che provoca la sostituzione del nuovo programma la shell (mantenendo lo stesso PID e parentela), che probabilmente non è quello che intendevi, ma tecnicamente quello che hai chiesto. -
Le sessioni desktop grafiche spesso iniziano senza richiamare bash o qualsiasi altra shell e questo si applica automaticamente alle app avviate tramite i menu grafici. Il genitore dell'app sarà il processo responsabile della visualizzazione del menu (ad esempio il gestore delle finestre o il pannello).
-
L'attuale popolare systemd init system non utilizza affatto una shell all'avvio dei servizi, quindi è possibile definire un .service e avviarlo:il genitore del servizio sarà init stesso. Ha anche una funzione che consente di creare servizi temporanei al volo utilizzando
systemd-run
, con gli stessi risultati.
Dal punto di vista di un programmatore, usa semplicemente fork()
e execve()
chiamate di sistema per avviare un nuovo processo. (Ci sono dettagli specifici del sistema operativo, ad esempio fork() potrebbe in effetti essere un wrapper per una chiamata diversa, ma funziona ancora allo stesso modo.)
Infatti, anche se il programma volesse invocare una shell, lo farebbe creando un nuovo processo figlio ed eseguendo /bin/sh usando lo stesso fork+exec. Non esiste una chiamata di sistema speciale per eseguire una shell. (Il programmatore potrebbe usare ad es. system() quando scrive in C, o os.system() in Python, ma questi sono ancora solo comodi wrapper attorno a fork/exec.)
Variabili d'ambiente:in bash, ci sono diversi script che vengono eseguiti quando si genera una shell, ad es. .bashrc, .bash_profile, ecc. (dipende dal tipo di shell:interattiva vs non interattiva, login vs non login). Questi script definiscono le variabili di ambiente. Se esiste un modo per eseguire un processo indipendentemente da qualsiasi shell, da dove vengono le variabili d'ambiente?
Beh, a volte non lo fanno. (È un vero problema pratico quando si cerca di fare in modo che le app grafiche raccolgano le personalizzazioni dell'ambiente, a seconda di come si avvia quel particolare ambiente grafico.)
Nel complesso, tuttavia, le variabili d'ambiente non lo sono univoco per le shell CLI. Ogni processo, indipendentemente da come è stato avviato (incluso anche il processo init), riceve un array di stringhe contenente la sua riga di comando e un array di stringhe contenente le sue variabili di ambiente. Quando si avvia un processo figlio, può specificare un ambiente diverso o consentire l'ereditarietà di una copia del proprio ambiente.
Quindi, quando accedi, la tua shell riceve già alcune variabili di ambiente iniziali dal suo genitore. Quegli script di avvio (bashrc, ecc.) sono solo un posto conveniente per un utente per personalizzare le variabili d'ambiente che poi erediteranno i processi figli della shell.
Molte parti di questa risposta si applicano anche completamente a Windows:sebbene la sua interfaccia grafica sia un po' più complessa, le shell della CLI (cmd.exe e PowerShell) sono ancora programmi ordinari che non vengono affatto utilizzati durante il normale funzionamento. L'unica grande differenza è che Windows ha una singola chiamata "CreateProcess" invece delle chiamate separate "fork + exec" in stile Unix.
-
È corretto. Alla fine, la shell eseguirà il
exec
chiamata di sistema, che è disponibile in tutti i sistemi operativi compatibili con POSIX, e più in generale in tutti i sistemi operativi Unix-like, incluso Linux. Altri sistemi operativi hanno concetti simili. Su Linux, ilexec
la chiamata di sistema alla fine chiamerà ilexecve
funzione, che è fornita dal kernel e fa il vero lavoro di caricare il file eseguibile ed eseguirlo. -
Sì. Qualsiasi processo può chiamare
exec
, e non deve essere un "guscio". Ad esempio, quando avvii un programma facendo clic su un browser di file system, il software desktop è quello che esegueexec
chiama, non c'è shell. Si noti che il processo diventa figlio del software desktop che lo ha avviato. Tutti i processi sono figli di un altro processo, tranne il primo, che si chiamainit
e ha PID 1. È responsabile della configurazione del sistema operativo all'avvio e dell'avvio di tutti gli altri processi, come i servizi in background e l'accesso al desktop. Su Linux al giorno d'oggi,systemd
è spesso usato comeinit
processo, ma ci sono altre alternative. -
Esistono diverse varianti di
exec
(execl
,execle
, ...) che hanno vari argomenti oltre al nome del programma da eseguire. In definitiva, ilexecve
la chiamata di sistema accetta un nome di programma, un elenco di stringhe che sono gli argomenti della riga di comando e un elenco di stringhe che sono le variabili di ambiente. Ad esempio, quando si avvia un software da un browser del filesystem, le variabili di ambiente possono essere copiate da quelle del browser del filesystem stesso, eventualmente modificate dal browser del filesystem. Questo dipende interamente dai programmatori del browser del filesystem.
Qualche ulteriore lettura:
- https://en.wikipedia.org/wiki/Exec_(system_call)
- https://en.wikipedia.org/wiki/Fork%E2%80%93exec
- https://man7.org/linux/man-pages/man2/execve.2.html