Newsgroup: it.comp.os.linux.iniziare
Titolo: guida bash

#!/bin/bash
# weirdvars.sh: Visualizzare strane variabili.
var="'(]\\{}\$\""
echo $var        # '(]\{}$"
echo "$var"      # '(]\{}$"     Nessuna differenza.
echo
IFS='\'
echo $var        # '(] {}$"     \ trasformata in spazio. Perché?
echo "$var"      # '(]\{}$"
una birra a chi sa' rispondere.
ciao 
 

 echo "$var"      # '(]\{}$"
Perché IFS definisce il "separatore interno di campi": solitamente è "
" (spazio), in molti script viene settato a "\n" (nuova riga). In questo caso
tu lo setti a "\", perciò hai due termini risultanti: '(] e {}$".
http://tldp.org/LDP/abs/html/internalvariables.html#IFSREF
Birra!!!
David
-- 
 . ''`.  Debian maintainer | 
http://wiki.debian.org/DavidPaleino
 : :'  : Linuxer #334216 --|-- 
http://www.hanskalabs.net/
 `. `'`  GPG: 1392B174 ----|---- 
http://snipr.com/qa_page
   `-   2BAB C625 4E66 E7B8 450A C3E1 E6AA 9017 1392 B174

claudio wrote:

.. e' qualcosa vicina al fatto che la stringa viene spezzata in due e ''l'a
capo'' non vien stampato ma ''sostituito' con lo spazio ...

 
 
ok !! 
una doppio malto per te. offro io.
ho impiegato qlq ora a capire il trucco.
ciao
-- 
--------------------------------
linux slackware
tutto il resto e' inutile
--------------------------------

 
rilancio con un'altra domanda... (due birre!)
$ IFS=" "; a="x         y"; echo $a
x y
$ IFS="."; a="x..........y"; echo $a
x          y
perche' nel secondo modo i punti non collassano in uno solo?

 perche' nel secondo modo i punti non collassano in uno solo?
Perché non hai quotato "$a", e gli spazi vengono "collassati" da echo:
$ IFS=" "; a="x    y"; echo $a
x y
$ IFS=" "; a="x    y"; echo "$a"
x    y
$
Ragionandoci e provando, però, effettivamente...
$ IFS="."; a="x...y"; echo $a
x   y
$ IFS="."; a="x...y"; echo "$a"
x...y
$
Quotando si "perde" l'effetto di IFS. Any idea?
Ciao,


 Quotando si "perde" l'effetto di IFS. Any idea?
quotando il discorso cade... quotando resta tutto sempre come l'originale.
pero' senza quoting, se si tratta di spazi tabulazioni e acapo, li 
collassa in uno spazio solo....
mentre per tutti gli altri caratteri, li trasforma in tanti spazi quanti 
sono i caratteri in questione...
pare sia cosi'... o no?

 perche' nel secondo modo i punti non collassano in uno solo?
mentre voi risolvete, io mi faccio la mia birra.
sono poco pratico di virtuosismi di bash. ho impiegato quais un pomeriggio
intero a capire la soluzione al quesito da me postato.
ciao 
:-)




Sì, più che altro il mio era un "ragionamento ad alta voce" (ehm.. se di "voce"
si può parlare ;) ).
La soluzione arriva (inaspettatamente!) da quello stesso link che ho dato
all'OP. Sempre nella sezione IFS, un po' più giù, c'è:
"$IFS does not handle whitespace the same as it does other characters."
C'è anche un bello script d'esempio (estraggo le parti rilevanti al nostro
caso):
(i commenti "#" indicano l'output dello script)
---8<---
[..]
IFS=" "
var=" a  b c   "
output_args_one_per_line $var  # output_args_one_per_line `echo " a  b c   "`
#
# [a]
# [b]
# [c]
[..]
IFS=:
var=":a::b:c:::"               # Same as above, but substitute ":" for " ".
output_args_one_per_line $var
#
# []
# [a]
# []
# [b]
# [c]
# []
# []
# []
[..]
--->8---
Come si capisce, quindi, se IFS è diverso da " ", sono "ammessi" campi vuoti,
quindi "a...b" non collassa perché i campi non sono [a] e [b], ma [a], [], [] e
[b].
Con gli spazi invece no.
Sarebbe bello capire il perché di questo diverso trattamento...


 
E' piuttosto semplice, si chiama trim degli spazi aggiunti, per esempio:
a b è identico a scrivere a             b cosa che avviene anche sulla
command line di un comando.
Mentre se si specifica un separatore diverso da spazio è evidente che si
vuole considerare lo spazio come un carattere ''importante'' e quindi da
non trimmare.

 
no... non hai capito l'inghippo... in effetti c'e' una piccola incongruenza
$ IFS=" "; echo "a b       c" | { read a b c rest; echo $a $b $c; }
a b c
$ IFS=":"; echo "a:b:::::c" | { read a b c rest; echo $a $b $c; }
a b
bisogna fare attenzione, perche' se leggi un file con i campi separati 
da spazi, puoi avere piu' di uno spazio tra un campo e l'altro
mentre per qualsiasi altro delimitatore, due consecutivi rappresentano 
un campo vuoto
a  b = 2 campi
a::b = 3 campi
pero' in realta' e' diventata una prassi anche los crivere cosi'...
nessuno si sognerebbe di scrivere un file passwd con piu' di un 
dopppio-punto in serie...
mentre e' normale, nel file fstab, che usa gli spazi, e' normale 
metterne piu' d'uno...

 Quotando si "perde" l'effetto di IFS. Any idea?
E' perche' quotando la shell non esegue word splitting.

 perche' nel secondo modo i punti non collassano in uno solo?
E' spiegato in POSIX:
The shell shall treat each character of the IFS as a delimiter and use the
delimiters to split the results of parameter expansion and command
substitution into fields.
   1. If the value of IFS is a <space>, <tab>, and <newline>, or if it is
unset, any sequence of <space>s, <tab>s, or <newline>s at the beginning or
end of the input shall be ignored and any sequence of those characters
within the input shall delimit a field. For example, the input:
          <newline><space><tab>foo<tab><tab>bar<space>
      yields two fields, foo and bar.
   2. If the value of IFS is null, no field splitting shall be performed.
   3. Otherwise, the following rules shall be applied in sequence. The
term "IFS white space" is used to mean any sequence (zero or more
instances) of white space characters that are in the IFS value (for
example, if IFS contains <space>/ <comma>/ <tab>, any sequence of <space>s
and <tab>s is considered IFS white space).
         1. IFS white space shall be ignored at the beginning and end of the
input.
         2. Each occurrence in the input of an IFS character that is not IFS
white space, along with any adjacent IFS white space, shall delimit a
field, as described previously.
         3. Non-zero-length IFS white space shall delimit a field.
E anche in man bash:
"The shell treats each character of IFS as a delimiter, and splits the
results of the other expansions into words on these characters. If IFS is
unset, or its value is exactly <space><tab><newline>, the default, then any
sequence of IFS characters  serves  to  delimit words. If  IFS  has  a 
value  other than the default, then sequences of the whitespace characters
space and tab are ignored at the beginning and end of the word, as long as
the whitespace character is in the value of IFS (an IFS whitespace
character).  Any character in IFS that is not IFS whitespace, along with
any adjacent IFS whitespace characters, delimits a field.  A sequence of
IFS whitespace characters is also treated as a delimiter.  If the value of
IFS is null, no word splitting occurs."
In sostanza, quando la shell fa word splitting, le sequenze di
caratteri "IFS whitespace" vengono compresse e considerate un solo
carattere (e quelle iniziali e finali vengono rimosse), mentre se sono
altri caratteri vengono mantenuti e ogni singolo carattere delimita un
campo.

 incongruenza
]zac[
No, è come ho scritto, e lo stesso modo di procedere del parsing delle
command line dei comandi.
Non c'è nessuna incongruenza, è proprio un caso voluto di trimming degli
spazi, cosa piuttosto abituale nel parsing.
Anzi a dire il vero è un comportamento coerente con i vari parsing presenti
in varie situazioni.