Perché devo digitare `. /` Prima di eseguire un programma nella directory corrente?


92

Durante l'esecuzione di un programma C a.out, utilizzando il terminale Ubuntu, perché devo sempre digitare ./prima a.out, invece di scrivere a.out? C'è una soluzione per questo?




Risposte:


119

Quando digiti il ​​nome di un programma come a.outil sistema cerca il file nel tuo PERCORSO. Sul mio sistema, PATH è impostato su

/usr/lib/lightdm/lightdm:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Il tuo è probabilmente simile. Per verificare, entra echo $PATHin un terminale.

Il sistema controlla queste directory nell'ordine indicato e se non riesce a trovare il programma produce un command not founderrore.

Preparare il comando con ./effettivamente dice "dimentica il PERCORSO, voglio che cerchi solo nella directory corrente".

Allo stesso modo puoi dire al sistema di guardare solo in un'altra posizione specifica anteponendo il comando con un percorso relativo o assoluto come:

../significa nella directory padre, ad esempio ../hellocercare ciao nella directory padre.

./Debug/hello: "cerca hellonella sottodirectory Debug della mia directory corrente."

oppure /bin/ls: "cerca lsnella directory /bin"

Per impostazione predefinita, la directory corrente non si trova nel percorso perché è considerata un rischio per la sicurezza. Vedi perché lo è. non nel percorso di default? su Superuser per il motivo.

È possibile aggiungere la directory corrente al PERCORSO, ma per i motivi indicati nella domanda collegata non lo consiglierei.


25
Questo. +1 Non aggiungere .al tuo PATH(come suggeriscono le altre 2 risposte) a causa del rischio per la sicurezza menzionato in questa risposta.
Giorno

8
Potrebbe anche valere la pena notare che qui non c'è nulla di speciale ., puoi usare un percorso completo o relativo a un eseguibile, ad esempio /home/user/foo/a.outoppure./build/a.out
tobyodavies,

@tobyodavies; In realtà .è speciale perché significa "la mia directory corrente" e quindi potrebbe essere qualsiasi directory in cui l'utente si trova autonomo con i privilegi di lettura ed esecuzione. Questo è potenzialmente più pericoloso dell'aggiunta di un percorso specifico completo.
Warren Hill,

@WarrenHill quando pensi di aggiungerlo al tuo percorso, sì, è abbastanza diverso. Tuttavia, in termini di sintassi bash, .non ha uno status speciale, è solo un percorso che potrebbe anche iniziare /e ./blahche funzionerebbe altrettanto bene con cato grepcome un prompt bash.
tobyodavies,

@tobyodavies: OK Ho modificato la mia risposta per includere il tuo punto.
Warren Hill,

24

Il motivo è semplice.

Supponiamo di avere un comando con lo stesso nome di un'applicazione nella directory corrente. Quindi l'esecuzione del comando nella shell invocherebbe la tua app invece del comando integrato. Questo sarebbe un problema di sicurezza se non altro.

Richiedendo ./di essere utilizzato in primo piano, la shell sa che si desidera eseguire l'applicazione con il nome specificato e non un comando integrato con quel nome.


1
la tua spiegazione è fuorviante, c'è una differenza tra i comandi integrati in una shell e gli eseguibili accessibili tramite la variabile PATH. In effetti la tua risposta più leggo sembra più errata.
Ahmed Masud,

16

./esegue i file che non sono nel tuo $PATH, piuttosto esegue il file nella directory corrente (o in un altro tramite ./home/stefano/script.sh). Ora, PATH è una variabile d'ambiente che contiene tutti i luoghi in cui bash può cercare programmi eseguibili, senza avere il percorso completo (assoluto).

Questa separazione è necessaria per evitare di eseguire il file errato. Vale a dire se hai un file chiamato lsnella tua home directory, non essere nel tuo PATH impedirà a bash di confonderlo con il reale ls. La variabile PATH definisce anche l'ordine di ricerca:

  • Quando si esegue un comando o un programma tenta di creare un execsyscall (un metodo speciale del kernel, come vengono avviati i programmi), il sistema cerca il file passando attraverso ciascuna delle directory nel proprio PERCORSO. Una volta trovato il programma, anche se si trova in più directory, la ricerca viene interrotta e viene eseguito il primo trovato.

