2009-04-24 9 views
240

Utilizzando una shell Linux, come posso avviare un programma con una directory di lavoro diversa dalla directory di lavoro corrente?Come si esegue un programma con una directory di lavoro diversa da quella corrente, dalla shell Linux?

Ad esempio, ho un file binario helloworld che crea il file hello-world.txt nella directory corrente. Questo file si trova all'interno della directory /a. Attualmente sono nella directory /b. Voglio avviare il mio programma in esecuzione ../a/helloworld e ottenere il hello-world.txt da qualche parte in una terza directory /c.

+4

ho scoperto nel modo più duro che ' su' reimposta la directory di lavoro alla directory home dell'utente che hai specificato prima di eseguire qualsiasi comando '-c'. Questo è stato molto utile per me. –

risposta

406

chiamata del programma come questo:

(cd /c; /a/helloworld) 

Le parentesi causano un sub-shell da deposto le uova. Questa sub-shell cambia la sua directory di lavoro in /c, quindi esegue helloworld da /a. Dopo che il programma è terminato, la sub-shell termina, ritornando al prompt della shell genitore, nella directory da cui hai iniziato.

Gestione degli errori: Per evitare l'esecuzione del programma senza aver modificato la directory, ad es. quando dopo aver scritto male /c, subordinare l'esecuzione di helloworld condizionale:

(cd /c && /a/helloworld) 

Ridurre l'utilizzo della memoria: Per evitare di dover la memoria rifiuti subshell mentre ciao mondo esegue, chiamare helloworld via exec:

(cd /c && exec /a/helloworld) 

[ Grazie a Josh and Juliano per suggerimenti su come migliorare questa risposta!]

+1

Qualche modo per passare argomenti a questa shell? Come in $ 1 e $ 2? – finiteloop

+1

@segfault: la sottoshell ha accesso completo all'ambito circostante. –

+0

Sembra che sia temporaneamente in quella directory comunque, non è vero? – dhein

1

Se si desidera sempre che passi a/C, utilizzare un percorso assoluto quando si scrive il file.

3

Un modo per farlo è creare uno script di shell wrapper.

Lo script di shell cambierà la directory corrente in/c, quindi eseguirà/a/helloworld. Una volta che lo script della shell viene chiuso, la directory corrente ritorna a/b.

Ecco un esempio bash script di shell:

#!/bin/bash 
cd /c 
/a/helloworld 
14
sh -c 'cd /c && ../a/helloworld' 
+1

Utilizzato questo per jesec di FreeBSD per eseguire un comando all'interno della jail nella directory di lavoro specificata. –

+0

wow, fortunato, ti hanno persino permesso di usare un computer in prigione –

+0

@MattWilde https://www.freebsd.org/cgi/man.cgi?jail – mihi

77

Simile alla risposta David Schmitt 's, più il suggerimento di Josh, ma non lascia un processo shell in esecuzione:

(cd /c && exec /a/helloworld) 

In questo modo è più simile a come di solito comandi della shell esegue. Per vedere la differenza pratica, è necessario eseguire ps ef da un'altra shell con ciascuna soluzione.

+0

[builtin Bash manuale ** exec **] (https: // www .gnu.org/software/bash/manual/html_node/Bourne-Shell-Builtins.html # Bourne-Shell-Builtins) –

1

Se si desidera eseguire questo all'interno del vostro programma quindi vorrei fare qualcosa di simile:

#include <unistd.h> 
int main() 
{ 
    if(chdir("/c") < 0) 
    { 
    printf("Failed\n"); 
    return -1 ; 
    } 

    // rest of your program... 

} 
+0

Vuole farlo in uno script di shell, e non in una C. Inoltre, sarebbe un'idea orribile per sottoporre a sottoprocesso il file binario. –

9

penso sempre strumenti UNIX dovrebbero essere scritte come filtri, leggere l'input dallo standard input e scrivere output sullo standard output. Se possibile, puoi modificare il tuo binario helloworld per scrivere il contenuto del file di testo su stdout anziché su un file specifico. In questo modo puoi usare la shell per scrivere il tuo file ovunque.

$ cd ~/b

$ ~/a/helloworld> ~/c/helloworld.txt

+5

+1 per avere ragione, anche se la risposta è solo marginalmente una risposta. –

1

perché non mantenerlo semplice

cd SOME_PATH && run_some_command && cd -

l'ultima ' cd 'command ti riporterà all'ultima directory pwd. Questo dovrebbe funzionare su tutti i sistemi * nix.

+0

Non ti riporterà indietro se run_some_command fallisce. –

+0

Sei iscritto @mezhaka, dovresti averlo considerato :) – Sahil

7

Un'opzione che non richiede una subshell ed è costruito in bash

(pushd SOME_PATH && run_stuff; popd) 

Demo:

$ pwd 
/home/abhijit 
$ pushd /tmp # directory changed 
$ pwd 
/tmp 
$ popd 
$ pwd 
/home/abhijit 
+0

Un suggerimento simile è stato fatto in seguito da Sahil. Non funziona se il comando fallisce. Considera 'pushd SOME_PATH && run_stuff && popd' - se run_stuff fallisce, che popd non verrà eseguito. –

+0

Risposta tardiva, che dipende dalle impostazioni del file bash. Bash può continuare ad eseguire comandi anche dopo un comando fallito (diversamente dall'utilizzo di &&), ma può essere impostato per non farlo usando '' set -e'' nel file e quindi fallirebbe in '' popd''. – Loren

+1

Ancora, penso 'pushd" $ {SOME_PATH} "&& run_stuff; popd' è migliore della risposta attuale, dal momento che la semantica pushd/popd è stata specificamente progettata per questa situazione di andare in qualche directory e poi tornare a quella originale. –

4

basta cambiare l'ultima "& &" in ";" e sarà CD di back, non importa se il comando non riesce o riesce:

cd SOME_PATH && run_some_command ; cd - 
-1

dalla directory corrente fornire il percorso completo per la directory script per eseguire il comando

/root/server/user/home/bin/script.sh 
+0

Questo non cambia affatto la directory di lavoro - penso che stai rispondendo a una domanda diversa da quella che è stata fatta. –

Problemi correlati