Если Вы не можете или не хотеть использовать файл версии LSB (из-за зависимостей, пакет вводит), можно искать определенные для дистрибутива файлы версии. Bcfg2 имеет датчик для дистрибутива, который Вы смогли использовать: http://trac.mcs.anl.gov/projects/bcfg2/browser/doc/server/plugins/probes/group.txt
Большинство команд имеет единственный канал ввода (стандартный вход, дескриптор файла 0) и единственный канал вывода (стандартный вывод, дескриптор файла 1) или иначе воздействует на несколько файлов, которые они открывают собой (таким образом, Вы передаете их имя файла). (Это, кроме того, от стандартной погрешности (fd 2), который обычно фильтрует полностью пользователю.) Однако иногда удобно иметь команду, которая действует как фильтр из нескольких источников или к нескольким целям. Например, вот простой сценарий, который разделяет нечетные строки в файле от четных
while IFS= read -r line; do
printf '%s\n' "$line"
if IFS= read -r line; then printf '%s\n' "$line" >&3; fi
done >odd.txt 3>even.txt
Теперь предположите, что Вы хотите применить другой фильтр к строкам нечетного числа и к четным строкам (но не откладывать их вместе, которые были бы другой проблемой, не выполнимой от оболочки в целом). В оболочке можно только передать стандартный вывод команды по каналу к другой команде; для передачи по каналу другого дескриптора файла необходимо перенаправить его к fd 1 сначала.
{ while … done | odd-filter >filtered-odd.txt; } 3>&1 | even-filter >filtered-even.txt
Другой, более простой вариант использования фильтрует вывод ошибок команды.
exec M>&N
перенаправляет дескриптор файла к другому для остатка от сценария (или пока другая такая команда не изменяет дескрипторы файлов снова). Существует некоторое перекрытие в функциональности между exec M>&N
и somecommand M>&N
. exec
форма более мощна в этом, она не должна быть вложена:
exec 8<&0 9>&1
exec >output12
command1
exec <input23
command2
exec >&9
command3
exec <&8
Другие примеры, которые могут представлять интерес:
И еще для большего количества примеров:
io-redirection
file-descriptors
P.S. Это - удивительный вопрос, прибывающий от автора большей части сообщения upvoted на сайте, который использует перенаправление через fd 3!
В контексте именованных каналов (fifos) использование дополнительного дескриптора файла может позволить не блокировать поведение передачи по каналу.
(
rm -f fifo
mkfifo fifo
exec 3<fifo # open fifo for reading
trap "exit" 1 2 3 15
exec cat fifo | nl
) &
bpid=$!
(
exec 3>fifo # open fifo for writing
trap "exit" 1 2 3 15
while true;
do
echo "blah" > fifo
done
)
#kill -TERM $bpid
См.: Именованный канал, закрывающийся преждевременно в сценарии?
Вот еще один сценарий, когда использование дополнительного дескриптора файла кажется соответствующим (в Bash):
Безопасность пароля сценария оболочки параметров командной строки
env -i bash --norc # clean up environment
set +o history
read -s -p "Enter your password: " passwd
exec 3<<<"$passwd"
mycommand <&3 # cat /dev/stdin in mycommand
Вот пример использования дополнительных FD в качестве контроля разговора в сценарии bash:
#!/bin/bash
log() {
echo $* >&3
}
info() {
echo $* >&4
}
err() {
echo $* >&2
}
debug() {
echo $* >&5
}
VERBOSE=1
while [[ $# -gt 0 ]]; do
ARG=$1
shift
case $ARG in
"-vv")
VERBOSE=3
;;
"-v")
VERBOSE=2
;;
"-q")
VERBOSE=0
;;
# More flags
*)
echo -n
# Linear args
;;
esac
done
for i in 1 2 3; do
fd=$(expr 2 + $i)
if [[ $VERBOSE -ge $i ]]; then
eval "exec $fd>&1"
else
eval "exec $fd> /dev/null"
fi
done
err "This will _always_ show up."
log "This is normally displayed, but can be prevented with -q"
info "This will only show up if -v is passed"
debug "This will show up for -vv"
Дополнительные файловые дескрипторы могут использоваться для создания временных файлов в сценариях оболочки.
Этот ответ stackexchange (, модифицированный , этот)дает изящное решение для создания временного файла в сценарии оболочки. Файл существует только до тех пор, пока дескриптор файла открыт, поэтому файл удаляется даже в случае сбоя программы. При использовании отдельных файловых дескрипторов для чтения и записи указатель файла «чтение» будет находиться в начале файла даже после того, как указатель файла «записи» переместится в конец файла.
tmpfile=$(mktemp)
exec 3> "$tmpfile"
exec 4< "$tmpfile"
rm "$tmpfile"
echo "foo" >&3
cat <&4
while IFS= read -r line;
? Путем я вижу его, IFS не имеет никакого эффекта здесь, так как Вы присваиваете значение только одной переменной (строка). Посмотрите этот вопрос. – rozcietrzewiacz 17.08.2011, 18:33IFS
имеет значение, даже если Вы читаете в единственную переменную (она должна сохранить ведущий пробел). – Gilles 'SO- stop being evil' 18.08.2011, 04:26sed -ne 'w odd.txt' -e 'n;w even.txt'
? – Wildcard 23.11.2017, 02:07