Per eseguire un file, è necessario impostare il bit eseguibile nelle autorizzazioni:

  • Dato che sei già sulla riga di comando, puoi semplicemente digitare chmod +x finename.

  • Oppure puoi impostare le autorizzazioni facendo clic con il pulsante destro del mouse sul file e selezionando Proprietà :

    testo alternativo

Ora puoi copiare il file in una qualsiasi delle directory in PATH, per vedere quali sono presenti - e sono impostati in base all'utente - tipo echo $PATH.

stefano@3000-G530:~$ echo $PATH
/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games

Se si crea un file eseguibile cate lo si sposta in /usr/local/sbin, viene eseguito invece del corretto cat, in cui risiede /bin. Puoi scoprire dove sono i tuoi file usando type cate whereis cat.


2
Una cosa da notare: la sua domanda sembra indicare che ha compilato e collegato qualcosa gcc, che imposta automaticamente il bit di esecuzione.
Nathan Osman,

12

Perché è necessario digitare ./prima di eseguire un programma?

Nel terminale, ogni volta che si digita il nome di un'applicazione, diciamo gedit, il terminale andrà a cercare in alcune directory (predefinite) che contengono applicazioni (i binari delle applicazioni). I nomi di queste directory sono contenuti in una variabile chiamata PATH. Puoi vedere cosa c'è in questa variabile eseguendo echo $PATH. Vedi quelle directory separate da :? Queste sono le directory che il terminale sarà Inizia la ricerca in, se si digita gedit, nautiluso a.out. Come puoi vedere, il percorso del tuo a.outprogramma non è lì. Quando lo fai ./a.out, stai dicendo al terminale "cerca nella directory corrente, ed esegui a.out, e non andare a cercare PATH.

Soluzione 1

Se non si desidera digitare ./ogni volta, è necessario aggiungere a.outla directory in $PATH. Nelle seguenti istruzioni, suppongo che il percorso a.outsia /path/to/programs/, ma è necessario modificarlo nel percorso effettivo.

  1. Aggiungi semplicemente la seguente riga alla fine del file ~/.pam_environment:

    PATH DEFAULT=${PATH}:/path/to/programs

    Fonte: variabili di ambiente persistenti

  2. Disconnettersi e riconnettersi. Ora sarà possibile eseguire a.outsenza ./da qualsiasi directory.

Se hai altri programmi in altre directory, puoi semplicemente aggiungerli alla riga sopra. Tuttavia, consiglierei di avere una directory chiamata "myPrograms" per esempio, e mettere tutti i tuoi programmi sotto di essa.

Soluzione 2

Nota: modificare userNameil nome utente Ubuntu attuale.

Che cosa succede se si dispone di altri programmi che si desidera eseguire? E sono tutti in cartelle diverse? Bene, una soluzione "più organizzata" sarebbe quella di creare una cartella chiamata binnella directory Home e aggiungere collegamenti simbolici (collegamenti) sotto quella cartella. Ecco come:

  1. mkdir /home/userName/bin

    • Questo creerà la cartella binnella tua directory Home.
  2. ln -s /path/to/programs/a.out /home/userName/bin

    • Questo creerà un "collegamento simbolico" (in sostanza, un collegamento) del tuo a.outprogramma sotto bin.
  3. Disconnettersi e riconnettersi. Ora sarà possibile eseguire a.outsenza ./da qualsiasi directory.

Ora, ogni volta che hai un altro programma altrove, diciamo che il programma b.insul tuo desktop, tutto ciò che devi fare è: ln -s /home/userName/Desktop/b.in /home/userName/bine sarai quindi in grado di eseguirlo anche senza ./.

Nota: grazie al commento di @ Joe , quando si eseguono i backup, i collegamenti simbolici devono essere gestiti in modo speciale. Per impostazione predefinita, rsyncnon li elabora affatto, quindi quando ripristini, non sono lì.


1
Questo è un trucco utile se usato con parsimonia. Usandolo molto, il tuo sistema fa cose che qualcun altro non si aspetterebbe. Inoltre, quando si eseguono backup, i collegamenti simbolici devono essere gestiti in modo speciale. Per impostazione predefinita , rsync non li elabora affatto, quindi quando ripristini non sono lì.
Joe,

