Existe uma linha única que me permite criar um diretório e mover para ele ao mesmo tempo?

Eu me pego repetindo muito:

 mkdir longtitleproject cd longtitleproject  

Existe uma maneira de fazer isso em uma linha sem repetir o nome do diretório? Estou na festa aqui.

Comentários

Resposta

Este é o one-liner de que você precisa. Nenhuma outra configuração necessária:

mkdir longtitleproject && cd $_ 

A variável $_, em bash, é o último argumento dado ao comando anterior. Neste caso, o nome do diretório que você acabou de criar. Conforme explicado em 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. 

Use cd $_ para recuperar o último argumento do comando anterior em vez de cd !$ porque cd !$ fornece o último argumento do comando anterior no histórico do shell :

cd ~/ mkdir folder && cd !$ 

você acaba em casa (ou ~ /)

cd ~/ mkdir newfolder && cd $_ 

você acaba na nova pasta em casa !! (ou ~ / newfolder)

Comentários

  • Por que diabos esta não é a resposta aceita
  • @JSmyth eu concordo , este é um one-liner que usa funcionalidade de shell nativa
  • Acho que o OP está tentando evitar o uso dos dois comandos. Essa resposta é (quase) tão válida quanto fazer mkdir foo && cd foo, que não ‘ t útil.
  • O OP é pedindo um one-liner que não ‘ requeira a repetição do nome do diretório, e é isso
  • Pelos votos positivos, ‘ s evidente que muitas pessoas estão achando essa resposta útil. Eu ‘ direi porque não ‘ selecione esta resposta: Eu ‘ muito provavelmente digitará incorretamente && cd $_ já que as teclas estão muito longe da linha inicial, portanto, embora tecnicamente corretas, ‘ não são ergonômicas. Agradeço o fato de que ‘ não depende do ambiente e ‘ é útil saber. Obrigado!

Resposta

Não há comando embutido, mas você pode facilmente escrever uma função que chama mkdir e cd:

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

Insira este código seu ~/.bashrc arquivo (ou ~/.kshrc para usuários ksh ou ~/.zshrc para usuários zsh). Ele define uma função chamada mkcd. "$1" será substituído pelo argumento da função quando você executá-la.

Esta versão simples tem vários defeitos:

  • Você não pode criar uma cadeia de subdiretórios de uma vez. Correção: passe a opção -p para mkdir. (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/newsub criará mydierctory e mydierctory/newsub quando você pretendia criar newsub dentro do existente mydirectory.)
  • Se o argumento começar com -, mas não for apenas -, então mkdir e cd irão interpretá-lo como uma opção. Se for apenas -, então cd interpretará como $OLDPWD. é “s + seguido por 0 ou mais dígitos, então cd em zsh irá interpretá-lo como um índice na pilha do diretório. 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.
  • mkdir não segue CDPATH, mas cd segue, então se você “definir CDPATH a um valor que não começa com . (uma configuração reconhecidamente um tanto incomum), então cd pode levá-lo a um diretório diferente do aquele que acabou de ser criado.Anexar ./ a caminhos relativos corrige isso¹ (faz com que CDPATH seja ignorado).
  • Se mkdir falha, ele tenta executar cd. Correção: use && para 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 fazer cd ir para um diretório diferente daquele que mkdir acabou de criar em um caso extremo: se o argumento para mkcd contiver .. e passa 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 cria /somewhere/else/foo enquanto cd mylink/../foo muda 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, então cd /tmp/mylink; mkdir ../foo; cd ../foo não muda para o novo diretório (/somewhere/else/foo), mas em /tmp/foo. Uma solução para isso é deixar o cd integrado resolver tudo .. componentes do caminho primeiro (não faz sentido usar foo/.. se foo não ” não existem, então mkdir nunca precisa ver nenhum ..).

Chegamos a este robusto, embora ligeiramente sangrento versão:

 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 o primeiro cd chamar?)

Se mkdir falhar, quero ter certeza de não alterar o diretório atual. Mudar de volta com cd – ou $ OLDPWD não é bom o suficiente se o shell não tiver permissão para mudar para seu diretório atual. Além disso, chamar o cd atualiza o OLDPWD, então queremos fazer isso apenas uma vez (ou restaurar o OLDPWD).


Existem também maneiras menos especializadas para não ter que redigitar a palavra da linha anterior:

  • Digite cd e, em seguida, Esc . (ou Alt + . ) para inserir o último argumento do comando anterior.
  • cd !$ executa cd no último argumento do comando anterior.
  • Pressione para cima para recuperar a linha de comando anterior e edite-a para mudar mkdir para cd.

¹ cuidado, entretanto, não funciona no ksh93 desde a u+ versão , corrigido em 93u + m / 1.0.0-alpha + d1483150 2021-01-05

Comentários

  • Obrigado! o Esc. parece o mais conveniente para mim, faz a sequência de teclas tem algum m especial entendendo?
  • É ‘ é apenas o Bash (e herdado de ksh, e também funciona em zsh) sequência para ” repetir a última palavra do comando anterior “. Eu o uso com bastante frequência.
  • @Gilles I ‘ estou começando a achar que o ” Gilles ” a conta é compartilhada por um painel de especialistas. 😉
  • @StephaneChazelas /a/b/..// funcionaria na verdade, mas não /a/b/../c. Fixo. Eu ‘ fiz a pergunta a um público mais amplo.
  • mkcd() { mkdir -p "$1" && cd "$1"; } não ‘ t parece ser um problema em (minha instância de) 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 (inclui a configuração e) exibe /tmp/here/foo que é o que foi criado (e o que eu esperava). bash cria e muda erroneamente para /var/tmp/somewhere/foo.

Resposta

