LINUX.ORG.RU

[bash] Записать перевод строки в переменную

 


0

1

Есть такая конструкция:

eval `sed '/^prestart:/!d;s/^prestart://' "$SCRIPT"`

В файле «$SCRIPT» лежат строки. Некоторые из них имеют вид «prestart:команда». Надо достать команды из каждой такой строки и выполнить по очереди. Если $IFS будет равен переводу строки (по умолчанию в нём пробел, LF и tab), то команды выполнятся по очереди. Иначе все команды объединяются в одну строку, что неправильно.

Необходимо записать в переменную $IFS один символ перевода строки, чтобы конструкция выше правильно выполнялась.

  1. Пробовал так:
    IFS='\n'

    Это записывает в $IFS текст '\n', не работает.

  2. Пробовал так:
    IFS='
    '

    Это записывает в $IFS перевод строки, echo -n «$IFS» печатает пустую строку, но конструкция неправильно работает (всё-таки сливает все команды в одну).

  3. Ещё я пробовал так:
    IFS=`echo`

    Так всё работает правильно.

Собственно, вопросы:

  • Чем отличаются способы 2 и 3? Почему 3 работает, а 2 - нет?
  • Как можно это сделать по-человечески, не вызывая echo? Это часть init-скриптов, которые я потихоньку пилю для своей системы, надо, чтобы всё работало как можно быстрее. [Код из парсера файлов, в которых прописано, как запускать демон; аналог юнитов в systemd. prestart - это те команды, которые выполнятся до запуска демона.]

PS Если есть ещё идеи по оптимизации выражения в sed, просьба написать, т.к. тут важна скорость работы.

> eval `sed '/^prestart:/!d;s/^prestart://' «$SCRIPT»`

awk умеет выполнять внешние команды, eval брррр....

anonymous
()

> IFS='

'

IFS=$'\x10'

IFS=`echo`

После `` строки объединяются пробелами (если не экранировано "")

тоже самое, если IFS=

man dash: 2. Field Splitting is performed on fields generated by step (1) unless the IFS variable is null.

anonymous
()

> PS Если есть ещё идеи по оптимизации выражения в sed, просьба написать, т.к. тут важна скорость работы.

info sed, есть (но гнутое => не полностью портабельное) расширение:

echo ls | sed /ls/e

anonymous
()

Я не совсем понял, что именно нужно ТС, но вроде как его проблема решается постановкой кавычек вокруг ``

vadim@host3:~$ cat > /tmp/bla
echo Hello 
echo World
vadim@host3:~$ eval "`cat /tmp/bla`"
Hello
World
geekless ★★
()
Ответ на: комментарий от geekless

Я не совсем понял, что именно нужно ТС, но вроде как его проблема решается постановкой кавычек вокруг ``

Спасибо, попробовал с кавычками в eval - работает правильно.

Также немного разобрался, чем отличаются способы 2 и 3. В способе 2:

IFS='
'

почему-то в $IFS записывается 2 перевода строки. Определил так:

IFS='
'
echo $IFS > /tmp/file
hexdump -C /tmp/file
gentoo_root ★★★★★
() автор топика
Ответ на: комментарий от anonymous

>Ну вариант IFS=«\n» (двойные кавычки), ты, конечно же, не осилил.

Я его осилил, но не написал здесь, т.к. посчитал, что всем очевидно, что '\n' - это то же самое, что «\n».

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

>есть (но гнутое => не полностью портабельное) расширение:

echo ls | sed /ls/e

Это тоже попробую, это поможет избавиться от eval.

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

>IFS=$'\x10'

Спасибо, теперь буду знать, как по-человечески положить LF в переменную. Нашёл в man bash про строки типа $'строка', там написано, что и $'\n' должно работать, но у меня почему-то работает только $'\x10'.

gentoo_root ★★★★★
() автор топика

Решено

В общем, проблема решена несколькими способами:

  1. IFS=$'\x10'
  2. eval "`sed '/^prestart:/!d;s/^prestart://' "$SCRIPT"`"
  3. sed '/^prestart:/!d;s/^prestart://e;d' "$SCRIPT"

Всем спасибо за ответы.

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