Iniciar novo plano de sessão bash

0

É possível criar um comando chamado new_bash que me permita fazer o seguinte?

new_bash alias test="ls"
new bash alias new_command="ls"

new_bash test
file1
new_bash new_command
file1
    
por William 03.09.2015 / 23:47

2 respostas

5
##Background:

cd $(mktemp -d)
> file1

##Setup state (background bash + pipe)
pipeDir=$(mktemp -d)
mkfifo $pipeDir/p #pipe for communicating with the shell
#start the shell in the background, make it read from the pipe, and disable I/O buffering
stdbuf -i0 -o0 bash < $pipeDir/p & 
#open the pipe from the other end on fd 3 (or another fd)
exec 3>$pipeDir/p && 
rm -rf "$pipeDir" #don't need the directory or the physical link to the pipe anymore

##Now you can communicate with the shell
echo ls >&3
#Ouptuts: file1

#This is how you end it all
exec 3>&-

Sua função precisaria manter o estado global. Sua função precisaria verificar se o estado foi configurado e configurado se não foi (verificando a existência de uma variável, talvez). Após a configuração ou se o estado existir, ele precisará apenas de echo de seus argumentos ( "$@" ) para &3 ou de qualquer descritor de arquivo em que você abrir o pipe.

Pode ser uma ideia melhor criar três funções (será um pouco mais eficiente):

init_new_bash
new_bash
end_new_bash

Exemplo (precisa de melhor tratamento de sinal):

#!/bin/sh 
#^will work in bash also
init_new_bash(){
    set -e #all must succeed
    pipeDir=$(mktemp -d)  
    mkfifo "$pipeDir/p" 

    stdbuf -i0 -o0 bash < "$pipeDir"/p & 
    bashPid=$! 

    exec 3>"$pipeDir/p"
    rm -rf "$pipeDir" 
    set +e
}
new_bash(){ echo "$@" >&3; }
end_new_bash(){ exec 3>&-; wait "$bashPid"; }

##Test run:
init_new_bash && {

   new_bash echo hello world
   new_bash ls

end_new_bash;}
    
por 04.09.2015 / 00:10
0

O que você está pedindo é muito parecido com um simples subnível .

Sempre que você usar encapsular seus comandos usando parênteses, por exemplo (ls) , este comando será executado em um processo filho do shell atual.

Para o seu exemplo:

( 
alias test='ls'
alias new_command='ls'
test
new_command
)

Ou, como os aliases são copiados para subshells

alias test='ls'
alias new_command='ls'
( test ) # one subshell
( new_command ) # another subshell

Se você precisar que seus comandos sejam executados na mesma sub-lista:

alias test='ls'
alias new_command='ls'
( test ; new_command ) # same subshell
    
por 09.09.2015 / 16:30

Tags