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 $string
non 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: $IFS
spazi bianchi e $IFS
qualsiasi altra cosa. Per impostazione predefinita $IFS
viene assegnata la scheda spazio valore newline - che sono i tre possibili $IFS
valori degli spazi bianchi. Tuttavia, è facilmente modificabile, come puoi vedere sopra, e può avere effetti drastici sulle espansioni di divisione del campo.
$IFS
gli spazi bianchi verranno elisi per sequenza in un singolo campo - e questo è il motivo echo
per cui un'espansione contenente qualsiasi sequenza di spazi quando $IFS
contiene uno spazio valuterà solo un singolo spazio - perché echo
concatena 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 -f
Se 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 $1
o ${33}
- e quindi assegnare i loro valori concatenati $var
all'utilizzo dello speciale parametro shell $*
.
Questo approccio non è immune $IFS
, anche così. Tuttavia, considero la sua relazione $IFS
un 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