C'è un modo per eseguire un comando in una directory diversa senza doverlo fare cd
? So che potrei semplicemente entrare cd
e cd
uscire, ma sono solo interessato alle possibilità di rinunciare ai passaggi aggiuntivi :)
C'è un modo per eseguire un comando in una directory diversa senza doverlo fare cd
? So che potrei semplicemente entrare cd
e cd
uscire, ma sono solo interessato alle possibilità di rinunciare ai passaggi aggiuntivi :)
Risposte:
Non so se questo conta, ma puoi creare una subshell:
$ (cd /var/log && cp -- *.log ~/Desktop)
La directory viene modificata solo per quella subshell, in modo da evitare il lavoro necessario in cd -
seguito.
$ (cd /var/log && cp *.log ~/Desktop)
. In questo modo, se la directory non esiste, non vengono eseguiti altri comandi.
Alcuni programmi hanno opzioni con le quali puoi dire loro di chdir (2) stessi (ad esempio GNU tar 's -C
/ --directory
).
Al di fuori di tali programmi, però, qualcosa dovrà essere chdir . Potresti scrivere e usare una sorta di programma “binario” compilato invece di farlo fare dalla shell, ma probabilmente non produrrebbe molto beneficio.
In un commento in un'altra risposta, hai fornito un esempio:
execindirectory -d /var/log "cp *.log ~/Desktop"
Poiché il *.log
pattern viene espanso dalla shell stessa (non da cp ), qualcosa dovrà chdir nella directory prima che una shell valuti il tuo comando.
Se sei solo interessante nell'evitare di dover "tornare indietro", allora puoi usare una subshell per isolare l'effetto del cd dall'istanza della shell di lavoro.
(cd /path/to/dir && some command)
Puoi impacchettarlo in una funzione shell. (Ho lasciato cadere l' -d
opzione dal tuo esempio di utilizzo poiché c'è poco senso a questo comando se la directory è in realtà facoltativa.)
runindir() { (cd "$1" && shift && eval "$@"); }
runindir /var/log 'cp *.log ~/Desktop' # your example
runindir /var/log cp \*.log \~/Desktop # eval takes multiple args
runindir /var/log cp \*.log ~/Desktop # it is okay to expand tilde first
Non compromettere il valore delle risposte fornite da altre persone, ma credo che ciò che vuoi sia questo:
(cd /path/to && ./executable [ARGS])
Nota le parentesi da invocare cd
in una sotto-shell.
Ecco qualcosa che dovrebbe farti cd
tornare dove eri (usando Bash), dal momento che non dimenticare di farlo sembra essere lo scopo della domanda:
# Save where you are and cd to other dir
pushd /path/to/dir/that/needs/to/be/current/dir
run-your-command
# Get back where you were at the beginning.
popd
(EDIT: versione leggermente più corta, grazie a @ Random832)
pushd other-dir
, piuttosto chepushd .; cd other-dir
Purtroppo, il tuo esempio:
execindirectory -d /var/log "cp *.log ~/Desktop"
non è necessario modificare la directory, perché
cp /var/log/*.log ~/Desktop
farebbe lo stesso. Non riesci ad avvicinarti al tuo vero problema? Perché potremmo conoscere una soluzione migliore anche per quello.
Un modo complicato per risolvere il tuo problema, che è lontano dall'eleganza della soluzione Michaels, è l'uso di find, che ha un interruttore '-execdir' da eseguire nella directory, dove viene trovato un file. Adottato male al tuo esempio:
find /var/log -maxdepth 1 -type f -name "*.log" -execdir echo cp {} ~/Desktop ";"
Forse è utile per il tuo vero problema. -okdir invece di -execdir ti chiederà di confermare ogni invocazione.
-okdir e -execdir potrebbero aver bisogno dell'installazione di gnu-find, che è generalmente usato su Linux.
Che ne dici ./your/path/command.sh
?
execindirectory -d /var/log "cp *.log ~/Desktop"
.
echo "#!/bin/bash; cd $1; exec $2" > /usr/local/bin/execindirectory; chmod +x /usr/local/bin/execindirectory
. Potrebbe essere necessario un piccolo sforzo in più se si desidera effettivamente supportare "tag" di opzioni come-d
e cose.