Esiste una riga che mi consente di creare una directory e di spostarmi al suo interno allo stesso tempo?

Mi ritrovo a ripetere molto:

 mkdir longtitleproject cd longtitleproject  

Esiste un modo per farlo in una riga senza ripetere il nome della directory? Sono qui.

Commenti

Risposta

Questo è la riga di cui hai bisogno. Nessunaltra configurazione necessaria:

mkdir longtitleproject && cd $_ 

La variabile $_, in bash, è lultimo argomento fornito 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. 

Utilizza cd $_ per recuperare lultimo argomento ment del comando precedente invece di cd !$ perché cd !$ fornisce lultimo argomento del comando precedente nella cronologia della shell :

cd ~/ mkdir folder && cd !$ 

finisci a casa (o ~ /)

cd ~/ mkdir newfolder && cd $_ 

finisci in nuova cartella sotto casa !! (o ~ / newfolder)

Commenti

  • Perché diavolo questa non è la risposta accettata
  • @JSmyth Sono daccordo , questo è un one-liner che utilizza la funzionalità della shell nativa
  • Penso che lOP stia cercando di evitare di usare i due comandi. Questa risposta è (quasi) valida quanto fare mkdir foo && cd foo, che non è ‘ a portata di mano.
  • LOP è chiedendo una riga che ‘ non richiede di ripetere il nome della directory, e questo è
  • Con i voti positivi ‘ è evidente che molte persone trovano utile questa risposta. ‘ spiegherò perché non ho ‘ selezionato questa risposta: ‘ sono molto è probabile che digiti in modo errato && cd $_ poiché le chiavi sono così lontane dalla riga principale, quindi sebbene tecnicamente corretto, ‘ non è ergonomico. Apprezzo il fatto che ‘ non sia dipendente dallambiente e che ‘ sia utile da sapere. Grazie!

Risposta

Non esiste un comando integrato, ma puoi scrivere facilmente una funzione che chiama mkdir quindi cd:

mkcd () { mkdir "$1" cd "$1" } 

Inserisci questo codice il tuo file ~/.bashrc (o ~/.kshrc per gli utenti ksh o ~/.zshrc per gli utenti zsh). Definisce una funzione chiamata mkcd. "$1" verrà sostituita dallargomento della funzione quando la esegui.

Questa semplice versione presenta diversi difetti:

  • Non è possibile creare una catena di sottodirectory contemporaneamente. Correzione: passare lopzione -p a mkdir. (Questo può essere desiderabile o meno, poiché aumenta il rischio che un errore di battitura non venga rilevato, ad esempio mkcd mydierctory/newsub creerà felicemente mydierctory e mydierctory/newsub quando intendevi creare newsub allinterno del esistente mydirectory.)
  • Se largomento inizia con - ma non è “t solo -, quindi mkdir e cd lo interpreteranno come unopzione. Se “è solo -, cd lo interpreterà come $OLDPWD. Se it “s + seguito da 0 o più cifre, quindi cd in zsh lo interpreterà come un indice nello stack di directory. Puoi risolvere il primo problema, ma non gli altri due, passando -- prima dellargomento. Puoi risolvere tutti questi problemi anteponendo ./ allargomento se si tratta di “un percorso relativo.
  • mkdir non “t segue CDPATH, ma cd sì, quindi se” hai impostato CDPATH a un valore che “t non inizia con . (una configurazione decisamente insolita), quindi cd potrebbe portarti a una directory diversa da quello che è stato appena creato.Anteporre ./ a percorsi relativi risolve questo problema¹ (fa sì che CDPATH venga ignorato).
  • Se mkdir non riesce, tenta di eseguire cd. Correzione: usa && 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 andare cd in una directory diversa da quella che mkdir ha appena creato in un caso limite: se largomento di mkcd contiene .. e passa attraverso un collegamento simbolico. Ad esempio, se la directory corrente è /tmp/here e mylink è un collegamento simbolico a /somewhere/else , quindi mkdir mylink/../foo crea /somewhere/else/foo mentre cd mylink/../foo diventa foo. Non è sufficiente cercare i collegamenti simbolici nellargomento, 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 è lasciare che il cd integrato risolva tutto .. prima i componenti del percorso (non “ha senso utilizzare foo/.. se foo non funziona” non esiste, quindi mkdir non ha mai bisogno di vedere alcun ..).

