Bash one-liner para anexar temporariamente o caminho para comandos encadeados sem chamada bash adicional?

3

Considere isso:

$ cd /tmp
$ echo "echo YES" >> prog/myprog
$ chmod +x prog/myprog
$ prog/myprog
YES
$ myprog
myprog: command not found

Eu posso modificar temporariamente PATH para chamar myprog pelo nome assim:

$ PATH="$PATH":$(readlink -f prog) myprog
YES

... no entanto, não posso encadear comandos com essa abordagem:

$ PATH="$PATH":$(readlink -f prog) myprog && myprog
YES
myprog: command not found

... aparentemente o PATH modificado aparentemente não se propagou para a segunda invocação.

Estou ciente de que posso fazer isso:

$ PATH="$PATH":$(readlink -f prog) bash -c "myprog && myprog"
YES
YES

... mas depois tenho que invocar um processo bash extra - e, pior ainda, tenho que citar.

Existe alguma maneira de acrescentar temporariamente ao PATH comandos encadeados em uma linha, sem precisar invocar bash e cotação extras? Tentei backticks, eles não funcionam:

$ PATH="$PATH":$(readlink -f prog) 'myprog && myprog'
myprog: command not found
    
por sdaau 26.03.2016 / 16:34

3 respostas

5

Que tal usar um subshell:

$ (PATH="$PATH:$(readlink -f prog)"; myprog && myprog)
YES
YES
    
por 26.03.2016 / 16:48
1

Isso dependerá do que você considera "temporário". Por exemplo, você poderia simplesmente executar:

$ PATH="$PATH":$(readlink -f prog) 

E, em seguida, você poderá executar myprog no conteúdo do seu coração durante o restante da sessão de shell. As alterações feitas em PATH desapareceriam assim que você efetuasse logout. Você poderia simplesmente abrir um novo terminal - se estivesse trabalhando graficamente, ou alternar para outro terminal, se não - ou executar uma nova sessão:

$ bash
$ PATH="$PATH":$(readlink -f prog) 
## Do your stuff here

$ exit

Outra maneira de executar a mesma coisa é:

PATH="$PATH":$(readlink -f prog) bash

Isso iniciará uma nova sessão bash com a variável PATH alterada. Assim que estiver pronto, execute exit para retornar ao pai.

    
por 26.03.2016 / 17:05
0

Se você quiser que o caminho seja alterado apenas pela duração do comando.
Então, você precisa configurá-lo para cada vez que o comando é chamado.
Esse é um trabalho perfeito para um alias:

alias myprog='PATH="$PATH":$(readlink -f prog) myprog'

Use como:

$ myprog && myprog
YES
YES

É claro que uma função com o mesmo nome não funcionará:

$ myprog(){ PATH="$PATH":$(readlink -f prog) myprog; }  ### DO NOT USE !!

Estou apenas imaginando se você realmente precisa disso. Se você criar o script dentro de ~/bin (após um login com o diretório ~/bin created), a variável PATH já incluirá esse caminho, e o script será executado apenas nomeando-o:

$ cd ~/bin                   ### create the dir if it didn't exist.
$ echo "echo YES" >> myprog
$ chmod u+x myprog
$ cd ~
$ myprog                     ### remember to reload ~/.bashrc (re-login).
YES
    
por 26.03.2016 / 21:22