Две важные ловушки
которые были проигнорированы другими ответами до сих пор:
- Удаление завершающего перевода строки из расширения команды
- Удаление символов NUL
Удаление завершающего перевода строки из расширения команды
Это проблема для:
value="$(cat config.txt)"
Тип решения, но не для read
решений на основе.
Расширение команды удаляет завершающие символы новой строки:
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: добавьте дополнительный символ в расширение команды и удалите его позже:
S="$(cat $FILE; printf a)"
S="${S%a}"
printf "$S" | od -tx1
Выходы:
0000000 61 0a 0a
0000003
Почти POSIX обходной путь: ASCII кодировать. См. ниже.
Удаление символов NUL
Не существует нормального способа Bash для хранения NUL-символов в переменных .
Это влияет как на расширение, так и на read
решения, и я не знаю хорошего обходного пути для этого.
Пример:
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.
cat
или$(<someFile)
приведет к неполному выходу (размер меньше , чем реальный файл).