é possível alterar o diretório de trabalho do shell pai programaticamente?

8

Eu quero escrever algum código para permitir que eu mude para alguns diretórios que eu geralmente uso. Digamos que este programa seja mycd e /a/very/long/path/name seja o diretório para o qual desejo ir.

Portanto, posso simplesmente digitar mycd 2 em vez de cd /a/very/long/path/name . Aqui eu assumo mycd sabe 2 refere-se a /a/very/long/path/name . Também pode haver mycd 1 , mycd 3 , ... etc.

O problema é que eu tenho que escrever mycd como um script de shell e digitar . mycd 2 para fazer a coisa desejada porque senão o script é executado em um script filho que não muda nada sobre o shell pai que eu realmente se importam.

Minha pergunta é:

  • posso fazer isso sem usar source ? porque . mycd assume mycd tem que ser um script de shell e isso também pode introduzir algumas funções que eu não quero.

  • posso implementá-lo em outras linguagens de programação?

por Javran 08.02.2014 / 20:50

3 respostas

23

crie mycd uma função para que o comando cd seja executado no seu shell atual. Salve no seu arquivo ~ / .bashrc.

function mycd {
    if (( $# == 0 )); then
        echo "usage: $FUNCNAME [1|2|3|...]"
        return
    fi
    case $1 in
        1) cd /tmp ;;
        2) cd /a/very/long/path/name ;;
        3) cd /some/where/else ;;
        *) echo "unknown parameter" ;;
    esac
}
    
por 08.02.2014 / 22:41
9

Você não pode alterar o diretório atual de um shell de outro processo. Somente o processo em si pode alterar seu próprio diretório atual. Isso também vale para algumas outras características, como variáveis de ambiente e descritores de arquivos.

Na verdade, é possível afetar o diretório atual de outro processo fazendo com que ele execute uma chamada de sistema chdir por meio do ptrace chamada de sistema, que é o que permite que os depuradores funcionem. No entanto, se o processo mantiver algumas estruturas de dados internas que precisam ser consistentes com o diretório atual real, o programa provavelmente falhará. Para um shell, essa abordagem não tem chance de funcionar.

Você precisa organizar seu código para ser executado pelo próprio shell. O modo normal de proceder seria torná-lo uma função de shell e armazená-lo no seu ~/.bashrc . Se isso não for possível, por exemplo, porque é um código que você deseja distribuir, escreva um arquivo de origem do shell que contenha a definição da função e diga às pessoas para que o shell interativo leia o arquivo com o . command .

    
por 08.02.2014 / 23:18
5

Como você mesmo apontou, os scripts de shell são sempre executados em um subshell, que não pode influenciar seu shell pai.

Você pode, no entanto ...

  • use um alias:
    alias mycd2='cd /a/very/long/path/name'
  • faça com que seu script 1 imprima um comando shell válido ...

    #!/bin/bash
    if [ "x$1" = "x2" ]
    then
        echo "cd /a/very/long/path/name"
    fi
    

    ... e execute sua saída: $(mycd 2)

1: Você provavelmente desejará usar uma instrução case em vez da condição if no exemplo.

    
por 08.02.2014 / 20:57