Что делает «3>&1 1>&2 2>&3» в скрипте?

Что делает «3>&1 1>&2 2>&3» в скрипте?

Я увидел эту строку в сценарии:

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вот шаги:

  1. Создайте новый fd 3 и укажите его на fd 1
  2. Перенаправить файловый дескриптор 1 в файловый дескриптор 2. Если бы мы не сохранили файловый дескриптор в 3, мы бы потеряли цель.
  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"

При запуске этого примера вы увидите, что дескрипторы файлов переупорядочены, а выходные данные изменены.

Связанный контент