Nunca teria me ocorrido criar um script desse comportamento, porque eu insiro o seguinte quase de hora em hora …

$ mkdir someDirectory<ENTER> $ cd !$ 

onde bash gentilmente substitui !$ pela última palavra da última linha; ou seja, o nome longo do diretório que você inseriu.

Além disso, a conclusão do nome do arquivo é sua amiga em tais situações. Se o seu novo diretório fosse o único arquivo na pasta, uma rápida TAB dupla forneceria o novo diretório sem inseri-lo novamente.

Embora seja legal que o bash permita para criar scripts de tarefas comuns conforme as outras respostas sugerem, acho melhor aprender os recursos de edição de linha de comando que o bash tem a oferecer para que, quando você estiver trabalhando em outra máquina, não perca o açúcar sintático que seus scripts personalizados fornecem.

Comentários

Resposta

Se você usar Oh meu Zsh, há “um comando chamado take que faz exatamente isso. Seria mais ou menos assim.

take myfolder 

Na verdade, encontrei este por acidente. Acabei de olhar e está listado em este cheatsheat do wiki Oh My Zsh GitHub. É um comando bastante útil e aparentemente muito fácil de criar você mesmo.

Comentários

  • Nunca soube sobre take 🙂 Perfeito! btw – iTerm2 com Oh My Zsh. Na verdade, existem 3 respostas perfeitas aqui. Esta, aquela de @jes ú s-carrera, e a resposta selecionada. Depende de sua configuração e preferência.

Resposta

Conforme Que personalizações você fez em seu perfil de shell para aumentar a produtividade? , é assim que eu faço:

# make a directory and cd to it mcd() { test -d "$1" || mkdir "$1" && cd "$1" } 

significa que também funciona se o diretório já existir.

Comentários

  • A opção -p para mkdir suprimirá os erros.
  • mcd é um comando já existente. Embora você ‘ tenha dado um exemplo, usei-o pessoalmente como ‘ uma letra menor que mkcd.
  • @Dharmit Shah: Qual é o comando mcd existente? Qual pacote ou projeto fornece este comando?
  • mtools fornece o comando mcd. Sua página de manual diz ” O comando mcd é usado para alterar o diretório de trabalho mtools no disco MS-DOS. ”

Resposta

Ou você pode apenas criar uma variável curta na hora e usá-la duas vezes x = longproject ; mkdir $x ; cd $x – que eu admito ainda é mais longo do que usar uma função shellscript 🙂

Resposta

Este é um coisa simples de fazer em um script / função bash. Eu criei um tutorial muito legível e suficientemente documentado, incluindo scripts que funcionam em Linux e MacOS (isso também será mantido no futuro).

Meu objetivo para a complexidade do tutorial é: escrito para um público-alvo com os únicos pré-requisitos sendo que o usuário tem pulso e pode ler em inglês, então forneça feedback se precisar de ajuda.

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  

Para instalar, você tem dois opções:

  • Primeiro é adicionar a função ao seu arquivo .bashrc.
  • O segundo é adicionar o arquivo ao seu caminho e, em seguida, codifique o arquivo em seu .bash_profile arquivo.

Novamente, o arquivo README é muito detalhado sobre como fazer isso.

Boa sorte!

Resposta

Aqui está uma pequena variante que vale a pena mencionar:

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

Adicione isto a você ur ~/.bash_profile e você pode usar mkdir normalmente (uma vez que você “ve source” d), exceto que agora ele executará a função acima em vez do comando mkdir padrão.

Observe que isso não valida a entrada de acordo com o resposta de Gilles , mas demonstra como você pode (efetivamente) substituir builtins.

Do docs (parafraseando um pouco):

command mkdir [args] executa mkdir com args ignorando qualquer função shell chamada mkdir. Somente comandos internos de shell ou comandos encontrados pesquisando o PATH são executados. Se houver uma função shell chamada ls, executar command ls dentro da função executará o comando externo ls em vez de chamar a função recursivamente

Eu acredito que builtin obtém um resultado semelhante a command.

Comentários

  • você definitivamente deve citar $dir
  • @Jeff, concordo, mas a resposta aceita tem toda a validação necessária.Eu ‘ estou apenas apresentando o uso de command como alternativa.

Resposta

Adicionando função auxiliar ao BASH, ZSH ou KSH

Crie o comando mkcd em seu ambiente em uma linha

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

Resposta

Se você estiver usando Oh-my-zsh , o comando take resolverá o problema. Dê uma olhada na folha de dicas .

Resposta

Apenas automatizei as respostas acima e criei um script executável único:

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

Basta copiar em um novo arquivo mkcd.sh e execute-o apenas uma vez no terminal por bash mkcd.sh. Em seguida, execute source ~/.bashrc para fazê-lo funcionar na sessão atual.

Depois disso, você pode usar mkcd some_dir para criar e entre diretamente nesse diretório.

Comentários

  • Você sugere escrever um script (em um arquivo) cujo único propósito é anexar ao ~/.bashrc arquivo (com uma resposta que já foi dada)? E como você sugere a criação deste script mkcd.sh? Com um editor, talvez? Isso parece mais trabalhoso do que apenas editar ~/.bashrc. Que vantagem isso tem sobre a resposta aceita? …………………………………………………………………… P.S. Isso falhará por causa de problemas de citação, o que me diz que você nem mesmo tentou.
  • Lamento dizer, mas sim, como escrevi em minha resposta, usei as respostas acima. Funciona. Se você não ‘ não acredita em mim, experimente. E sobre não tentar, usei meu dia inteiro para escrever esses scripts em bash e python hoje.
  • Eu tentei o que você escreveu. não funciona.

Deixe uma resposta

O seu endereço de email não será publicado. Campos obrigatórios marcados com *