В документах, в которых говорится, что они допустимы для Samba 3 и 4, говорится:
"... удостоверьтесь, что Ваш smbd компилируется с поддержкой CUPS":
# smbd -b | grep CUPS
HAVE_CUPS_CUPS_H
HAVE_CUPS_LANGUAGE_H
HAVE_CUPS
HAVE_LIBCUPS
Я реализовал это с помощью вот этого документа:
i=1
while read -r line; do
eval VAL$i=\$line
i=$((i+1))
done <<EOF
$(my_command)
EOF
Работает отлично.
Обновление: учтены отзывы Жиля и mikeserv.
Сделайте это таким образом:
i=1
my_command | while read line; do
echo $line
eval VAL$i="$line"
i=$((i+1))
done
, поскольку вывод команды является линейкой чтения по строке, эти строки обрабатываются индивидуально (включая пустые Линии) без необходимости сначала хранить эти строки в переменной. Это также сохраняет память, так как вывод не заканчивается в памяти дважды, и сценарий Bash может начать обработку этих строк, как только они выводят, а не только после завершения команды.
Отредактируйте: поскольку переменные VALX устанавливаются в вышеупомянутой поверхности, необходима модификация:
eval `i=1
my_command | while read line; do
# echo $line
echo "VAL$i=\"$line\""
i=$((i+1))
done`
, если вам действительно нужны Echo $ Line
, некоторые модификации будут необходимы.
set -f -- "-$-"' -- "$@" '"
${IFS+IFS=\$2} ${out+out=\$3}" \
"$IFS" "$out" "$@"
IFS='
';for out in $(my command|grep -n '.\|')
do : something with "${out%%:*}" and "${out#*:}"
done
unset IFS out
eval "set +f $1"
shift 3
Вам нужно только расположить его так, чтобы не было пустых строк. Хотя я изначально предложил для этой цели nl
, при второй мысли есть небольшая вероятность того, что логический разделитель страниц nl
может появиться на входе и исказить его вывод (это будет на самом деле приводит к появлению пустой строки и может повлиять на то, какая строка была пронумерована - хотя это очень удобная функция для других целей) . За исключением без интерпретации логических разрывов страниц, результаты grep -n '. \ |'
будут идентичными.
Используя подобный конвейер с небольшой заменой параметров, вы можете не только избежать проблемы с пустой строкой, но также, что каждая итерация имеет предварительно пронумерованный одновременно - (номер текущей итерации теперь будет равным Глава каждого значения обслуживает вас за $ out
, за которым следует :
) .
Строки set ... IFS = ...
предназначены для того, чтобы гарантировать, что состояние оболочки будет восстановлено до того места, в котором вы его оставили до изменения. Эти меры предосторожности могут оказаться излишними, если это сценарий, а не функция. Тем не менее, вы должны по крайней мере установить -f
перед разделением оболочки, чтобы избежать непреднамеренного подстановки на ваш ввод.
(d) ash
и <(
подстановка процесса )
Затем снова в Debian ( тире
) производный ash
(например, busybox ash
) , вы можете обнаружить, что его обработка ссылок файловых дескрипторов и здесь-документов обеспечивает лучшую альтернативу тому, что вы могли бы привыкать делать с <(
подстановка процесса )
.
Рассмотрим этот пример:
exec "$((i=3))"<<R "$((o=4))"<<W 3<>/dev/fd/3 4<>/dev/fd/4
R
W
sed -u 's/.*/here I am./' <&"$o" >&"$i" &
echo "hey...sed?" >&"$o"
head -n1 <&"$i"
Потому что тире
и производные здесь - документы с анонимными каналами, а не (как большинство других оболочек) с обычными файлами, и потому что / dev / fd / [num]
ссылки в системах Linux обеспечивают косвенный способ ссылки на файл резервной копии файлового дескриптора (даже если на него нельзя ссылаться в файловой системе - например, для анонимных pipe) Вышеупомянутая последовательность демонстрирует очень простые средства настройки того, что некоторые оболочки могут называть сопроцессом . Например, в busybox ash
или dash
в системе Linux (я не ручаюсь за другие) выше будет напечатано:
here I am.
... и будет продолжать делать это до тех пор, пока оболочка не закроет свои файловые дескрипторы $ i
и $ o
. Он использует переключатель -u
nbuffered, который предлагает GNU sed
, чтобы избежать проблем с буферизацией, но даже без него входные данные фонового процесса могут быть отфильтрованы и conv = sync
хронизируется по блокам \ 0NUL
байтов с dd
в конвейере, если это необходимо.
Вот способ, которым я обычно использую вышеуказанное с sed
в интерактивной оболочке:
: & SEDD=$$$!
sed -un "/^$SEDD$/!H;//!d;s///;x;/\n/!q;s///;s/%/&&/g;l" <&"$o" >&"$i" &
...который является фоном для sed
, который будет читать и сохранять ввод до тех пор, пока не встретит уникальный разделитель, после чего он удвоит любое вхождение %
в своем старом буфере H
и напечатайте в моем exec
'd анонимном конвейере строку, удобную для формата printf с экранированием на языке C, в одной строке - или, в нескольких строках, если результат превышает 80 символов. Последний - для GNU sed
- может быть обработан с помощью sed -l0
, который является переключателем, который инструктирует sed
никогда не переносить строки на \
, или еще как:
fmt=
while IFS= read -r r <&"$i"
case $r in (*$)
! fmt=$fmt$r ;;esac
do fmt=$fmt${r%?}
done
В любом случае, я создаю его буфер как:
echo something at sed >&"$o"
printf '%s\n' more '\lines%' at sed "$SEDD" >&"$o"
Затем я втягиваю его, как ...
IFS= read -r fmt <&"$i"
Вот как выглядит содержимое $ fmt
после:
printf %s\\n "$fmt"
something at sed\nmore\n\\lines%%\nat\nsed$
sed
также будет выполнять восьмеричные escape-символы в стиле C для непечатаемых символов.
Так что я могу использовать его как ...
printf "%d\n${fmt%$}\n" 1 2 3
... который печатает ...
1
something at sed
more
\lines%
at
sed
2
something at sed
more
\lines%
at
sed
3
something at sed
more
\lines%
at
sed
И я могу убить sed
и освободить каналы по мере необходимости, например ...
printf %s\\n "$SEDD" "$SEDD" >&"$o"
exec "$i">&- "$o">&-
Это то, что вы можете сделать, когда вам нужно удерживать fd, а не использовать его только один раз. Вы можете поддерживать обратную трубу столько, сколько вам нужно -и он более безопасен, чем именованный канал, потому что ядро не предлагает эти ссылки никому, кроме процесса, которому они принадлежат (ваша оболочка) , тогда как именованный канал может быть найден (и прослушано / украдено) в файловой системе любым процессом с разрешениями на его ссылочный файл.
Чтобы делать подобные вещи в оболочке, которая выполняет подстановку, вы, вероятно, можете сделать что-то вроде ...
eval "exec [num]<>"<(:)
... но я никогда не пробовал.