Não sei dizer quantas vezes desejei um comando que crie um diretório e mude para esse diretório. Basicamente, eu gostaria do equivalente ao seguinte:
mkdir -p /arbitrarily/long/path; cd /arbitrarily/long/path
mas apenas tendo que digitar /arbitrarily/long/path
uma vez, algo como:
mk-cd /arbitrarily/long/path
Tentei criar um script para fazer isso, mas ele apenas altera o diretório dentro do script. Eu gostaria que o diretório no shell também tivesse mudado.
#!/bin/bash
mkdir $1
cd $1
export PWD=$PWD
Como eu posso fazer isso funcionar?
cd
, você escolheu um caso especial desde o início. : Dcd
informações relacionadas a informações muito legais (retorne ao diretório anterior usandocd -
, usepushd
epopd
para manter uma "pilha" de diretórios): superuser.com/questions/324512/…mkdir -p /very/long/path
, usarcd
espaço e pressionar Alt +.
para repetir o último argumento, ou seja, o nome do diretório.mkdir -p /very/long/path; cd !#:2
. A string!#:2
será expandida para o argumento nr. 2 (ou seja, o terceiro argumento/very/long/path
, conforme a contagem começa com zero).!$
. Eu uso esse truque em particular o tempo todo, embora haja muito mais a fazer com a expansão do histórico .Respostas:
A maneira mais simples é usar uma função shell:
Coloque-o no seu
.bashrc
arquivo para torná-lo disponível, assim como outro comando do shell.A razão pela qual ele não funciona como um script externo é
cd
altera o diretório atual do script em execução, mas não afeta o chamado. Isso é por design! Cada processo tem seu próprio diretório de trabalho que é herdado por seus filhos, mas o oposto não é possível.A menos que parte de um pipeline seja executado em segundo plano ou explicitamente em um subshell, uma função shell não é executada em um processo separado, mas no mesmo, como se o comando tivesse sido originado. O shell do diretório atual pode ser alterado por uma função.
O
&&
usado aqui para separar os dois comandos utilizados significa que, se o primeiro comando for bem-sucedido (mkdir
), execute o segundo (cd
). Consequentemente, semkdir
não conseguir criar o diretório solicitado, não faz sentido tentar entrar nele. Uma mensagem de erro é impressamkdir
e é isso.A
-p
opção usada commkdir
existe para informar este utilitário para criar qualquer diretório ausente que faça parte do caminho completo do nome do diretório passado como argumento. Um efeito colateral é que, se você pedir para criar um diretório já existente, amkcd
função não falhará e você terminará nesse diretório. Isso pode ser considerado um problema ou um recurso. No primeiro caso, a função pode ser modificada, por exemplo, da maneira que simplesmente avisa o usuário:Sem a
-p
opção, o comportamento da função inicial teria sido muito diferente.Se o diretório que contém o diretório a ser criado ainda não existir,
mkdir
a função também falhará.Se o diretório a ser criado já existir,
mkdir
falhará também ecd
não será chamado.Por fim, observe que a configuração / exportação
PWD
é inútil, como o shell já faz internamente.Editar: adicionei a
--
opção aos dois comandos da função para permitir um nome de diretório que comece com um traço.fonte
~/.bashrc
ou um dos outros scripts de inicialização.alias mk-cd 'mkdir -p \!:1; cd \!:1'
sem uma função? Ou talvez eu devesse começar a pensar nas funções do bash mais como aliases estendidos?csh
mecanismo de passagem de argumentos não é implementado com aliases de estilo bourne. As funções são realmente o caminho a percorrer, sendo muito mais flexíveis.bar
). Outra opção seria usarhistory 1
, como emalias mk-cd='args="$(history 1)" && args="${args#*mk-cd\ }" && mkdir -p "$args" && cd'
- isso funciona bem para o exemplo do questionador, mas não é uma solução geral, pois qualquer outro comando na mesma linha (por exemplo, canalizar a saída) fará com que ela falhe.Eu gostaria de adicionar uma solução alternativa.
Seu script vai funcionar se você invocá-lo com o
.
ousource
comando:Se você fizer isso
export
, o script não será necessário. Você pode ignorar a digitação.
usando umalias
:A razão pela qual isso funciona é que um script normalmente é executado em um sub shell, para que seu ambiente seja perdido na conclusão, mas o comando
.
(ousource
) o força a executar no shell atual.Essa técnica pode ser útil para seqüências de comandos que são muito complexas para uma função ou que estão em desenvolvimento e são frequentemente editadas: uma vez
alias
inserida.bash_aliases
, você pode editar o script à vontade sem reinicializar.Observe o seguinte: -
Se você escrever um script que deve ser chamado com o comando
.
/source
, há duas maneiras de garantir isso:Por alguma razão, um script invocado com
.
/source
não precisa ser executável; portanto, remova essa permissão e o script não será encontrado em "$ PATH" ou causará um erro de permissão se invocado com um caminho explícito.Como alternativa, o seguinte truque pode ser usado na cabeça do script:
Isso funciona porque em um sub-shell
bind
emite um aviso, embora não haja status de erro: portanto,read
é usado para dar um erro em nenhuma entrada.fonte
.
. Já fiz. .bashrc
inúmeras vezes, mas não sabia exatamente o que.
faz. É semelhante aexport
?export var
copia a variável internavar
para o ambiente, onde é herdada e importada como variável em qualquer sub shell, mas não tem efeito em um shell pai. Normalmente, um sub-shell é criado para executar um script e todas as alterações que ele faz (incluindo variáveis exportadas) são perdidas quando concluídas. Para que um script defina variáveis em um shell, ele deve ser executado nesse shell, e é isso que o.
comando faz: execute o script sem criar um sub shell. Curiosamente, os scripts executados por.
não precisam ter permissão executável..
eexport
, o título desta pergunta não levaria você a esperar uma resposta aqui, então deixarei minha resposta como está, mas obrigado pelo seu comentário.Não é um comando único, mas você não precisa digitar novamente todo o caminho usado
!$
(que é o último argumento do comando anterior no histórico do shell).Exemplo:
fonte
Criando aliases . Maneira muito popular de criar seus próprios comandos.
Você pode criar um alias rapidamente:
É isso aí. Se você deseja manter esse alias permanentemente (não apenas a sessão atual), coloque esse comando em um arquivo de pontos (normalmente ~ / .bash_aliases ou ~ / .bash_profile).
fonte
Além do que já foi sugerido, eu gostaria de recomendar o caralho . É uma estrutura Python para otimizar seu processo de shell, corrigindo erros. Inspirado por esse tweet , tudo o que você precisa fazer é digitar seu alias configurado (por padrão
fuck
) e ele tentará corrigir o comando anterior. Uma de suas correções se comporta da seguinte maneira:fonte