Я хочу прочитати файл і зберегти його в змінній, але мені потрібно зберегти змінну, а не просто роздрукувати файл. Як я можу це зробити? Я написав цей скрипт, але це не зовсім те, що мені потрібно:
#!/bin/sh
while read LINE
do
echo $LINE
done <$1
echo 11111-----------
echo $LINE
У моєму скрипті я можу передати ім'я файлу як параметр, щоб, наприклад, якщо файл містить "aaaa", він виводив би це:
aaaa
11111-----
Але це просто виводить файл на екран, а я хочу зберегти його у змінну! Чи є простий спосіб це зробити?
У крос-платформенному режимі ви використовуєте найменший спільний знаменник sh
:
#!/bin/sh
value=`cat config.txt`
echo "$value"
У bash
або zsh
для читання цілого файлу у змінну без виклику cat
:
#!/bin/bash
value=$(<config.txt)
echo "$value"
Виклик cat
у bash
або zsh
для зчитування файлу вважатиметься Марним використанням Cat.
Зауважте, що для збереження нових рядків не обов'язково брати підстановку команди у лапки.
Див: Bash Hacker's Wiki - Підстановка команд - Спеціальності.
Два важливих підводних камені.
які були проігноровані в інших відповідях:
**Видалення кінцевого нового рядка з розширення команди
Ця проблема є актуальною для:
value="$(cat config.txt)"
типу, але не для розв'язків типу "зчитування".
Розширення команди видаляє кінцеві нові рядки:
S="$(printf "a\n")"
printf "$S" | od -tx1
Вихідні дані:
0000000 61
0000001
Це порушує наївний метод читання з файлів:
FILE="$(mktemp)"
printf "a\n\n" > "$FILE"
S="$(<"$FILE")"
printf "$S" | od -tx1
rm "$FILE"
Обхідний шлях POSIX: додайте додатковий символ char до розширення команди і видаліть його пізніше:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Вихідні дані:
0000000 61 0a 0a
0000003
Майже POSIX обхідний шлях: Кодування ASCII. Див. нижче.
**Видалення нульового символу
Не існує нормального способу в Bash зберігати NUL-символи в змінних.
Це впливає як на розширення, так і на рішення для "читання", і я не знаю жодного хорошого обхідного шляху для цього.
Приклад:
printf "a\0b" | od -tx1
S="$(printf "a\0b")"
printf "$S" | od -tx1
Вихідні дані:
0000000 61 00 62
0000003
0000000 61 62
0000002
Ха, наш NUL зник!
Обхідні шляхи:
ASCII кодування. Дивіться нижче.
використовувати літерали з розширенням bash $""
:
S=$"a\0b"
printf "$S" | od -tx1
Працює тільки для літералів, тому для читання з файлів не підходить.
**Обхідні шляхи для підводних каменів
Зберігати версію файлу в кодуванні uuencode base64 у змінній і декодувати перед кожним використанням:
FILE="$(mktemp)"
printf "a\0\n" > "$FILE"
S="$(uuencode -m "$FILE" /dev/stdout)"
uudecode -o /dev/stdout <(printf "$S") | od -tx1
rm "$FILE"
Вивести:
0000000 61 00 0a
0000003
uuencode і udecode є POSIX 7, але не в Ubuntu 12.04 за замовчуванням (пакунок sharutils
)... Я не бачу альтернативи POSIX 7 для розширення заміни процесу bash <()
, крім запису в інший файл...
Звичайно, це повільно і незручно, тому я вважаю, що правильна відповідь така: не використовуйте Bash, якщо вхідний файл може містити NUL-символи.