O problema é que sua substituição de comando se expande para uma string delimitada por espaços em branco e o loop itera todas as palavras nessa string. Uma "palavra" é qualquer coisa delimitada por um espaço, tabulação ou caractere de nova linha.
Note também que em shells parecidas com Bourne que não sejam zsh
, essas palavras estão sujeitas à geração de nome de arquivo (também globbing), então caracteres curinga (e {
em alguns shells) também seriam um problema. espaço e tabulação.
lssyscfg -r lpar -m "$system" -F name,lpar_env | cut -d, -f 1 | sort |
while IFS= read -r lpar; do
echo "$lpar"
done
Isso usa um loop while
em vez de um loop for
estático. O corpo do loop while
é executado em um subshell (em bash
), portanto, a variável lpar
não existirá após o final do corpo do loop. Isso não é um problema se você usar a variável no corpo do loop.
Relacionados: Compreendendo "IFS = read -r line"
Outra solução seria definir IFS
para uma nova linha antes do loop (e redefini-la posteriormente):
oldIFS=$IFS
IFS=$'\n' # assumes bash
set -o noglob
for lpar in $( lssyscfg -r lpar -m "$system" -F name,lpar_env | cut -d, -f 1 | sort )
do
echo "$lpar"
done
set +o noglob
IFS=$oldIFS
O valor padrão de $IFS
inclui espaços, e é por isso que o loop original percorre as coisas erradas. Também desativei o globbing de nomes para o loop, pois de outra forma poderíamos obter resultados inesperados se o texto retornado de lssyscfg
incluir padrões de globbing de nomes de arquivo, conforme discutido acima.
Esta última variação é IMHO bastante deselegante e absolutamente inadequado para comandos que produzem mais do que um punhado de linhas de saída.