Я увидел эту строку в сценарии:
DEVICE=`dialog --inputbox "Festplatten-Laufzeit auslesen. Gebe Sie das
gewünschte Device an: " 0 70 "" 3>&1 1>&2 2>&3`
Что
3>&1 1>&2 2>&3
делаю? Я знаю, что 1 = stdout и 2 = stderr, но что такое 3
и &
for?
решение1
Числа являются дескрипторами файлов, и только первые три (начиная с нуля) имеют стандартизированное значение:
0 - stdin
1 - stdout
2 - stderr
Итак, каждое из этих чисел в вашей команде относится к файловому дескриптору. Вы можете либо перенаправить файловый дескриптор в файл с помощью, >
либо перенаправить его в другой файловый дескриптор с помощью>&
В вашей командной строке 3>&1
будет создан новый файловый дескриптор и перенаправлен на , 1
который является STDOUT
. Теперь 1>&2
будет перенаправлен файловый дескриптор 1 на STDERR
и 2>&3
будет перенаправлен файловый дескриптор 2 на 3, который является STDOUT
.
Итак, по сути, вы переключились STDOUT
и STDERR
вот шаги:
- Создайте новый fd 3 и укажите его на fd 1
- Перенаправить файловый дескриптор 1 в файловый дескриптор 2. Если бы мы не сохранили файловый дескриптор в 3, мы бы потеряли цель.
- Перенаправить файловый дескриптор 2 на файловый дескриптор 3. Теперь файловые дескрипторы один и два поменялись местами.
Теперь, если программа печатает что-либо в файловый дескриптор 1, это будет напечатано в файловый дескриптор 2 и наоборот.
решение2
Это обмен stdout
и stderr
.
>name
означает перенаправление вывода в файл name
.
>&number
означает перенаправление вывода в файловый дескриптор number
.
Таким образом, &
необходимо сообщить оболочке, что вы имеете в виду дескриптор файла, а не имя файла.
Файловый дескриптор — это число, которое ссылается на уже открытый файл. Стандартные — 0
для стандартного ввода, 1
стандартного вывода или 2
стандартной ошибки. Вы также можете использовать любое другое число, которое создаст новый файловый дескриптор, как при создании новой переменной с помощью var=value
.
По умолчанию и дескриптор файла, 1
и 2
переход к нему /dev/tty
, поэтому если вы запустите somecommand 3>&1 1>&2 2>&3
новую оболочку, это ничего не изменит (за исключением того, что теперь у вас есть дескриптор файла номер 3).
Но если где-то ранее в скрипте выполняется перенаправление с помощью exec (например exec 2>error.log
, ) или скрипт запускается с командной строкой, включающей перенаправление (например, ./thescript 2>error.log
), то перестановка stdout и stderr что-то сделает.
В вашем конкретном случае команда, у которой stdout и stderr поменялись местами, это dialog
. Глядя на еестраница руководства, Я понимаю
Some widgets, e.g., checklist, will write text to dialog's output.
Normally that is the standard error
возможно, человек, написавший скрипт, по какой-то причине хочет dialog
, чтобы вывод отправлялся в , stdout
а не в .stderr
Смотрите такжеПорядок перенаправлений
решение3
Автор сценария определил fd 3 следующим образом:
exec 3<> File.txt
Откройте "File.txt" и назначьте ему fd 3. Максимальное количество дескрипторов файлов: 255
read -n 4 <&3
Прочитайте только 4 символа.
echo -n . >&3
Поставьте там десятичную точку.
exec 3>&-
Закрыть фд 3.
cat File.txt
==> 1234.67890
решение4
Я понял назначение файлового дескриптора и команды «3> & 1 1> & 2 2> & 3» по примеру ниже
#!/bin/bash
#it's normal case fd environment
echo test 1> afile.txt
echo "Test no 1"
cat afile.txt
echo "Test no 1"
echo test 2> afile.txt
echo "Test no 2"
cat afile.txt
echo "Test no 2"
echo test 1> afile.txt
echo "Test no 3"
cat afile.txt
echo "Test no 3"
echo test 2> afile.txt
echo "Test no 4"
cat afile.txt
echo "Test no 4"
echo > afile.txt
echo "------------------------------------------------------------------------"
#it's relocate filedescriptor and cause not problem, and cause error(std error)
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 5"
#cat afile.txt
echo $var
echo "Test no 5"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 6"
#cat afile.txt
echo $var
echo "Test no 6"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 7"
#cat afile.txt
echo $var
echo "Test no 7"
var=
var=$(echo test 3>&1 1>&2 2>&3)
echo "Test no 8"
#cat afile.txt
echo $var
echo "Test no 8"
При запуске этого примера вы увидите, что дескрипторы файлов переупорядочены, а выходные данные изменены.