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
amkdir
. (Questo può essere desiderabile o meno, poiché aumenta il rischio che un errore di battitura non venga rilevato, ad esempiomkcd mydierctory/newsub
creerà felicementemydierctory
emydierctory/newsub
quando intendevi crearenewsub
allinterno del esistentemydirectory
.) - Se largomento inizia con
-
ma non è “t solo-
, quindimkdir
ecd
lo interpreteranno come unopzione. Se “è solo-
,cd
lo interpreterà come$OLDPWD
. Se it “s+
seguito da 0 o più cifre, quindicd
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 segueCDPATH
, macd
sì, quindi se” hai impostatoCDPATH
a un valore che “t non inizia con.
(una configurazione decisamente insolita), quindicd
potrebbe portarti a una directory diversa da quello che è stato appena creato.Anteporre./
a percorsi relativi risolve questo problema¹ (fa sì cheCDPATH
venga ignorato). - Se
mkdir
non riesce, tenta di eseguirecd
. 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 !$
eseguecd
sullultimo argomento del comando precedente. - Premi Su per richiamare la riga di comando precedente, quindi modificala per cambiare
mkdir
incd
.
¹ 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 inzsh
) 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
- Cè un buon posto per scoprire le più importanti stranezze di bash come questa?
- @ dominicbri7 In generale rientra nella ” modifica della riga di comando bash ” Googling stesso fornisce quanto segue come risultato principale web.mit.edu/gnu/doc/html/features_7.html Più specificamente,! $ è un esempio di Word Designator vedi gnu.org/software /bash/manual/bashref.html#Word-Designators
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 eseguitomkdir
conargs
ignorando qualsiasi funzione della shell denominatamkdir
. Vengono eseguiti solo i comandi incorporati della shell oi comandi trovati cercando nel PERCORSO. Se è presente una funzione shell denominatals
, lesecuzione dicommand ls
allinterno della funzione eseguirà il comando esternols
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 questomkcd.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.
mcd
da unix.stackexchange.com/questions/6628/…mkdir longtitleproject
quindicd !^