Mi ritrovo a ripetere molto:
mkdir longtitleproject
cd longtitleproject
C'è un modo per farlo in una riga senza ripetere il nome della directory? Sono a bash qui.
mkdir longtitleproject
quindicd !^
Mi ritrovo a ripetere molto:
mkdir longtitleproject
cd longtitleproject
C'è un modo per farlo in una riga senza ripetere il nome della directory? Sono a bash qui.
mkdir longtitleproject
quindicd !^
Risposte:
Non esiste un comando integrato, ma puoi facilmente scrivere una funzione che chiama mkdir
quindi cd
:
mkcd () {
mkdir "$1"
cd "$1"
}
Inserisci questo codice nel tuo ~/.bashrc
file (o ~/.kshrc
per utenti ksh o ~/.zshrc
per utenti zsh). Definisce una funzione chiamata mkcd
. "$1"
verrà sostituito dall'argomento della funzione quando lo si esegue.
Questa versione semplice presenta diversi difetti:
-p
opzione a mkdir
. (Ciò può essere o non essere desiderabile, poiché aumenta il rischio che un errore di battitura non venga rilevato, ad esempio, mkcd mydierctory/newsub
si creerà felicemente mydierctory
e mydierctory/newsub
quando si intende creare newsub
all'interno dell'esistente mydirectory
.)-
ma non è giusto -
, allora mkdir
e cd
lo interpreterà come un'opzione. Se è giusto -
, allora cd
lo interpreterà nel senso $OLDPWD
. Se è +
seguito da 0 o più cifre, cd
in zsh lo interpreterà come un indice nello stack della directory. Puoi risolvere il primo problema, ma non gli altri due, passando --
prima dell'argomento. Puoi risolvere tutti questi problemi anteponendo ./
all'argomento se si tratta di un percorso relativo.mkdir
non segue CDPATH
, ma lo cd
fa, quindi se hai impostato CDPATH
un valore che non inizia con .
(una configurazione certamente un po 'insolita), allora cd
potresti portarti in una directory diversa da quella appena creata. La preparazione ./
ai percorsi relativi risolve questo problema (causa CDPATH
di essere ignorato).mkdir
fallisce, prova a eseguire cd
. Correzione: utilizzare &&
per separare i due comandi.Ancora abbastanza semplice:
mkcd () {
case "$1" in /*) :;; *) set -- "./$1";; esac
mkdir -p "$1" && cd "$1"
}
Questa versione ha ancora il potenziale per far cd
passare una directory diversa da quella mkdir
appena creata in un caso limite: se l'argomento mkcd
contiene ..
e passa attraverso un collegamento simbolico. Ad esempio, se la directory corrente è /tmp/here
ed mylink
è un collegamento simbolico a /somewhere/else
, quindi mkdir mylink/../foo
crea /somewhere/else/foo
mentre cd mylink/../foo
cambia in foo
. Non è sufficiente cercare i collegamenti simbolici nell'argomento, perché la shell tiene traccia anche dei collegamenti simbolici nella propria directory corrente, quindi cd /tmp/mylink; mkdir ../foo; cd ../foo
non cambia nella nuova directory ( /somewhere/else/foo
) ma in /tmp/foo
. Una soluzione per questo è lasciare che il cd
builtin risolva prima tutti i ..
componenti del percorso (non ha senso usare foo/..
iffoo
non esiste, quindi mkdir
non è mai necessario vederne nessuno ..
).
Veniamo a questa versione robusta anche se leggermente cruenta:
mkcd () {
case "$1" in
*/..|*/../) cd -- "$1";; # that doesn't make any sense unless the directory already exists
/*/../*) (cd "${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd -- "$1";;
/*) mkdir -p "$1" && cd "$1";;
*/../*) (cd "./${1%/../*}/.." && mkdir -p "./${1##*/../}") && cd "./$1";;
../*) (cd .. && mkdir -p "${1#.}") && cd "$1";;
*) mkdir -p "./$1" && cd "./$1";;
esac
}
(Esercizio: perché sto usando una subshell per la prima cd
chiamata?)
Se mkdir fallisce, voglio essere sicuro di non cambiare la directory corrente. Tornare indietro con cd - o $ OLDPWD non è abbastanza buono se la shell non ha i permessi per cambiare nella sua directory corrente. Inoltre, chiamando gli aggiornamenti cd OLDPWD, quindi vogliamo farlo una sola volta (o ripristinare OLDPWD).
Esistono anche modi meno specializzati per non dover riscrivere la parola dalla riga precedente:
cd
, quindi Esc .(o Alt+ .) per inserire l'ultimo argomento dal comando precedente.cd !$
esegue cd
l'ultimo argomento del comando precedente.mkdir
in cd
.ksh
, e funziona anche zsh
) per "ripetere l'ultima parola del comando precedente". Lo uso abbastanza spesso.
/a/b/..//
funzionerebbe davvero ma non /a/b/../c
. Fisso. Ho posto la domanda a un pubblico più vasto.
mkcd() { mkdir -p "$1" && cd "$1"; }
non sembra essere un problema in (la mia istanza di) zsh. mkdir -p /var/tmp/somewhere/else /tmp/here; cd /tmp/here; ln -s /var/tmp/somewhere/else mylink; mkdir -p mylink/../foo && cd mylink/../foo; pwd
(include l'installazione e) visualizza /tmp/here/foo
qual è ciò che è stato creato (e ciò che mi aspettavo). bash
crea e cambia erroneamente in /var/tmp/somewhere/foo
.
Questa è la linea di cui hai bisogno. Non sono necessarie altre configurazioni:
mkdir longtitleproject && cd $_
La $_
variabile, in bash, è l'ultimo argomento dato al comando precedente. In questo caso, il nome della directory appena creata. Come spiegato in man bash
:
_ At shell startup, set to the absolute pathname used to invoke
the shell or shell script being executed as passed in the envi‐
ronment or argument list. Subsequently, expands to the last
argument to the previous command, after expansion. Also set to
the full pathname used to invoke each command executed and
placed in the environment exported to that command. When check‐
ing mail, this parameter holds the name of the mail file cur‐
rently being checked."$_" is the last argument of the previous command.
Utilizzare cd $_
per recuperare l'ultimo argomento del comando precedente anziché cd !$
perché cd !$
fornisce l'ultimo argomento del comando precedente nella cronologia della shell :
cd ~/
mkdir folder && cd !$
finisci a casa (o ~ /)
cd ~/
mkdir newfolder && cd $_
finisci in newfolder sotto casa !! (o ~ / newfolder)
mkdir foo && cd foo
, il che non è utile.
Non mi sarebbe mai venuto in mente di scrivere questo comportamento perché inserisco quanto segue su base oraria ...
$ mkdir someDirectory<ENTER>
$ cd !$
dove bash sostituisce gentilmente !$
con l'ultima parola dell'ultima riga; cioè il nome della directory lunga che hai inserito.
Inoltre, il completamento del nome file è tuo amico in tali situazioni. Se la tua nuova directory fosse l'unico file nella cartella, un doppio veloce TABti darebbe la nuova directory senza reinserirla.
Sebbene sia bello che bash ti permetta di scrivere script su attività comuni come suggeriscono le altre risposte, penso che sia meglio imparare le funzionalità di modifica della riga di comando che bash ha da offrire in modo che quando lavori su un altro computer non ti manca la sintattica zucchero fornito dagli script personalizzati.
Secondo Quali personalizzazioni hai fatto sul tuo profilo shell per aumentare la produttività? , ecco come lo faccio:
# make a directory and cd to it
mcd()
{
test -d "$1" || mkdir "$1" && cd "$1"
}
significa che funziona anche se la directory esiste già.
-p
opzione per mkdir eliminerà gli errori.
mcd
comando esistente ? Quale pacchetto o progetto fornisce questo comando?
Se usi Oh My Zsh, c'è un comando chiamato take che fa esattamente questo. Sembrerebbe qualcosa del genere.
take myfolder
In realtà l'ho trovato per caso. Ho appena guardato ed è elencato su questo cheatheat dal wiki Oh My Zsh GitHub. È un comando abbastanza utile e apparentemente molto facile da creare.
take
:) Perfetto! btw - iTerm2 con Oh My Zsh. In realtà ci sono 3 risposte perfette qui. Questo, quello di @ jesús-carrera, e la risposta selezionata. Dipende dalla configurazione e dalle preferenze.
Ecco una leggera variante che è degna di menzione:
function mkdir() {
local dir=$1
command mkdir "$dir" && cd "$dir"
}
Aggiungi questo al tuo ~/.bash_profile
e puoi quindi usarlo mkdir
normalmente (una volta che lo hai source
fatto), tranne ora che eseguirà la funzione sopra anziché il mkdir
comando standard .
Nota, questo non convalida l'input secondo la risposta accettata da Gilles , ma dimostra come puoi (efficacemente) ignorare i builtin.
Dai documenti (parafrasando leggermente):
command mkdir [args]
corremkdir
conargs
ignorando qualsiasi funzione di shell di nomemkdir
. Vengono eseguiti solo i comandi incorporati della shell o i comandi trovati cercando nel PERCORSO. Se esiste una funzione shell denominatals
, l'esecuzionecommand ls
all'interno della funzione eseguirà il comando esternols
invece di chiamare la funzione in modo ricorsivo
Credo che builtin
raggiunga un risultato simile a command
.
$dir
command
come alternativa.
Ho creato uno script che crea la directory e quindi i cd, quindi gli ho dato un alias. Ed ecco un riassunto in cui lo descrivo.
https://gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be
Ho appena automatizzato le risposte di cui sopra e creato uno script eseguibile una sola volta:
fun='
mkcd ()
{
mkdir -p -- "$1" && cd -P -- "$1"
}'
echo "$fun" >> ~/.bashrc
Basta copiarlo in un nuovo file mkcd.sh
ed eseguirlo solo una volta nel terminale da bash mkcd.sh
. Quindi esegui source ~/.bashrc
per farlo funzionare nella sessione corrente.
Successivamente, è possibile utilizzare mkcd some_dir
per creare e immettere direttamente in quella directory.
~/.bashrc
file (con una risposta che è già stata data)? E come suggerisci di creare questo mkcd.sh
script? Con un editore, forse? Sembra più lavoro che semplice modifica ~/.bashrc
. Che vantaggio ha questo rispetto alla risposta accettata? ... ... ... ... ... ... ... .... ... ... ...
mcd
da unix.stackexchange.com/questions/6628/…