./ vs. per l'esecuzione di programmi sotto il terminale


13

Avrei bisogno di alcuni chiarimenti riguardo al modo in cui eseguiamo gli eseguibili sotto il terminale. Questa potrebbe essere una domanda scadente, ma qual è la differenza tra l'esecuzione di un eseguibile con ./an_executablee . an_executable(supponiamo che siamo nella directory in cui si trova an_executable)

So già che il primo fa sì che la shell cerchi an_executable nella directory corrente ( .), ma perché non è /necessario dopo aver .usato l'ultima versione?

Grazie in anticipo.


Risposte:


22

La . executablesintassi non funziona con qualsiasi eseguibile (o funziona?). Invece, è un alias per il bash sourceincorporato. Quindi la differenza è principalmente rilevante per gli script bash, e la verità è che sono cose completamente diverse :)

./executablechiede di eseguire l'eseguibile "normalmente". ./è un riferimento relativo al percorso corrente. Questo evita che la shell (bash) tenti di individuare l'eseguibile in una directory nella sua $PATH(cosa che farebbe se non si specificasse affatto un percorso con il comando). Il motivo per cui non puoi semplicemente fare executableè quello della sicurezza; immagina di decomprimere un archivio scaricato e che contiene una versione dannosa di ls. Se fosse eseguito direttamente dalla tua directory corrente, avresti eseguito quella versione senza accorgertene.

D'altra parte, . executablesta dicendo "sorgente di un file chiamato executable". Dato che stai nominando direttamente il file e in realtà non deve essere un eseguibile, non si applica la limitazione di sicurezza per $ PATH. Il sourcing "eseguirà" (o sembrerà funzionare) solo script di shell. Quello che fa è:

   source filename [arguments]
          Read and execute commands from filename  in  the  current  shell
          environment  and return the exit status of the last command exe‐
          cuted from filename.

Quindi ... Qual è davvero la differenza tra esecuzione e sourcing? Supponendo che lo stesso script di shell, eseguendolo ( ./script) genererà una nuova shell, eseguirà lo script all'interno di quella shell e, quando lo script uscirà, chiuderà quella shell e tornerà alla shell madre. In effetti, avvierà un nuovo bashprocesso per eseguire lo script).

( . script) farà sì che la shell corrente legga i comandi dal file come se fossero stati digitati nella riga di comando. Non ci sono nuove shell generate.

Un modo molto semplice per vedere come si comporta è scrivere uno script che contiene solo exit. Se lo fai ./script, nulla sembrerà accadere, questo perché viene avviato un nuovo processo di shell, il exitcomando esce da quella nuova shell e la shell corrente non viene influenzata.

Se si . script, il terminale corrente verrà chiuso, poiché il exitcomando viene eseguito nella shell corrente. Quindi equivale a digitare exitsul prompt dei comandi.


In effetti, avevo a che fare con lo script della shell quando ho notato questo comportamento. Grazie mille, questa è la risposta di cui avevo bisogno. :)
zipzap,

un'altra domanda sollevata (se non ti dispiace): se il mio script contiene solo alcuni semplici messaggi con echo e lo sto eseguendo con ./script, allora perché sono in grado di vedere i messaggi nella shell genitore se la subshell si chiude appena termina l'esecuzione?
zipzap,

2
Perché mentre la subshell è un processo separato , usa lo stesso terminale della shell che invoca. È simile a come sei ancora in grado di vedere l' lsoutput: digiti il ​​comando, viene eseguito, mostra l'output e quindi termina, ma l'output rimane nel terminale.
Roadmr,

2
Non confondere la shell con il terminale; sono cose diverse. Apri un terminale e il prompt dei comandi è dato da una bashshell in esecuzione al suo interno. Se digiti bash, eseguirai un'altra shell; alla prima shell, è solo un programma da eseguire. Se digiti exit, chiuderai l' ultima shell che hai avviato ma rimarrai nella prima shell (quella di quando hai avviato il terminale). Ancora una volta, tutto ciò accade all'interno dello stesso terminale.
Roadmr,

1
@DavidZ L'ho già detto :) "Il sourcing" eseguirà "(o sembrerà funzionare) solo script di shell."
Roadmr,
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.