Arriviamo a questo robusto, anche se leggermente cruento versione:

 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 call?)

Se mkdir fallisce, voglio essere sicuro di non cambiare la directory corrente. Cambiare indietro con cd – o $ OLDPWD non è abbastanza buono se la shell non ce lha permesso di passare alla directory corrente. Inoltre, la chiamata del cd aggiorna OLDPWD, quindi vogliamo farlo solo una volta (o ripristinare OLDPWD).


Ci sono anche modi meno specializzati per non dover ridigitare la parola dalla riga precedente:

  • Digita cd , quindi Esc . (o Alt + . ) per inserire lultimo argomento del comando precedente.
  • cd !$ esegue cd sullultimo argomento del comando precedente.
  • Premi Su per richiamare la riga di comando precedente, quindi modificala per cambiare mkdir in cd.

¹ attenzione tuttavia non funziona in ksh93 dalla u+ versione , corretta in 93u + m / 1.0.0-alpha + d1483150 05/01/2021

Commenti

  • Grazie! Esc. mi sembra il più conveniente, fa la sequenza di tasti avere qualche m speciale significa?
  • ‘ è solo Bash (ed è ereditato da ksh e funziona anche in zsh) sequenza per ” ripeti lultima parola del comando precedente “. Lo uso abbastanza spesso.
  • @Gilles I ‘ comincio a pensare che ” Gilles ” laccount è effettivamente condiviso da un gruppo di esperti. 😉
  • @StephaneChazelas /a/b/..// funzionerebbe effettivamente ma non /a/b/../c. Fisso. ‘ ho rivolto la domanda a un pubblico più ampio.
  • 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 la configurazione e) visualizza /tmp/here/foo che è ciò che è stato creato (e ciò che mi aspettavo). bash crea e modifica erroneamente /var/tmp/somewhere/foo.

Risposta

Non mi sarebbe mai venuto in mente di scrivere questo comportamento perché inserisco quanto segue su base quasi oraria …

$ mkdir someDirectory<ENTER> $ cd !$ 

dove bash sostituisce gentilmente !$ con lultima parola dellultima riga; cioè il nome di directory lungo che hai inserito.

Inoltre, il completamento del nome file è tuo amico in tali situazioni. Se la tua nuova directory fosse lunico file nella cartella, un rapido doppio TAB ti darebbe la nuova directory senza reinserirla.

Anche se è bello che bash ti permetta per creare script 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 unaltra macchina non ti manchi lo zucchero sintattico fornito dai tuoi script personalizzati.

Commenti

Risposta

Se utilizzi Oh mio Zsh, cè “un comando chiamato take che fa esattamente questo. Sarebbe simile a questo.

take myfolder 

Ho trovato questo per caso. Ho appena cercato ed è “elencato su questo cheatsheat dal wiki di Oh My Zsh GitHub. È un comando abbastanza utile e apparentemente molto facile da creare da solo.

Commenti

  • Non ho mai saputo di take 🙂 Perfetto! btw – iTerm2 con Oh My Zsh. In realtà ci sono 3 risposte perfette qui. Questa, quella di @jes ú s-carrera, e la risposta selezionata. Dipende dalla configurazione e dalle preferenze.

Risposta

Come da 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à.

Commenti

  • Lopzione -p per mkdir sopprimerà gli errori.
  • mcd è un comando già esistente. Anche se ‘ hai appena fornito un esempio, lho usato io stesso perché ‘ una lettera più corta di mkcd.
  • @Dharmit Shah: Qual è il comando mcd esistente? Quale pacchetto o progetto fornisce questo comando?
  • mtools fornisce il comando mcd. La sua pagina man dice ” Il comando mcd è usato per cambiare la directory di lavoro di mtools sul disco MS-DOS. ”

Risposta

Oppure puoi semplicemente creare una breve variabile al volo e usarla due volte x = longproject ; mkdir $x ; cd $x – che ammetto sia ancora più lungo rispetto allutilizzo di una funzione shellscript 🙂

Answer

Questo è un cosa semplice da fare in uno script / funzione bash. Ho creato un tutorial molto leggibile e sufficientemente documentato, inclusi script che funzionano sia su Linux che su MacOS (anche questo sarà mantenuto in futuro).

Il mio obiettivo per la complessità del tutorial è: scritto per un pubblico mirato con lunico prerequisito è che lutente abbia il polso e sappia leggere linglese, quindi fornisci un feedback se hai bisogno di assistenza.

