Qual è la differenza tra l'esecuzione di un eseguibile solo per nome e aggiungendo un punto / barra prima di esso?


13

Questo è l'output del ls -allcomando:

-rwxr----- 1 subhrcho dba  3600 Nov 13 17:26 jdev
-rw-r----- 1 subhrcho dba  1566 Nov 13 17:26 jdev-Darwin.conf
-rw-r----- 1 subhrcho dba   347 Mar  6  2009 jdev-debug.boot
-rw-r----- 1 subhrcho dba   821 Nov 13 17:26 jdev-logging-debug.conf
-rw-r----- 1 subhrcho dba   584 Nov 13 17:26 jdev-logging.conf
-rw-r----- 1 subhrcho dba  4717 Jul 31 16:09 jdev.boot
-rw-r----- 1 subhrcho dba 12877 Nov 13 17:26 jdev.common
-rw-r----- 1 subhrcho dba  5047 Dec  6 01:43 jdev.conf
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdev.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64.exe
-rwxr-x--- 1 subhrcho dba 28672 Nov 13 16:28 jdev64W.exe
-rwxr-x--- 1 subhrcho dba 28160 Nov 13 16:28 jdevW.exe

Ora, quando eseguojdev , esegue una versione diversa di Oracle JDveloper rispetto a quando lo ./jdeveseguo come .. Perché è così?

Risposte:


20

Quando esegui un file eseguibile (o meglio nel mondo unix / linux - un file con diritti eseguibili / flag attivo) in questo modo:

$ ./jdev

si contrassegna quindi con .quello che si desidera eseguire un file all'interno della directory di lavoro (directory in cui ci si trova attualmente) che è denominato jdeve dispone dei diritti eseguibili per l'utente che lo sta avviando (è necessario notare che può ancora essere un collegamento a altro file, puoi verificarlo digitando ls -l jdevnel terminale)

(vedi i permessi sui file in linux / unix )

Quando lo esegui come

$ jdev

quindi molto probabilmente è jdevinstallato da qualche parte sul sistema e ce l'hai $PATH(es. /usr/bin/o /bin/oppure /usr/local/bin/)

Come affermato da peterph : è possibile utilizzare whichper indicare l'eseguibile che viene avviato con un comando particolare, ad esempio:

$ which find
/usr/bin/find

1
Inoltre, l' whichutilità non può dirti quale eseguibile verrà utilizzato se non viene fornito alcun percorso.
peterph

@peterph Modificato la mia risposta.
Patryk,

7
È molto meglio usare typeper controllare ciò che viene lanciato da un comando particolare. Causa whichti mostrerà solo un binario da qualche parte nel $ PATH, tuttavia potrebbe essere aliasato con un altro binario.
precipita il

@rush I ha appena provato questo e non lavoro sarà come dici tu: [~] $which zsoelim /usr/bin/zsoelim [~] $ type zsoelim zsoelim is /usr/bin/zsoelim. Mentrezsoelim -> soelim
Patryk il

2
@Patryk Penso che rush abbia significato gli alias / funzioni della shell, che whichnon ha alcuna possibilità di trovare, dal momento che è un binario autonomo che non ha accesso all'ambiente shell in esecuzione (con il quale intendo alias e funzioni, non solo le variabili di ambiente , alcuni dei quali sono ereditati).
peterph

8

Se si chiama un comando senza barra nel suo nome in una shell, viene cercato negli alias, nelle funzioni della shell e nell'elenco dei percorsi forniti nella $PATHvariabile d'ambiente. (nota che puoi avere la directory di lavoro corrente (specificata come .o la stringa vuota) o qualsiasi directory relativa in $PATH, ma non è raccomandata per motivi di sicurezza).

Se c'è una barra nel nome, quindi ciò non accade, il nome viene preso come un percorso da cui eseguire il comando (anche se alcune shell come zshpermettono ad alias o funzioni di avere barre nel loro nome che avrebbero quindi la precedenza).

