Desejo executar um script para simplesmente alterar o diretório de trabalho atual:
#!/bin/bash cd web/www/project
Mas, depois de executá-lo, o pwd atual permanece o mesmo! Como posso fazer isso?
Resposta
É um comportamento esperado. O script é executado em um subshell e não pode alterar o diretório de trabalho do shell pai. Seus efeitos são perdidos quando termina.
Para alterar o diretório do shell atual permanentemente, você deve usar o comando source
, também conhecido como .
, que executa um script no ambiente do shell atual em vez de um sub shell.
Os seguintes comandos são idênticos:
. script
ou
source script
Comentários
Resposta
Para pequenas tarefas como esta, em vez de criar um script, crie um alias como este,
$ alias cdproj="cd /dir/web/www/proj"
Você deve adicionar isso ao seu .bashrc
arquivo, se você quiser que seja definido para cada shell interativo.
Agora você pode executá-lo como $ cdproj
.
Comentários
- Você também pode fazer o script ecoar os comandos a serem executados e, em seguida, usar
eval `./script`
oueval $(./script)
para executar esses comandos. Esta é uma abordagem comum para comandos que precisam atualizar o ambiente do ‘ s do shell invocador. - Apenas tome muito cuidado com o que você produz, se for a abordagem
eval
.
Resposta
Use exec bash
no final
Um script bash opera em seu ambiente atual ou no de seus filhos, mas nunca em seu ambiente pai.
No entanto, essa pergunta costuma ser feita porque se deseja ser deixado na festa prompt em um determinado diretório após a execução de um script bash de outro diretório.
Se for esse o caso, simplesmente execute uma instância bash filha no final do script:
#!/usr/bin/env bash cd desired/directory exec bash
Isso cria um novo subshell. Digite Ctrl + D ou exit
para retornar ao primeiro shell onde o script foi inicialmente iniciado.
Atualizar
Pelo menos com as versões mais novas de bash
, o exec
na última linha não é mais necessário. Além disso, o script pode ser feito para funcionar com qualquer shell preferido usando a variável de ambiente $SHELL
. Em seguida, ele fornece:
#!/usr/bin/env bash cd desired/directory $SHELL
Comentários
- Melhor apenas fornecer o script, como na resposta aceita : usar
exec
é normalmente considerado o último recurso de um canalha .. 🙂 - este truque não ‘ t trabalhe no debian 9 stretch.
- Esta é a maneira errada de fazer isso!
- Já que ninguém detalhou os problemas com isso (estou olhando para você, @Dennis): (1) Cada vez que você executa isso, ele cria um novo processo bash persistente. Faça isso dez ou vinte vezes em uma sessão, e você terá 11 a 21 processos bash empilhados. Isso pode afetar o desempenho e, se você tentar encerrar a sessão de forma limpa, digitando
exit
(ou Ctrl + D), você terá que fazer isso 11 a 21 vezes. (2) Outra desvantagem de usar um script executável é que, se você definir quaisquer opções de shell (por exemplo,dotglob
ouglobstar
) em seu sessão de shell interativa, você os perderá, porque está iniciando um novo shell. - Solução muito boa! Eu ‘ reescrevi meu alias em bash_profile, então agora é um script armazenado em um arquivo separado. Eu uso o script para ir para uma pasta temporária recém-criada. E agora é ainda mais fácil ter uma sessão bash temporária. SRP em ação! Obrigado!
Resposta
Embora existam respostas que executam a ação exata que você deseja, um método mais padrão para tal o objetivo é criar um link simbólico:
ln -s ~/web/www/project proj #use full path to dir!
Então você poderia cd
para o diretório usando o nome proj
:
cd proj
Este método é mais flexível porque você pode acessar arquivos usando o nome curto sem cd
:
ls proj/ #note the endslash! vim proj/file.x
Resposta
Depende do que você “vamos fazer, outra solução pode ser criar uma função em vez de um script.
Exemplo:
Crie uma função em um arquivo, digamos /home/aidin/my-cd-script
:
function my-cd() { cd /to/my/path }
Em seguida, inclua-o em bashrc
ou zshrc
arquivo:
# Somewhere in rc file source /home/aidin/my-cd-script
Agora você pode usá-lo como um comando:
$ my-cd
Resposta
Se você mudar entre diretórios distantes no sistema de arquivos. Vou recomendar o autojump .
Resposta
Para mim, a abordagem mais conveniente e flexível era uma mistura de um alias e um script:
criar script com lógica arbitrária
Aqui eu crio um script que muda para um diretório e ativa o ambiente Python apropriado. A localização dos scripts é exmplary em /path/to/workon_myproj.sh
.
#!/usr/bin/env bash cd $HOME/workspace/myproj source .venv/bin/activate
criar alias que origina o script
alias workon_myproj="source /path/to/workon_myproj.sh"
Adicione a definição de alias em seu arquivo inicial de shell apropriado, por exemplo .profile
, .bashrc
ou .zshrc
.
resultado
Agora você pode simplesmente executar workon_myproj
em um shell que fornecerá o conteúdo do seu script no diretório desejado.
extensibilidade
Você poderia eventualmente melhorar seu script para obter um argumento para que funcione com vários projetos em um diretório de trabalho específico, ou combiná-lo com um git pull
para obter as alterações mais recentes imediatamente e assim em … tudo que você faz ao continuar a trabalhar em um projeto específico.
Resposta
Por que não usar ” exec “parece fazer exatamente o que eu desejo.
#!/bin/bash cd someplace exec bash ~/someplace
Comentários
- Cuidado com as coisas que parece ser o que você deseja. (Um cavalo de madeira gigante! Exatamente o que eu queria!) Cada vez que você executa isso, ele cria um processo de bash novo e persistente. Faça isso dez ou vinte vezes em uma sessão e você terá de 11 a 21 processos bash empilhados. Isso pode afetar o desempenho e, se você tentar encerrar a sessão de forma limpa, digitando
exit
(ou Ctrl + D), você terá que fazer isso 11 a 21 vezes. - Eu definitivamente pude ver onde isso seria um problema. No entanto, para mim, ‘ estou usando uma vez, fazendo o trabalho de que preciso e depois saindo. Se ‘ for a única desvantagem, eu pode viver com isso. Por outro lado, se houver uma solução melhor, eu ‘ estou disposto a olhar para ela.
- A resposta de Aidin a esta pergunta , usando uma função shell, e a resposta de Sachin Divekar , usando um alias, são soluções (IMO) melhores do que usar um script . P.S. Outra desvantagem de usar um script é que, se você definir quaisquer opções de shell (por exemplo,
dotglob
ouglobstar
), você as perderá, porque você está iniciando um novo shell. … (Cont.) - (Cont.)… P.P.S. Acabei de notar que você está, basicamente, reiterando a resposta de Serge Stroobandt e dizendo Por que não fazer isso? Em Stack Exchange , esperamos respostas para fornecer novas ideias e / ou informações, e não apenas discutir outras respostas.
Resposta
Isso combina a resposta de Serge com uma resposta não relacionada de David . Ele muda o diretório e, em vez de forçar um shell bash, inicia o shell padrão do usuário . No entanto, requer getent
e /etc/passwd
para detectar o shell padrão.
#!/usr/bin/env bash cd desired/directory USER_SHELL=$(getent passwd <USER> | cut -d : -f 7) $USER_SHELL
Claro, isso ainda tem a mesma deficiência de criar um shell aninhado.
Resposta
Você pode fazer isso usando uma função ou & & Os exemplos abaixo instalam o Zabbix e cria um com uma linha dentro dele.
Ex:
#!/bin/bash # Create Function: installZabbix(){ cd /usr/src/zabbix-4.2.4; ./configure --enable-agent; make install; cd /usr/src/; >file; echo "Hi, this is a file." >>file; } # Call the function: installZabbix
ou:
#!/bin/bash cd /usr/src/zabbix-4.2.4 && ./configure --enable-agent && make install && cd /usr/src && >file && echo "Hi, this is a file." >>file
return
para escapar de um script originado desta forma, nãoexit
– são como funções de shell eexit
sairá do shell que originou o script.source ./script
o mesmo?.
esource
são iguais no bash. 2. Nós não ‘ Não é necessário usar./
antes do nome do arquivo se ele ‘ s no mesmo diretório. É normal executar apenas isto:. script