Subshells isolados no bash

0

Existe uma maneira de chamar um subshell completamente isolado de um script bash? O que quero dizer é que o subshell chamado não terá variáveis ​​herdadas de seu pai. Isto é essencialmente o que estou tentando realizar

Chris
fonte
Dê uma olhada neste repo! github.com/kusalananda/shell-toolbox
vfbsilva

Respostas:

2
env -i "$BASH" -c 'your code here'

Inicia um novo bashintérprete para interpretar your code hereem um ambiente inicialmente vazio.

Como é uma nova bashinstância, não herdaria os aliases, parâmetros posicionais, variáveis ​​não exportadas, funções.

Com o env -itambém não herdaria as variáveis ​​e funções exportadas (definidas pela chamada bashou possivelmente herdadas anteriormente).

Ele ainda herdaria alguns outros tipos de atributos que são preservados na execução de bifurcação e comando, como os umaskdescritores de arquivo abertos sem o sinalizador close-on-exec, limites, algumas disposições de sinal (como um trap '' INTno chamador também faria com que o SIGINT fosse ignorado no chamado).

Stéphane Chazelas
fonte
1

O envcomando com o -isinalizador cria um ambiente vazio

% env -i /bin/env
%

Agora bashcriará um conjunto de variáveis, mas elas não serão herdadas; isso é apenas bashserbash

% env -i /bin/bash -c set
BASH=/bin/bash  
BASHOPTS=cmdhist:extquote:force_fignore:hostcomplete:interactive_comments:progcomp:promptvars:sourcepath
BASH_ALIASES=()
BASH_ARGC=()
BASH_ARGV=()
BASH_CMDS=()
BASH_EXECUTION_STRING=set
BASH_LINENO=()
BASH_SOURCE=()
BASH_VERSINFO=([0]="4" [1]="2" [2]="46" [3]="2" [4]="release" [5]="x86_64-redhat-linux-gnu")
BASH_VERSION='4.2.46(2)-release'
DIRSTACK=()
EUID=1000
GROUPS=()
HOSTNAME=myhost.local
HOSTTYPE=x86_64
IFS=$' \t\n'
MACHTYPE=x86_64-redhat-linux-gnu
OPTERR=1                          
OPTIND=1
OSTYPE=linux-gnu
PATH=/usr/local/bin:/usr/bin
PPID=12003
PS4='+ '
PWD=/tmp
SHELL=/bin/bash
SHELLOPTS=braceexpand:hashall:interactive-comments
SHLVL=1
TERM=dumb
UID=1000
_=/bin/bash

Conchas diferentes criarão variáveis ​​diferentes; por exemplo, ksh93 e csh:

% env -i /bin/ksh -c set
ENV=.sh.ENV
FCEDIT=ed
HISTCMD=0
IFS=$' \t\n'
JOBMAX=0
KSH_VERSION=.sh.version
LINENO=1
MAILCHECK=600
OPTIND=1
PPID=12003
PS2='> '
PS3='#? '
PS4='+ '
PWD=/tmp
RANDOM=12790
SECONDS=0.000
SHELL=/bin/sh
SHLVL=1
TMOUT=0

% env -i /bin/csh -c set
argv    ()
cwd     /tmp
path    (/usr/bin /bin /usr/local/bin)
shell   /bin/csh
status  0

% env -i /bin/csh -c setenv
PWD=/tmp
Stephen Harris
fonte
Observe que, como env -i bashtambém desativa a PATHvariável de ambiente, isso significa que ela só funcionará se bashpuder ser encontrada no caminho de pesquisa padrão da libc. Em sistemas GNU / Linux mais antigos (e não tão antigos), ele procuraria bashprimeiro no diretório atual o que seria potencialmente perigoso.
Stéphane Chazelas
@ StéphaneChazelas Se o PATH estiver definido em um arquivo de inicialização (lido) como em /etc/profile: não há esse problema.
Isaac
@isaac, envnão lê /etc/profile. Esse é o tipo de arquivo lido pelos shells de login. O problema aqui é que env -ilimpe o ambiente e, em seguida, chame execvp("bash", ...)e execvp()procure bashem um PATH padrão que, por exemplo, no Ubuntu 16.04 :/bin:/usr/bin. Se estiver cd /tmp; ln -s /bin/echo bash; env -i bash -c uname, veja -c uname, não Linuxindependentemente do que /etc/profilecontém.
Stéphane Chazelas
@ StéphaneChazelas Obrigado; Atualizei a resposta para ter o caminho completo para o comando que está sendo executado.
Stephen Harris