FreeBSD также поддерживает FUSE.
Удивительно, но существует реализация EXT4 для FUSE. Не знаю, насколько стабильным он считается.
http://blog.ataboydesign.com/2014/04/23/freebsd-10-mounting-usb-drive-with-ext4-filesystem/
Есть переносной ext4fuse, но он доступен только для чтения . Должна быть возможность использовать ntfs-3g
, что дает вам преимущество журналируемой файловой системы, но некоторые функции Unix могут быть недоступны или потребовать дополнительной настройки.
Могу ли я предложить свой сценарий для этого?
https://github.com/rydnr/set-square/blob/master/.templates/common-files/process-file.sh
#!/bin/bash /usr/local/bin/dry-wit
# Copyright 2016-today Automated Computing Machinery S.L.
# Distributed under the terms of the GNU General Public License v3
function usage() {
cat <<EOF
$SCRIPT_NAME -o|--output output input
$SCRIPT_NAME [-h|--help]
(c) 2016-today Automated Computing Machinery S.L.
Distributed under the terms of the GNU General Public License v3
Processes a file, replacing any placeholders with the contents of the
environment variables, and stores the result in the specified output file.
Where:
* input: the input file.
* output: the output file.
Common flags:
* -h | --help: Display this message.
* -v: Increase the verbosity.
* -vv: Increase the verbosity further.
* -q | --quiet: Be silent.
EOF
}
# Requirements
function checkRequirements() {
checkReq envsubst ENVSUBST_NOT_INSTALLED;
}
# Error messages
function defineErrors() {
export INVALID_OPTION="Unrecognized option";
export ENVSUBST_NOT_INSTALLED="envsubst is not installed";
export NO_INPUT_FILE_SPECIFIED="The input file is mandatory";
export NO_OUTPUT_FILE_SPECIFIED="The output file is mandatory";
ERROR_MESSAGES=(\
INVALID_OPTION \
ENVSUBST_NOT_INSTALLED \
NO_INPUT_FILE_SPECIFIED \
NO_OUTPUT_FILE_SPECIFIED \
);
export ERROR_MESSAGES;
}
## Parses the input
## dry-wit hook
function parseInput() {
local _flags=$(extractFlags $@);
local _flagCount;
local _currentCount;
# Flags
for _flag in ${_flags}; do
_flagCount=$((_flagCount+1));
case ${_flag} in
-h | --help | -v | -vv | -q)
shift;
;;
-o | --output)
shift;
OUTPUT_FILE="${1}";
shift;
;;
esac
done
# Parameters
if [[ -z ${INPUT_FILE} ]]; then
INPUT_FILE="$1";
shift;
fi
}
## Checking input
## dry-wit hook
function checkInput() {
local _flags=$(extractFlags $@);
local _flagCount;
local _currentCount;
logDebug -n "Checking input";
# Flags
for _flag in ${_flags}; do
_flagCount=$((_flagCount+1));
case ${_flag} in
-h | --help | -v | -vv | -q | --quiet)
;;
-o | --output)
;;
*) logDebugResult FAILURE "fail";
exitWithErrorCode INVALID_OPTION ${_flag};
;;
esac
done
if [[ -z ${INPUT_FILE} ]]; then
logDebugResult FAILURE "fail";
exitWithErrorCode NO_INPUT_FILE_SPECIFIED;
fi
if [[ -z ${OUTPUT_FILE} ]]; then
logDebugResult FAILURE "fail";
exitWithErrorCode NO_OUTPUT_FILE_SPECIFIED;
fi
}
## Replaces any placeholders in given file.
## -> 1: The file to process.
## -> 2: The output file.
## <- 0 if the file is processed, 1 otherwise.
## <- RESULT: the path of the processed file.
function replace_placeholders() {
local _file="${1}";
local _output="${2}";
local _rescode;
local _env="$(IFS=" \t" env | awk -F'=' '{printf("%s=\"%s\" ", $1, $2);}')";
local _envsubstDecl=$(echo -n "'"; IFS=" \t" env | cut -d'=' -f 1 | awk '{printf("${%s} ", $0);}'; echo -n "'";);
echo "${_env} envsubst ${_envsubstDecl} < ${_file} > ${_output}" | sh;
_rescode=$?;
export RESULT="${_output}";
return ${_rescode};
}
## Main logic
## dry-wit hook
function main() {
replace_placeholders "${INPUT_FILE}" "${OUTPUT_FILE}";
}
# vim: syntax=sh ts=2 sw=2 sts=4 sr noet
Используйте функцию cmake
и configure_file
.
Он копирует файл <input>
в файл <output>
и заменяет значения переменных, указанные как @VAR@
или ${VAR}
, в содержимом входного файла. Каждая ссылка на переменную будет заменена текущим значением переменной или пустой строкой, если переменная не определена.
Приведенная ниже команда заменяет все вхождения переменных среды формы $VAR
в файле.
compgen -e | xargs -I @ sh -c 'printf "s|\$%q\>|%q|g\n" "@" "$@"' | sed -f /dev/stdin input.file > output.file
Примечание. Синтаксис:sed
немного отличается в macOS:[[:>:]]
для использования вместо \>
.
Вот как это работает:
compgen -e
перечисляет имена переменных среды без значений, например :HOME
LANG
PATH
PWD
...
xargs
перенаправляет вывод в оболочку, которая обрабатывает sed
подстановочные команды через printf
заполнение значений переменных среды по пути :s|$HOME\>|/Users/sshymko|g
s|$LANG\>|en_US.UTF-8|g
s|$PATH\>|/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin|g
s|$PWD\>|/Users/sshymko/Documents|g
...
sed
изменяет содержимое файла с помощью подстановочных команд в стандартном вводе Замещающий формат команды: s|\$%q\>|%q|g\n
, где:
|
— разделитель гарантированно экранируется в имени/значении переменной окружения %q
— строковый заменитель printf
, экранирующий специальные символы оболочки \>
— конец границы слова , чтобы избежать совпадения префикса имени переменной g
— глобальная замена, т.е.заменить все вхождения \n
— разрыв строки, разделяющий sed
подстановочные команды Дополнительно:
@
— аргумент-заполнитель xargs
, содержащий имя переменной окружения $@
— разыменованное значение переменной окружения Чтобы добавить к обсуждению образов Docker выше, (к сожалению, не смог прокомментировать ).
В качестве наиболее безопасных методов следует использовать либо envsubst
, либо perl
. При использовании в Docker проблема заключается в том, что последний является частью образов на основе Debian -(, включаяslim
-типа ), но не Alpine. Добавление envsubst
непосредственно к образу приведет к увеличению размера на 25 МБ или 65 МБ в образах на базе Alpine или Debian -соответственно.
В результате я выбрал один из них напрямую в docker-entrypoint
. Предупреждение :в образах на основе Alpine -, он загружает envsubst
непосредственно с Github. Возможно, вы захотите, чтобы он был где-то локально, чтобы ускорить процесс. Или запеките -на этапе сборки (всего 2,5 Мб таким образом ).
# do not add `envsubst` to the image! It saves 25/65M in Docker Alpine/Debian-based images correspondingly
# `perl` is part of Debian but not Alpine-based images
if [[ -n $(command -v perl) ]] ; then
perl -pe 's/\$(\w+)/$ENV{$1}/g' <"${file}" >"/tmp/${filename}"
else
if [[ ! -f /tmp/envsubst ]] ; then
wget -O /tmp/envsubst "https://github.com/a8m/envsubst/releases/latest/download/envsubst-$(uname -s)-$(uname -m)"
chmod 500 /tmp/envsubst
fi
/tmp/envsubst -i "${file}" -o "/tmp/${filename}"
fi
...
[[ -f /tmp/envsubst ]] && rm -f /tmp/envsubst
Как и в случае с ответом Perl, подстановку переменных среды можно делегировать PHP CLI. Зависимость от PHP может быть приемлемой или неприемлемой в зависимости от используемого технического стека.
php -r 'echo preg_replace_callback("/\\$([a-z0-9_]+)/i", function ($matches) { return getenv($matches[1]); }, fread(STDIN, 8192));' < input.file > output.file
Можно пойти дальше и поместить его в многоразовый скрипт, например,envsubst
:
#!/usr/bin/env php
<?php
echo preg_replace_callback(
'/\$(?<name>[a-z0-9_]+)/i',
function ($matches) {
return getenv($matches['name']);
},
file_get_contents('php://stdin')
);
Использование будет:
envsubst < input.file > output.file