Quindi, se vuoi eseguire un comando chiamato fooche si trova nella directory di lavoro corrente, devi trovare un nome che contiene una barra. ./fooè il più ovvio. Puoi anche utilizzare il percorso completo o ../dir/foo...

Per sapere quale sarebbe l'esecuzione della shell, utilizzare il typecomando Non usare il whichcomando che generalmente non fa quello che pensi che faccia ed è un'eredità da cshcui è meglio lasciare solo.


Perché non "quale" ma "tipo"?
Geek,


hai fornito il link corretto?
Geek,

Questo è un risultato di ricerca su questo sito per dimostrare che è una domanda frequente. Molte risposte a queste domande ti diranno perché non usarle which. Vedi ad esempio unix.stackexchange.com/questions/16693/…
Stéphane Chazelas il

2

Consiglio di usare il 'dove' (meglio di 'quale') incorporato di Zsh per vedere come e in quale ordine si troveranno alias, built-in di shell o qualsiasi altra cosa per $ PATH ;-)

Ecco un esempio per capire meglio le cose, come viene scelto:

[ 0:04:08 ] afsin@s15426859:~ % pwd
/home/afsin
[ 0:04:30 ] afsin@s15426859:~ % which who
/usr/bin/who
[ 0:04:47 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:27 ] afsin@s15426859:~ % echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/bin/X11:/usr/games:/home/afsin/bin
[ 0:05:31 ] afsin@s15426859:~ % touch who
[ 0:05:40 ] afsin@s15426859:~ % chmod +x who
[ 0:05:47 ] afsin@s15426859:~ % ls -al who
-rwxr-xr-x 1 afsin afsin 0 23. Jan 00:05 who
[ 0:05:50 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
[ 0:05:55 ] afsin@s15426859:~ % export PATH=$PATH:.
[ 0:06:09 ] afsin@s15426859:~ % where who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:14 ] afsin@s15426859:~ % alias who=who
[ 0:06:19 ] afsin@s15426859:~ % where who
who: aliased to who
/usr/bin/who
/usr/bin/X11/who
./who
[ 0:06:22 ] afsin@s15426859:~ % which who
who: aliased to who
[ 0:06:27 ] afsin@s15426859:~ %

1

Anche se questo probabilmente dipende dalla tua shell, la regola di solito è:

  • Se si fornisce un percorso, relativo o assoluto, viene utilizzato quel percorso. ./jdevè un percorso relativo, perché .rappresenta la directory corrente (in effetti, ls -all .ti darebbe lo stesso di ls -all). Se lo fai /usr/bin/tool/, stai usando un percorso assoluto. In questi casi, il file indicato viene eseguito.

  • Se non si fornisce un percorso, ma solo un nome, le directory in $PATHvengono ricercate per lo strumento che si sta tentando di eseguire.

Se nella directory corrente è presente un file con lo stesso nome di un file in alcune directory $PATHe lo si esegue anteponendone ./il nome, verrà effettivamente eseguito un file diverso.

Forse un altro problema è che ti aspettavi jdevdi eseguire l'eseguibile nella directory corrente. A meno che tu non abbia cambiato $PATHper includere ., questo non è qualcosa che dovresti aspettarti ...

... e non è ancora una buona idea includerlo .lì, se lo fai, per favore almeno mettilo alla fine, in modo che il resto $PATHsia sempre cercato per primo - immagina di essere su una directory di rete condivisa e qualcuno decide di mettere lì un binario malefico poiché ls, se $PATHinizia ., ls -lahbasta una semplice per attaccare il tuo sistema.


La tua terminologia è confusa. jdevda solo è anche un percorso relativo. La regola è: se non contiene una barra, viene cercata in alias, funzioni e $PATH, in caso contrario, viene cercata direttamente sul file system (anche se alcune shell consentono alias o funzioni con / nel loro nome che poi prenderebbero precendenza).
Stéphane Chazelas,
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.