Eu estava tentando escrever uma função simples que verifica se um arquivo de configuração é "higienizado" e seguro para o fornecimento ou não. Eu aparentemente tenho que funcionar em bash
, e em ksh
(Versão ABIJM 93v - 2014-06-25) na primeira invocação da função apenas. Esta é a versão mais enxuta da função que ainda reproduz esse bug para mim:
function sanitized_source
{
typeset source_filename=$1
(
#shopt -s extdebug # Need this if using bash
trap 'if [[ $? != 0 ]]; then return 66; fi' DEBUG
PATH=.
set -re
. "${source_filename}"
)
}
e o arquivo de configuração:
cd /root || echo 'what?'
echo 'why is this executed?'
Como eu corro e vejo:
% . ./dotfile
% sanitized_source test.conf
ksh: sanitized_source[79]: sanitized_source[1]: cd: restricted
% sanitized_source test.conf
ksh: sanitized_source[79]: .[1]: cd: restricted
what?
why is this executed?
A intenção do trap
é cobrir os casos em que set -e
não sairá do shell mesmo que um comando falhe. De man bash
:
[set] -e
[...] The shell does not exit if the command that fails is [...] part of any command executed in a && or || list except the command following the final && or || [...]
extdebug
[...] 2. If the command run by the DEBUG trap returns a non-zero value, the next command is skipped and not executed.
Percebi que os parâmetros .sh.command
e .sh.subshell
foram alterados entre a primeira e a segunda invocação:
% sanitized_source test.conf
ksh: sanitized_source[9]: sanitized_source[1]: cd: restricted
% echo "${.sh.command}"
echo 'what?'
% echo "${.sh.subshell}"
0
% sanitized_source test.conf
ksh: sanitized_source[9]: .[1]: cd: restricted
what?
why is this executed?
% echo "${.sh.command}"
'���2
% echo "${.sh.subshell}"
%
Além disso, se eu substituir a instrução return
ou exit
em trap
por echo
, por exemplo, posso ver que a instrução trap
é executada toda vez.
Então, por que esse comportamento é observado apenas em ksh
e não em bash
? Qual é a causa raiz e como faço para corrigir isso?