Ecco come ti suggerisco di farlo, e spiegherò perché, ma prima voglio parlare di qualcos'altro ...
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
Molte delle altre soluzioni offerte qui sembrano suggerire che puoi in qualche modo influenzare il contenuto di una variabile di shell alterando i tuoi metodi di espansione. Posso assicurarti che non è così.
string="some stuff here \
some more stuff here."
echo $string ${#string}
echo "$string" "${#string}"
PRODUZIONE
some stuff here some more stuff here. 53
some stuff here some more stuff here. 53
Quello che vedi sopra è prima un'espansione suddivisa in campi, quindi un rapporto sul conteggio dei byte per la variabile di origine dell'espansione, quindi un'espansione delimitata da virgolette e lo stesso conteggio dei byte. Mentre l'output può differire, il contenuto della variabile shell $stringnon cambia mai se non in caso di assegnazione.
Inoltre, se non capisci perché, sei costretto a incontrare brutte sorprese prima o poi. Riproviamo, ma in condizioni leggermente diverse.
IFS=sf
echo $string ${#string}
echo "$string" "${#string}"
Stesso $string- ambiente diverso.
PRODUZIONE
ome tu here ome more tu here. 53
some stuff here some more stuff here. 53
La suddivisione dei campi avviene in base ai delimitatori di campo definiti in $IFS. Esistono due tipi di delimitatori: $IFSspazi bianchi e $IFSqualsiasi altra cosa. Per impostazione predefinita $IFSviene assegnata la scheda spazio valore newline - che sono i tre possibili $IFSvalori degli spazi bianchi. Tuttavia, è facilmente modificabile, come puoi vedere sopra, e può avere effetti drastici sulle espansioni di divisione del campo.
$IFSgli spazi bianchi verranno elisi per sequenza in un singolo campo - e questo è il motivo echoper cui un'espansione contenente qualsiasi sequenza di spazi quando $IFScontiene uno spazio valuterà solo un singolo spazio - perché echoconcatena i suoi argomenti sugli spazi. Ma tutti i valori non di spazi bianchi non usciranno allo stesso modo e ogni delimitatore che si verifica ottiene sempre un campo a sé - come si può vedere nell'espansione delle cose sopra.
Questo non è il peggio. Considera questo altro $string.
IFS=$space$tab$newline
cd emptydir
string=" * * * \
* * * "
echo $string ${#string}
echo "$string" "${#string}"
PRODUZIONE
* * * * * * 30
* * * * * * 30
Sembra ok, vero? Bene, cambiamo di nuovo l'ambiente.
touch file1 file2 file3 file4 file5
echo $string ${#string}
echo "$string" "${#string}"
PRODUZIONE
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.
Per impostazione predefinita, la shell espanderà globs di nome file se può corrispondere a loro. Ciò si verifica dopo l' espansione dei parametri e la divisione dei campi nel suo ordine di analisi e quindi qualsiasi stringa non quotata è vulnerabile in questo modo. set -fSe lo desideri, puoi disattivare questo comportamento , ma qualsiasi shell compatibile con POSIX sarà sempre glob per impostazione predefinita.
Questo è il tipo di cose a cui ti trovi di fronte quando lasci cadere le virgolette sulle espansioni in base alle tue preferenze di rientro. E comunque, in ogni caso, indipendentemente dal suo comportamento di espansione, il valore effettivo $stringè sempre quello che era quando lo hai assegnato l'ultima volta. Quindi torniamo alla prima cosa.
set -- 'Arg 1: Line 1.' \
'Arg 2: Line 2.' \
'and so on for' \
'as long as you might like.'
var="$*"
echo "$var" "${#var}"
PRODUZIONE
Arg 1: Line 1. Arg 2: Line 2. and so on for as long as you might like. 70
Credo che questo sia un modo molto più sano per adattare la sintassi della shell alle tue preferenze di rientro. Quello che sto facendo sopra è assegnare ogni singola stringa a un parametro posizionale - che può essere indicato da un numero come $1o ${33}- e quindi assegnare i loro valori concatenati $varall'utilizzo dello speciale parametro shell $*.
Questo approccio non è immune $IFS, anche così. Tuttavia, considero la sua relazione $IFSun ulteriore vantaggio in questo senso. Tener conto di:
IFS=\ ;space_split="$*"
IFS=/; slash_split="$*";IFS='
';new_line_split="$*"
echo "$space_split"
echo "$slash_split"
echo "$new_line_split"
PRODUZIONE
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.
Come puoi vedere, $*concatena ogni argomento nel "$@"primo byte in $IFS. Pertanto, salvando il suo valore mentre $IFSè assegnato in modo diverso, si ottengono delimitatori di campo diversi per ciascun valore salvato. A proposito, quello che vedi sopra è il valore letterale per ogni variabile. Se non volessi assolutamente delimitatore, faresti:
IFS=;delimitless="$*"
echo "$delimitless" "${#delimitless}"
PRODUZIONE
Arg 1: Line 1.Arg 2: Line 2.and so on foras long as you might like. 67