https://github.com/craigopie/shellscripts

 mcdir() { if [ $# -eq 0 ] || [ $1 = "-h" ] || [ $1 = "--help" ] then echo "Usage: [option...] {directory}" echo " -p, --path Create all directories in path " echo " -h, --help Shows this helpful information " echo return 0 fi ## create directory with a path if [ $1 = "-p" ] || [ $1 = "--path" ] then mkdir -p "$2" &>/dev/null if [ $? -gt 0 ] then echo "There was a problem creating your directory." return 1 fi cd "$2" &>/dev/null if [ $? -gt 0 ] then echo "Unable to change into that directory." return 1 fi return 0 fi ## create directory in this location mkdir "$1" &>/dev/null if [ $? -gt 0 ] then echo "There was a problem creating your directory." return 1 fi cd "$1" &>/dev/null if [ $? -gt 0 ] then echo "Unable to change into that directory." return 1 fi return 0 } export -f mcdir  

Per installarlo hai due opzioni:

  • La prima è aggiungere la funzione al tuo file .bashrc.
  • La seconda è aggiungere il file al tuo percorso e poi cerca il file nel tuo file .bash_profile.

Anche in questo caso, il file README è molto dettagliato su come farlo.

Buona fortuna!

Risposta

Ecco “una piccola variante che merita di essere menzionata:

function mkdir() { local dir=$1 command mkdir "$dir" && cd "$dir" } 

Aggiungilo a te ur ~/.bash_profile e puoi quindi utilizzare mkdir normalmente (una volta che “hai source” d it), tranne che ora eseguirà la funzione sopra invece del comando mkdir standard.

Nota, questo non convalida linput secondo il risposta di Gilles , ma dimostra come puoi (efficacemente) sovrascrivere i builtin.

Dal docs (parafrasando leggermente):

command mkdir [args] viene eseguito mkdir con args ignorando qualsiasi funzione della shell denominata mkdir. Vengono eseguiti solo i comandi incorporati della shell oi comandi trovati cercando nel PERCORSO. Se è presente una funzione shell denominata ls, lesecuzione di command ls allinterno della funzione eseguirà il comando esterno ls invece di chiamare la funzione in modo ricorsivo

Credo che builtin ottenga un risultato simile a command.

Commenti

  • dovresti assolutamente citare $dir
  • @Jeff, daccordo, ma la risposta accettata ha tutta la convalida necessaria.’ sto solo presentando luso di command come alternativa.

Rispondi

Aggiunta di una funzione di supporto a BASH, ZSH o KSH

Crea il comando mkcd nel tuo ambiente in una riga

echo -e "mkcd() {\n mkdir -p "$1" && cd $_\n}" >> ~/.${0//-/}rc && . ~/.${0//-/}rc 

Risposta

Se stai usando Oh-my-zsh , il comando take farà il trucco. Dai unocchiata al cheat sheet .

Risposta

Ho appena automatizzato le risposte precedenti e creato uno script eseguibile una tantum:

fun=" mkcd () { mkdir -p -- "$1" && cd -P -- "$1" }" echo "$fun" >> ~/.bashrc 

Copia semplicemente questo in un nuovo file mkcd.sh ed eseguilo solo una volta nel terminale da bash mkcd.sh. Quindi esegui source ~/.bashrc per farlo funzionare nella sessione corrente.

Successivamente, puoi utilizzare mkcd some_dir per creare e inserisci direttamente in quella directory.

Commenti

  • Suggerisci di scrivere uno script (in un file) il cui unico scopo è quello di aggiungere al ~/.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 della semplice modifica di ~/.bashrc. Che vantaggio ha questo rispetto alla risposta accettata? … … … … … … … … … … … … … … … … … … … … … … … P.S. Questo fallirà a causa di problemi di citazione, il che mi dice che non lhai nemmeno provato da solo.
  • Mi dispiace dirlo ma sì, come ho scritto nella mia risposta, ho usato le risposte sopra. Funziona. Se ‘ non mi credi, provalo. E riguardo al non provare, oggi ho usato tutta la mia giornata per scrivere tali script in bash e python.
  • Ho provato quello che hai scritto. non funziona.

Lascia un commento

Il tuo indirizzo email non sarà pubblicato. I campi obbligatori sono contrassegnati *