1

Come ha sottolineato George nella sua risposta, questo ti aiuta a notare che stai eseguendo un file nella directory di lavoro corrente ( pwd).

Ricordo di aver fatto questa domanda al mio senior molto tempo fa, ha detto che avrei dovuto aggiungere .al mio percorso in modo che quando lo faccio a.outguardasse nella directory corrente e la eseguisse. In questo caso non devo farlo ./a.out.

Ma, personalmente, lo sconsiglio. Non mi è mai successo, ma se ti trovi in ​​una directory di rete aliena o qualcosa del genere, e lsesiste un file eseguibile dannoso chiamato lì, avere .sul tuo percorso è una pessima idea. Non che incontrerai questo problema molto spesso, solo dicendo.


ok, Stefano ha adottato la sua risposta per contenere queste informazioni :)
Shrikant Sharat il

3
Sono completamente d'accordo con non aggiungere .a $PATH. Idea molto pericolosa.
Nathan Osman,

1

Oltre ad altre risposte, qui la parte essenziale da man bashcui lo spiega bene:

ESECUZIONE DEI COMANDI
       Dopo che un comando è stato diviso in parole, se risulta in un semplice
       comando e un elenco opzionale di argomenti, sono le seguenti azioni
       prese.

       Se il nome del comando non contiene barre, la shell tenta di individuare
       esso. Se esiste una funzione shell con quel nome, quella funzione è
       invocato come descritto sopra in FUNZIONI. Se il nome non corrisponde a
       funzione, la shell lo cerca nell'elenco dei builtin della shell. Se
       viene trovata una corrispondenza, viene invocato quel builtin.

       Se il nome non è né una funzione shell né un builtin, e contiene no
       barra, bash cerca in ogni elemento del PERCORSO una directory con-
       conservare un file eseguibile con quel nome.

0

Un './' ha senso quando esegui un programma che è noto per te e specifico, ad esempio il tuo. Questo programma deve essere presente nella directory corrente. Un './' non ha senso quando si esegue un comando standard da qualche parte nel $ PATH. Un comando "quale comando da eseguire" indica dove si trova il comando da eseguire nel $ PATH.


0
$ gcc hello.c -o /path/to/someplace/hello

produrrà un eseguibile in qualche posizione. Se quella posizione si trova sul tuo percorso, sarai in grado di eseguire il file. Puoi scrivere questo script se ti piace creare un'etichetta per l'azione "compila questo codice sorgente usando gcc e posiziona un eseguibile in qualche posizione sul tuo percorso"

Ti suggerirei di creare una nuova directory chiamata "testbin" o qualcosa del genere e metterla sul tuo percorso per mantenere pulite le tue directory di percorso esistenti.


0

./elimina la ricerca non necessaria di un percorso. ./forzare la ricerca solo nella directory corrente. Se non diamo ./allora cercherà varie percorso impostato nel sistema come /usr/bin, /usr/sbin/, etc.


0

"./" significa che si desidera eseguire un file nella directory corrente è un collegamento per digitare l'intero percorso, ad esempio:

[root@server ~]#/path/to/file/file.pl

è uguale a:

[root@server file]#./file.pl

nell'esempio precedente hai passato la directory e le sue sup-directory nella posizione del file e hai usato "./" per eseguire il file nella directory corrente.

quello precedente " [root @ server ~] # / path / to / file / file.pl " eseguirà anche il file se si è pigri a "cd" fino al percorso del file.


-4

È molto semplice e ha molti usi.

  1. Quando sono installate più versioni della stessa applicazione, sarà disponibile in un percorso diverso, ma è possibile creare un collegamento software al file binario /usr/bin. Ad esempio, Python 2.7, Python 2.6 è installato ma / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6

Se sei nel percorso /usr/local/bined esegui Python eseguirà sempre Python 2.7. La specifica .richiederà l'eseguibile della cartella corrente.

  1. .- rappresenta sempre l'esecuzione dalla directory corrente. E ..significa sempre che viene eseguito dalla directory precedente.
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.