Encontro-me 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.
mkdir longtitleproject
entãocd !^
Encontro-me 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.
mkdir longtitleproject
entãocd !^
Respostas:
Não há comando interno, mas você pode escrever facilmente uma função que chama mkdir
então cd
:
mkcd () {
mkdir "$1"
cd "$1"
}
Coloque esse código no 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ê a executar.
Esta versão simples possui vários defeitos:
-p
opção 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á com alegria mydierctory
e mydierctory/newsub
quando você pretende criar newsub
dentro do existente mydirectory
.)-
, mas não é apenas -
, em seguida, mkdir
e cd
irá interpretá-lo como uma opção. Se for justo -
, então cd
o interpretará como significando $OLDPWD
. Se for +
seguido por 0 ou mais dígitos, o cd
zsh o interpretará 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 anexando ./
o argumento se for um caminho relativo.mkdir
não segue CDPATH
, mas segue ; cd
portanto, se você definiu CDPATH
um valor que não começa com .
(uma configuração reconhecidamente um tanto incomum), cd
poderá levá-lo para um diretório diferente daquele que foi criado. A adição ./
de caminhos relativos corrige isso (faz CDPATH
com que seja ignorado).mkdir
falhar, 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"
}
Essa versão ainda tem o potencial de cd
entrar em um diretório diferente daquele que mkdir
acabou de ser criado em um caso de borda: se o argumento mkcd
contiver ..
e passar por um link simbólico. Por exemplo, se o diretório atual é /tmp/here
e mylink
é um link simbólico para /somewhere/else
, em seguida, 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, portanto cd /tmp/mylink; mkdir ../foo; cd ../foo
, não muda para o novo diretório ( /somewhere/else/foo
), mas para /tmp/foo
. Uma correção para isso é permitir que o cd
interno resolva todos os ..
componentes do caminho primeiro (não faz sentido usar foo/..
sefoo
não existe, então mkdir
nunca precisa ver nenhum ..
).
Chegamos a esta 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 na primeira cd
chamada?)
Se o 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 o diretório atual. Além disso, a chamada de CD atualiza o OLDPWD, portanto, queremos fazê-lo apenas uma vez (ou restaurar o OLDPWD).
Também existem maneiras menos especializadas de não precisar digitar novamente a palavra da linha anterior:
cd
, então Esc .(ou Alt+ .) para inserir o último argumento do comando anterior.cd !$
executa cd
no último argumento do comando anterior.mkdir
para cd
.ksh
, e também funciona em zsh
) para "repetir a última palavra do comando anterior". Eu o uso com bastante frequência.
/a/b/..//
realmente funcionaria, mas não /a/b/../c
. Fixo. Eu coloquei a questão para um público mais amplo.
mkcd() { mkdir -p "$1" && cd "$1"; }
não parece ser um problema no (meu exemplo 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 o /tmp/here/foo
que foi criado (e o que eu esperava). bash
cria e altera erroneamente para /var/tmp/somewhere/foo
.
Este é o one-liner que você precisa. Nenhuma outra configuração é necessária:
mkdir longtitleproject && cd $_
A $_
variável, em bash, é o último argumento dado ao comando anterior. Nesse caso, o nome do diretório que você acabou de criar. Como 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 em uma nova pasta em casa !! (ou ~ / nova pasta)
mkdir foo && cd foo
, o que não é útil.
Nunca me ocorreu escrever esse comportamento porque eu insiro o seguinte quase que de hora em hora ...
$ mkdir someDirectory<ENTER>
$ cd !$
onde bash gentilmente substitui !$
a última palavra da última linha; ou seja, o nome do diretório longo que você digitou.
Além disso, a conclusão do nome do arquivo é seu amigo nessas situações. Se o seu novo diretório fosse o único arquivo na pasta, um duplo rápido TABforneceria o novo diretório sem precisar digitá-lo novamente.
Embora seja legal que o bash permita que você crie scripts de tarefas comuns, como 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 a sintaxe sintática. açúcar que seus scripts personalizados fornecem.
De acordo com Quais personalizações você fez no 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.
-p
opção para mkdir suprimirá erros.
mcd
comando existente ? Qual pacote ou projeto fornece esse comando?
Se você usar Oh My Zsh, há um comando chamado take que faz exatamente isso. Seria algo assim.
take myfolder
Na verdade, encontrei este por acidente. Eu apenas olhei e está listado neste truque do wiki Oh My Zsh GitHub. É um comando bastante útil e aparentemente muito fácil de se criar.
take
:) Perfeito! btw - iTerm2 com Oh My Zsh. Na verdade, existem 3 respostas perfeitas aqui. Este, o de @ jesús-carrera, e a resposta selecionada. Depende da sua configuração e preferência.
Aqui está uma pequena variante que vale a pena mencionar:
function mkdir() {
local dir=$1
command mkdir "$dir" && cd "$dir"
}
Adicione isso ao seu ~/.bash_profile
e você poderá usá-lo mkdir
normalmente (assim que o desejar source
), exceto que agora ele executará a função acima, em vez do mkdir
comando padrão .
Observe que isso não valida a entrada de acordo com a resposta aceita por Gilles , mas demonstra como você pode (efetivamente) substituir os componentes internos.
Dos documentos (parafraseando um pouco):
command mkdir [args]
corremkdir
comargs
ignorando qualquer função shell chamadomkdir
. Apenas comandos internos do shell ou comandos encontrados pesquisando o PATH são executados. Se houver uma função shell nomeadals
, a execuçãocommand ls
dentro da função executará o comando externo emls
vez de chamar a função recursivamente
Eu acredito que builtin
alcança um resultado semelhante ao command
.
$dir
command
como alternativa.
Eu criei um script que cria o diretório e, em seguida, o CD, e dei um apelido. E aqui está uma essência onde eu a descrevo.
https://gist.github.com/rehnen/34236d6ff270ccaa74b6#mkdir-like-it-was-meant-to-be
Apenas automatizou as respostas acima e criou um script executável único:
fun='
mkcd ()
{
mkdir -p -- "$1" && cd -P -- "$1"
}'
echo "$fun" >> ~/.bashrc
Apenas copie isso 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 inserir diretamente nesse diretório.
~/.bashrc
arquivo (com uma resposta que já foi dada)? E como você sugere a criação desse mkcd.sh
script? Com um editor, talvez? Parece mais trabalho do que apenas editar ~/.bashrc
. Que vantagem isso tem sobre a resposta aceita? ....
mcd
A partir de unix.stackexchange.com/questions/6628/…