Não há comando interno, mas você pode escrever facilmente uma função que chama mkdir then cd :
mkcd () {
mkdir "$1"
cd "$1"
}
Coloque este código no seu arquivo ~/.bashrc (ou ~/.kshrc para usuários do ksh ou ~/.zshrc para usuários do zsh). Define uma função chamada mkcd . "$1" será substituído pelo argumento da função quando você executá-lo.
Esta versão simples tem vários defeitos:
- Você não pode criar uma cadeia de subdiretórios de uma só vez. Correção: passe a opção
-pparamkdir. (Isso pode ou não ser desejável, pois aumenta o risco de um erro de digitação não ser detectado, por exemplo,mkcd mydierctory/newsubterá prazer em criarmydierctoryemydierctory/newsubquando você pretende criarnewsubdentro domydirectoryexistente.) - Se o argumento começar com
-, mas não for apenas-, entãomkdirecdo interpretarão como uma opção. Se for apenas-, entãocdinterpretará como$OLDPWD. Se for+seguido por 0 ou mais dígitos, entãocdem zsh irá interpretá-lo como um índice na pilha de diretórios. Você pode corrigir o primeiro problema, mas não os outros dois, passando--antes do argumento. Você pode corrigir todos esses problemas, adicionando./ao argumento se for um caminho relativo. -
mkdirnão segueCDPATH, mascd, portanto, se você definiuCDPATHcomo um valor que não começa com.(uma configuração reconhecidamente um tanto incomum), entãocdpode levar você a um diretório diferente daquele que acabou de ser criado. Colocar./nos caminhos relativos corrige isso (faz com queCDPATHseja ignorado). - Se
mkdirfalhar, ele tentará executarcd. Correção: use&¶ separar os dois comandos.
Ainda bastante simples:
mkcd () {
case "$1" in /*) :;; *) set -- "./$1";; esac
mkdir -p "$1" && cd "$1"
}
Esta versão ainda tem o potencial de tornar cd em um diretório diferente daquele que mkdir acabou de criar em um caso de borda: se o argumento para mkcd contiver .. e passar por um link simbólico . Por exemplo, se o diretório atual for /tmp/here e mylink for um link simbólico para /somewhere/else , então mkdir mylink/../foo criará /somewhere/else/foo , enquanto cd mylink/../foo será alterado para foo . Não é suficiente procurar links simbólicos no argumento, porque o shell também rastreia links simbólicos em seu próprio diretório atual, portanto, cd /tmp/mylink; mkdir ../foo; cd ../foo não é alterado para o novo diretório ( /somewhere/else/foo ), mas para /tmp/foo . Uma correção para isso é deixar o cd builtin resolver todos os componentes .. path primeiro (não faz sentido usar foo/.. if foo não existe, portanto mkdir nunca precisa ver nenhum .. ).
Chegamos a essa versão robusta, embora um pouco sangrenta:
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
}
(Exercício: por que estou usando um subshell para a primeira chamada cd ?)
If mkdir fails, I want to be sure not to change the current directory. Changing back with cd - or $OLDPWD isn't good enough if the shell doesn't have permission to change into its current directory. Also, calling cd updates OLDPWD, so we only want to do it once (or restore OLDPWD).
Há também formas menos especializadas de não precisar redigitar a palavra da linha anterior:
- Digite
cd, então Esc . (ou Alt + . ) para inserir o último argumento do comando anterior. -
cd !$executacdno último argumento do comando anterior. - Pressione Para cima para recuperar a linha de comando anterior e edite-a para alterar
mkdirparacd.