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?
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:
Quando digiti il nome di un programma come a.out
il 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 $PATH
in un terminale.
Il sistema controlla queste directory nell'ordine indicato e se non riesce a trovare il programma produce un command not found
errore.
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 ../hello
cercare ciao nella directory padre.
./Debug/hello
: "cerca hello
nella sottodirectory Debug della mia directory corrente."
oppure /bin/ls
: "cerca ls
nella 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.
.
al tuo PATH
(come suggeriscono le altre 2 risposte) a causa del rischio per la sicurezza menzionato in questa risposta.
.
, puoi usare un percorso completo o relativo a un eseguibile, ad esempio /home/user/foo/a.out
oppure./build/a.out
.
è 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.
.
non ha uno status speciale, è solo un percorso che potrebbe anche iniziare /
e ./blah
che funzionerebbe altrettanto bene con cat
o grep
come un prompt bash.
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.
./
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 ls
nella 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:
exec
syscall (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à :
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 cat
e 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 cat
e whereis cat
.
gcc
, che imposta automaticamente il bit di esecuzione.
./
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
, nautilus
o a.out
. Come puoi vedere, il percorso del tuo a.out
programma 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
.
Se non si desidera digitare ./
ogni volta, è necessario aggiungere a.out
la directory in $PATH
. Nelle seguenti istruzioni, suppongo che il percorso a.out
sia /path/to/programs/
, ma è necessario modificarlo nel percorso effettivo.
Aggiungi semplicemente la seguente riga alla fine del file ~/.pam_environment
:
PATH DEFAULT=${PATH}:/path/to/programs
Disconnettersi e riconnettersi. Ora sarà possibile eseguire a.out
senza ./
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.
Nota: modificare
userName
il 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 bin
nella directory Home e aggiungere collegamenti simbolici (collegamenti) sotto quella cartella. Ecco come:
mkdir /home/userName/bin
bin
nella tua directory Home.ln -s /path/to/programs/a.out /home/userName/bin
a.out
programma sotto bin
.Disconnettersi e riconnettersi. Ora sarà possibile eseguire a.out
senza ./
da qualsiasi directory.
Ora, ogni volta che hai un altro programma altrove, diciamo che il programma b.in
sul tuo desktop, tutto ciò che devi fare è: ln -s /home/userName/Desktop/b.in /home/userName/bin
e 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,
rsync
non li elabora affatto, quindi quando ripristini, non sono lì.
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.out
guardasse 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 ls
esiste un file eseguibile dannoso chiamato lì, avere .
sul tuo percorso è una pessima idea. Non che incontrerai questo problema molto spesso, solo dicendo.
.
a $PATH
. Idea molto pericolosa.
Oltre ad altre risposte, qui la parte essenziale da man bash
cui 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.
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.
$ 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.
./
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.
"./" 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.
È molto semplice e ha molti usi.
/usr/bin
. Ad esempio, Python 2.7, Python 2.6 è installato ma / usr / bin / python -> python2.7 / usr / local / bin / python -> python2.6Se sei nel percorso /usr/local/bin
ed esegui Python eseguirà sempre Python 2.7. La specifica .
richiederà l'eseguibile della cartella corrente.
.
- rappresenta sempre l'esecuzione dalla directory corrente. E ..
significa sempre che viene eseguito dalla directory precedente.