scripts BASH trabalhando seletivamente

2

Eu tenho várias funções BASH, que tive no meu /etc/bash.bashrc por um longo tempo. Eles trabalham lá, em ~/.bashrc , e em ~/.bash_profile do OSX quando escrito assim:

mcdir(){
    mkdir "$1";
    eval cd "$1";
}

Este é apenas um curto, que eu uso diariamente, como um exemplo. Ele simplesmente faz um determinado diretório e muda para ele, o caminho que o mkdir "$1" && cd "$1" faria ... Eu sou apenas preguiçoso.

O ponto é que funciona ... Eu sei que funciona, porque eu tenho usado por anos.

Agora, recentemente o removi do meu bashrc e o coloquei em /usr/local/bin as mcdir (assim como chmod +x /usr/local/bin/mcdir ), para que realmente não haja alterações. Aqui, parece algo assim:

#!/bin/bash

mkdir "$1";
eval cd "$1";

Isso, para todos os efeitos, deve funcionar exatamente como a função acima. O problema é que isso só funciona no meio do caminho. Ele fará o novo diretório, mas NUNCA mude para ele.

Alguém sabe o que estou fazendo de errado aqui e / ou como resolvê-lo?

Outro exemplo que tenho é uma função cdd ... em bashrc , é assim:

cdd(){
    cd "$1";
    echo -e "3[101m" $(pwd) "3[49m";
    ls -l;
}

E isso funciona perfeitamente! Mas, quando eu coloco em seu próprio script em /usr/local/bin e o faço executável, assim:

cd "$1";
echo -e "3[101m" $(pwd) "3[49m";
ls -l;

Na verdade, ele não é alterado no diretório. Ele me dará o pwd e o ls -l , mas não alterarei o diretório.

    
por antiDill 16.11.2017 / 17:06

1 resposta

3

Os scripts são executados em subshells. Eles não podem afetar o ambiente da sua sessão de shell ativa da maneira que as funções podem. Veja, por exemplo, o avançada Guia de Bash-Scripting, capítulo 21: subshells :

A subshell is a separate instance of the command processor -- the shell that gives you the prompt at the console or in an xterm window. Just as your commands are interpreted at the command-line prompt, similarly does a script batch-process a list of commands. Each shell script running is, in effect, a subprocess (child process) of the parent shell.

Ou o Bash Referência, Seção 3.8: Scripts Shell :

A shell script may be made executable by using the chmod command to turn on the execute bit. When Bash finds such a file while searching the $PATH for a command, it spawns a subshell to execute it. In other words, executing

filename arguments

is equivalent to executing

bash filename arguments

if filename is an executable shell script. This subshell reinitializes itself, so that the effect is as if a new shell had been invoked to interpret the script, with the exception that the locations of commands remembered by the parent (see the description of hash in Bourne Shell Builtins) are retained by the child.

Se você quiser usar um script em vez de uma função, pode source em vez de executá-lo, mas honestamente eu acho que provavelmente é melhor ficar apenas usando funções (ou aliases) para o tipo de coisa que você está fazendo.

Desse modo, se você quiser reorganizar o código em ~/.bashrc , poderá separá-lo em arquivos separados e, em seguida, source desses arquivos em ~/.bashrc , por exemplo, você pode colocá-los em um subdiretório local, como ~/.bashrc.d .

    
por 16.11.2017 / 17:08