Por favor, conselhos por que isso acontece.
de um shell bash do Linux:
ps
PID TTY TIME CMD
20406 pts/0 00:00:01 bash
26896 pts/0 00:00:00 ps
eu corro o seguinte
str="a b c d"
printf "%s\n" ` echo $str `
a
b
c
d
mas do script bash
#!/bin/bash
.
.
.
.
str="a b c d"
printf "%s\n" ` echo $str `
ele imprime:
a b c d
enquanto os resultados esperados do script devem ser assim:
a
b
c
d
O que está faltando no meu script bash? Talvez bash ENV, ou algo assim?
Eu também corro o shopt
comando do meu script bash e estes são os resultados:
utocd off
cdable_vars off
cdspell off
checkhash off
checkjobs off
checkwinsize off
cmdhist on
compat31 off
compat32 off
compat40 off
compat41 off
direxpand off
dirspell off
dotglob off
execfail off
expand_aliases off
extdebug off
extglob off
extquote on
failglob off
force_fignore on
globstar off
gnu_errfmt off
histappend off
histreedit off
histverify off
hostcomplete on
huponexit off
interactive_comments on
lastpipe off
lithist off
login_shell off
mailwarn off
no_empty_cmd_completion off
nocaseglob off
nocasematch off
nullglob off
progcomp on
promptvars on
restricted_shell off
shift_verbose off
sourcepath on
xpg_echo off
Posso reproduzir esse comportamento apenas em dois casos:
substituição de comando com aspas duplas:
ou mudou o Separador de Campo Interno (
IFS
variável), por exemplo:Em ambos os casos, a saída é
Para reparar o primeiro caso, basta remover as aspas e, para restaurar,
IFS
basta defini-lo como o valor padrão em algum lugar acima da substituição do comando.Um pouco de explicação de por que a saída é diferente quando
IFS
alterada e o que ela tem em comum com aspas duplas?Vamos começar do final:
é obviamente diferente de
No primeiro caso, temos quatro palavras separadas e
printf
as exibimos uma a uma, adicionando uma nova linha a elas. No segundo caso, o todoa b c d
é tratado como uma única palavra eprintf
apenas a envia como tal para o terminal. E agora deve ser óbvio que a saída de`echo $str`
é tratada como uma única palavra quando adicionalmente entre aspas duplas.Agora é onde
IFS
começa a desempenhar um papel. Ou seja, tt é usado para dividir palavras após expansões, portanto, com padrão,IFS=$' \t\n'
a expressãoecho a b c d
saia b c d
, mas comIFS=,
ela se torna'a b c d'
- um único mundo, embora as aspas não tenham sido usadas explicitamente. Pode-se verificar isso mais claramente sem variável:Como observação final: é melhor usar uma
$()
forma de substituição de comando, não backticks, mas esse é um tópico diferente.