Alias ​​su CD in una directory e chiama un comando


21

Ho un .bash_profilee in quello ho un set di alias. Quegli alias al momento eseguono solo un singolo comando ed è stato abbastanza facile. Vorrei tuttavia fare due cose con un nuovo alias che sto cercando di creare.

  1. CD in una directory
  2. Esegui un comando da quella directory

Risposte:


26

Per eseguire un comando con una directory di lavoro specifica, di solito si fa

( cd directory && utility )

Le parentesi intorno cd ...indicano che i comandi in essa contenuti vengono eseguiti in una subshell. La modifica della directory di lavoro in una subshell comporta che la directory di lavoro corrente della shell chiamante non venga modificata, ovvero, dopo aver chiamato questo comando, ci si troverà comunque nella stessa directory da cui è stato avviato.

Esempio:

( cd / && echo "$PWD" )  # will output "/"
echo "$PWD"              # will output whatever directory you were in at the start

Questo non può essere trasformato in un alias generico poiché un alias non può accettare alcun argomento.

Per una directory e un'utilità specifiche , si potrebbe fare

alias cdrun='( cd "$HOME/somedir" && ./script.sh )'

ma per il caso generale, dovresti usare una funzione shell:

cdrun () {
    ( cd "$1" && shift && command "$@" )
}

o

cdrun () (
    cd "$1" && shift && command "$@"
)

Sostituendo le parentesi graffe con parentesi attorno al corpo della funzione, la funzione viene eseguita nella propria sottostruttura.

Questo sarebbe usato come

$ cdrun "$HOME/somedir" ./script.sh

che eseguirà lo script script.shsituato nella directory $HOME/somedir, con $HOME/somedircome directory di lavoro, o

$ cdrun / ls -l

che ti fornirebbe un elenco di directory in "formato lungo" della directory principale.

La funzione shell prende il suo primo argomento e tenta di passare a quella directory. Se funziona, sposta il nome della directory dai parametri posizionali (l'elenco degli argomenti della riga di comando) ed esegue il comando dato dal resto degli argomenti. commandè un comando integrato nella shell che esegue semplicemente i suoi argomenti come comando.


Tutto ciò è necessario se si desidera eseguire un comando con una directory di lavoro modificata . Se vuoi solo eseguire un comando che si trova altrove, puoi ovviamente usarlo

alias thing='$HOME/somedir/script.sh'

ma ciò sarebbe script.shsituato nella $HOME/somedircon la corrente directory come la directory di lavoro.

Un altro modo di eseguire uno script situato altrove senza modificare la directory di lavoro è aggiungere la posizione dello script alla PATHvariabile di ambiente, ad es.

PATH="$PATH:$HOME/somedir"

Ora script.shin $HOME/somedirsarà in grado di essere eseguito da qualsiasi luogo, semplicemente utilizzando

$ script.sh

Ancora una volta, questo non cambia la directory di lavoro per il comando.


2
Risposta eccellente e completa. Ho solo pensato che avrei detto che la definizione della funzione necessita di un solo metodo per raggruppare i comandi e le parentesi per la subshell sono sufficienti: cdrun () ( cd "$1" && shift && command "$@" ).
Anthony G - giustizia per Monica

2
@AnthonyGeoghegan Ah, è vero. Uso sempre { ... }per coerenza con funzioni più lunghe.
Kusalananda

Questo D&R sembra parlare della mia situazione e potrebbe essere un miglioramento nell'uso di un ambiente circostante pushde popd(anche > /dev/nullse stai cercando di evitare anche i messaggi di output), pur mantenendo il contesto pulito!
Pysis,

1
@Pysis Sì, (cd dir && thing)è anche molto più portatile dell'uso di pushde popd.
Kusalananda

@Kusalananda Davvero? Li ho fatti lavorare per almeno diversi sistemi.
Pysis,

4
alias <name-of-the-alias>='cd <the-directory> && <command>'

Quindi, se si desidera modificare la directory (cd) nella cartella /var/log/e quindi elencare (ls) i suoi file, è possibile aggiungere nel proprio .bash_profilefile quanto segue:

alias logs='cd /var/log/ && ls'

1

Uso questa funzione per eseguire un singolo comando in una directory diversa:

cd1 () {
  if [ $# -eq 1 ]; then
    command cd -- "$1"
  else
    ( command cd -- "$1" && shift && "$@" )
  fi
}

Una limitazione di questa funzione è che i caratteri jolly sono completati rispetto alla directory originale, non alla directory in cui viene eseguito il comando. È possibile fare di meglio in zsh .

Questa funzione si comporta come una normale cdse chiamata con un singolo argomento, quindi potresti volerla chiamare cd. (Questa funzione non supporta alcuna opzione, ma le opzioni da cdutilizzare raramente.)


-1

Separare i comandi con un punto e virgola, ad esempio:

alias do_something='cd /tmp; ls'

8
In caso cdcontrario, si otterrà l'elenco delle directory della directory errata. È meglio usare al &&posto di ;qui.
Kusalananda

@Kusalananda ha ragione. Puoi trovare di più in questa risposta
nikolas
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.