Невідстежувані нові рядки не видаляються
Нові рядки, які ви шукаєте, є, ви просто їх не бачите, оскільки використовуєте echo
без наведення змінної.
Перевірка :
$ a=$( df -H )
$ echo $a
Filesystem Size Used Avail Use% Mounted on /dev/sda3 276G 50G 213G 19% / udev 2.1G 4.1k 2.1G 1% /dev tmpfs 832M 820k 832M 1% /run none 5.3M 0 5.3M 0% /run/lock none 2.1G 320k 2.1G 1% /run/shm
$ echo "$a"
Filesystem Size Used Avail Use% Mounted on
/dev/sda3 276G 50G 213G 19% /
udev 2.1G 4.1k 2.1G 1% /dev
tmpfs 832M 820k 832M 1% /run
none 5.3M 0 5.3M 0% /run/lock
none 2.1G 320k 2.1G 1% /run/shm
$
Вихідні нові рядки видаляються
Як правильно зазначив @ user4815162342 , хоча нові рядки у вихідному коді не видаляються, кінцеві нові рядки видаляються із заміною команди. Дивіться експеримент нижче:
$ a=$'test\n\n'
$ echo "$a"
test
$ b=$(echo "$a")
$ echo "$b"
test
$
У більшості випадків це не має значення, оскільки echo
буде додано видалений новий рядок (якщо це не викликано з -n
параметром), але є деякі крайні випадки, коли в результатах програми є більше, ніж один, що відстає від нових рядків, і вони є чомусь.
Обхідні шляхи
1. Додайте фіктивний символ
У цьому випадку, як згадував @Scrutinizer , ви можете скористатися таким обхідним шляхом :
$ a=$(printf 'test\n\n'; printf x); a=${a%x}
$ echo "$a"
test
$
Пояснення: Символx
додається до виводу (за допомогоюprintf x
) після нових рядків. Оскільки нові рядки більше не відстають , вони не видаляються підстановкою команди. Наступним кроком є видаленняx
доданого нами за допомогою%
оператора in${a%x}
. Тепер ми маємо оригінальний вихід, з усіма новими рядками !!!
2. Читання з використанням заміни процесу
Замість того, щоб використовувати заміну команди для призначення виходу програми змінної, ми можемо замість цього замінити процес, щоб подати вихід програми read
вбудованій команді (кредит @ormaaj ). Заміна процесу зберігає всі нові рядки. Читання вихідних даних для змінної трохи складно, але ви можете зробити це так:
$ IFS= read -rd '' var < <( printf 'test\n\n' )
$ echo "$var"
test
$
Пояснення:
- Ми встановлюємо внутрішній роздільник полів для команди читання як нуль, за допомогою
IFS=
. Інакше read
не присвоїв би весь вихід var
, а лише перший маркер.
- Ми використовуємо
read
варіанти -rd ''
. Служить r
для запобігання зворотній косою рисою виступати в ролі спеціального символу та d ''
встановити роздільник на нуль, щоб читання читало весь вивід, а не лише перший рядок.
3. Читання з труби
Замість того, щоб використовувати заміну команди або процесу для призначення виходу програми змінної, ми можемо замість цього передати результат програми read
команді (кредит @ormaaj ). Трубопроводи також зберігають усі нові рядки. Однак слід зазначити, що на цей раз ми встановлюємо lastpipe
оболонки додаткового поведінки, використовуючи в shopt
вбудованої команду . Це потрібно, щоб read
команда виконувалась у поточному середовищі оболонки. В іншому випадку змінна буде присвоєна в підшелутці, і вона не буде доступна з решти сценарію.
$ cat test.sh
shopt -s lastpipe
printf "test\n\n" | IFS= read -rd '' var
echo "$var"
$ ./test.sh
test
$
eval
.