É assim que eu sugiro que você faça, e vou explicar o porquê, mas primeiro quero falar sobre outra coisa ...
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
Muitas das outras soluções oferecidas aqui parecem sugerir que você pode, de alguma forma, afetar o conteúdo de uma variável de shell alterando seus métodos de expansão. Posso garantir que esse não é o caso.
string="some stuff here \
some more stuff here."
echo $string ${#string}
echo "$string" "${#string}"
RESULTADO
some stuff here some more stuff here. 53
some stuff here some more stuff here. 53
O que você vê acima é primeiro uma expansão de divisão de campo, depois um relatório sobre a contagem de bytes para a variável de origem da expansão, depois uma expansão delimitada por aspas e a mesma contagem de bytes. Embora a saída possa diferir, o conteúdo da variável do shell $string
nunca muda, exceto na atribuição.
Além do mais, se você não entende por que isso ocorre, é provável que encontre surpresas muito desagradáveis, mais cedo ou mais tarde. Vamos tentar novamente, mas em condições ligeiramente diferentes.
IFS=sf
echo $string ${#string}
echo "$string" "${#string}"
Mesmo $string
- ambiente diferente.
RESULTADO
ome tu here ome more tu here. 53
some stuff here some more stuff here. 53
A divisão de campo ocorre com base nos delimitadores de campo definidos em $IFS
. Existem dois tipos de delimitadores - $IFS
espaço em branco e $IFS
qualquer outra coisa. Por padrão, $IFS
é atribuída a nova linha da guia do espaço de valor - que são os três $IFS
valores possíveis de espaço em branco. Porém, é facilmente alterado, como você pode ver acima, e pode ter efeitos drásticos nas expansões divididas em campo.
$IFS
o espaço em branco será eliminado por sequência em um único campo - e é por isso que echo
uma expansão contendo qualquer sequência de espaços quando $IFS
contiver um espaço será avaliada em apenas um espaço - porque echo
concatena seus argumentos em espaços. Mas quaisquer valores que não sejam de espaço em branco não serão exibidos da mesma maneira, e cada delimitador sempre terá um campo em si - como pode ser visto na expansão de coisas acima.
Isso não é o pior. Considere esse outro $string
.
IFS=$space$tab$newline
cd emptydir
string=" * * * \
* * * "
echo $string ${#string}
echo "$string" "${#string}"
RESULTADO
* * * * * * 30
* * * * * * 30
Parece ok, certo? Bem, vamos alterar o ambiente novamente.
touch file1 file2 file3 file4 file5
echo $string ${#string}
echo "$string" "${#string}"
RESULTADO
file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 file1 file2 file3 file4 file5 30
* * * * * * 30
Woah.
Por padrão, o shell expandirá os globs do nome do arquivo, se puder correspondê-los. Isso ocorre após a expansão do parâmetro e a divisão do campo em sua ordem de análise e, portanto, qualquer string não citada fica vulnerável dessa maneira. Você pode desativar esse comportamento set -f
se quiser, mas qualquer shell compatível com POSIX sempre será exibido por padrão.
Esse é o tipo de coisa contra a qual você solta citações em expansões para se adequar às suas preferências de recuo. E mesmo assim, em todos os casos, independentemente do seu comportamento de expansão, o valor real $string
ainda é sempre o que era quando você o atribuiu pela última vez. Então, voltemos à primeira coisa.
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
echo "$var" "${#var}"
RESULTADO
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like. 70
Acredito que esta é uma maneira muito mais sadia de adaptar a sintaxe do shell às suas preferências de recuo. O que estou fazendo acima é atribuir cada sequência individual a um parâmetro posicional - que pode ser referenciado por número como $1
ou ${33}
- e depois atribuir seus valores concatenados ao $var
uso do parâmetro shell especial $*
.
Essa abordagem não é imune $IFS
, mesmo assim. Ainda assim, considero sua relação com $IFS
um benefício adicional a esse respeito. Considerar:
IFS=\ ;space_split="$*"
IFS=/; slash_split="$*";IFS='
';new_line_split="$*"
echo "$space_split"
echo "$slash_split"
echo "$new_line_split"
RESULTADO
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like.
Arg 1: Line 1./Arg 2: Line 2./and so on for/as long as you might like.
Arg 1: Line 1.
Arg 2: Line 2.
and so on for
as long as you might like.
Como você pode ver, $*
concatena cada argumento no "$@"
primeiro byte $IFS
. Assim, salvar seu valor enquanto $IFS
é atribuído de forma diferente obtém delimitadores de campo diferentes para cada valor salvo. O que você vê acima é o valor literal de cada variável, a propósito. Se você não quisesse delimitador, faria:
IFS=;delimitless="$*"
echo "$delimitless" "${#delimitless}"
RESULTADO
Arg 1: Line 1.Arg 2: Line 2.and so on foras long as you might like. 67