LINUX.ORG.RU
решено ФорумAdmin

Bash не понятное поведение в цикле...


0

1

Уважаемый ЛОР, подскажи что тут не так и не эдак:

cat 1.sh

 
for line in $(cat /etc/fstab)
do 
   echo $line ; sleep 1
done
./1.sh
 
#
/etc/fstab:
static
file
system
information.
#
#
Use
cat 2.sh

 
while read line
do
    echo $line ; sleep 1
done < /etc/fstab
./2.sh 

# /etc/fstab: static file system information.
#
# Use 'blkid' to print the universally unique identifier for a
# device; this may be used with UUID= as a more robust way to name devices
# that works even if disks are added and removed. See fstab(5).

Почему в 1.sh переменная line не содержит строку, а всего лишь набор символов до пробела..?

★★★★★

Потому, что Долдон не читает man bash, зато пишет чег-то там.

anonymous
()

Почему в 1.sh переменная line не содержит строку, а всего лишь набор символов до пробела..?

потому-что cat выплёвывает весь файл, а потом он режется bash'ем по пробельным символам (пробелы, табуляции, переводы строки).

А вот если кормить весь цикл с командой read, то эта команда читает файл построчно. В переменной line оказывается одна строка в каждой итерации.

//2анон. Сам-то читал? В этом веке?

emulek
()
Ответ на: комментарий от emulek

а потом он режется bash'ем по пробельным символам (пробелы, табуляции, переводы строки).

А почему если cat /etc/fstab сделать оно не режется?

P.S. я думал что cat просто побитовое содержание выкидывает файла в stdout, а bash просто хватает перевод строк и переводит. Разве нет? Очевидно что нет, раз такое поведение... Однако интересно...

DALDON ★★★★★
() автор топика
Ответ на: комментарий от DALDON

я думал что cat просто побитовое содержание выкидывает файла в stdout, а bash просто хватает перевод строк и переводит. Разве нет?

нет. Смотри:

S="a b c
d

e f"

for L in $S
do
	echo "L: '$L'"
done
L: 'a'
L: 'b'
L: 'c'
L: 'd'
L: 'e'
L: 'f'
Видно, что bash берёт то, что после in, и режет это так, как оно написано в IFS

А написано там вот это:

$ echo -n "$IFS" | hexdump -C
00000000  20 09 0a                                          | ..|
пробел-табуляция-перевод_строки

emulek
()
Ответ на: комментарий от DALDON

bash <...> переводит.

переводит не bash, а echo. Она всегда переводит без -n.

emulek
()

Потому что почитай как for работает. Ты сказал «for line in (...)», но for жеж всё равно делит в т.ч. по пробелам, а не только по переносам строки.

proud_anon ★★★★★
()
Последнее исправление: proud_anon (всего исправлений: 1)

в первом случае тебе нужно что-то типа

while read line;do
   echo $line ; sleep 1
done < /etc/fstab

megabaks ★★★★
()
Последнее исправление: megabaks (всего исправлений: 1)
Ответ на: комментарий от anonymous

А что, у молодёжи этого века не принято читать документацию? Или что ты хотел сказать?

ты думаешь, пословица «настоящие хакеры манов не читают» придумали в этом веке?

emulek
()
Ответ на: комментарий от emulek

Огромное тебе спасибо за подробное разъяснение! Теперь всё понял.

DALDON ★★★★★
() автор топика
Ответ на: комментарий от proud_anon

Спасибо!

Завтра помчится imapsync с допотопного exim на zimbra... :)

DALDON ★★★★★
() автор топика
Ответ на: комментарий от anonymous

я-то помог вопрос решить, и скор теперь набиваю. А вот чего ты добиваешься своими комментариями?

Я надеюсь, что увеличивая энтропию ЛОРа, ты её уменьшаешь в каком-то другом месте.

emulek
()
Ответ на: комментарий от emulek

Я, вот, дал ссылку на мануал, в первом посте. А ты, как там говоришь, добиваешься чего-то своими комментариями на сайте в интернете? Ну, респект, всегда должно быть что-то в жизни.

anonymous
()
Ответ на: комментарий от anonymous

Я, вот, дал ссылку на мануал, в первом посте.

ты действительно думаешь, что ТС не знает про man bash? ИМХО он просто его не осилил, ибо man большой, и найти это место там достаточно сложно(если не знать, что искать). В следующий раз, будь так любезен, представь пожалуйста хотя-бы цитату. В данном случае я это сделаю за тебя (1456я строчка)

   Word Splitting
       The  shell  scans  the  results  of  parameter expansion, command substitution, and
       arithmetic expansion that did not occur within double quotes for word splitting.

       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 sequences  of  <space>,  <tab>,
       and  <newline>  at  the beginning and end of the results of the previous expansions
       are ignored, and any sequence of IFS characters not at the beginning or end  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  adja-
       cent  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.

       Explicit null arguments ("" or '') are retained.  Unquoted implicit null arguments,
       resulting from the expansion of parameters that have no values, are removed.  If  a
       parameter  with  no value is expanded within double quotes, a null argument results
       and is retained.

       Note that if no expansion occurs, no splitting is performed.
emulek
()
Ответ на: комментарий от Komintern

энтропию нельзя уменьшать, она только увеличивается.

4.2

ты забыл ключевое понятие ГЛОБАЛЬНО. Глобально — нельзя. А вот локально — вполне. Тепло тоже может идти от холодного к горячему, посмотри на холодильник. Да, в сумме энтропия растёт, но тебе-то что? Солнце горит уже 5Г лет, и будет гореть как минимум столько-же.

emulek
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.