Що означає "<& 3" та "done <file11 3 <file22"


16

У мене є такий сценарій:

while read lineA && read lineB <&3
do
    echo "$lineA"
    echo "$lineB"
    echo
done < file11 3< file22

Цей код працює нормально. Але я цього не розумію:

  • <&3
  • done < file11 3< file22

1
Чи можете ви пояснити нам, що означає сценарій? (Ви кажете, що це працює нормально)
Матьє

Відповіді:


22

Сценарій читає пари рядків з двох файлів. У кожній ітерації він читає рядок file11зсередини lineAта file22зсередини lineB. Це робиться до тих пір, поки він не зустріне кінець будь-якого файлу. Тіло циклу виводить два рядки та порожню лінію.

В <file11означає «з'єднання / перенаправити стандартне введення з file11в цю команду», де «ця команда» є whileциклом. Про це теж можна було написати 0<file11.

Стандартний вхід - це дескриптор файлу № 0. Дескриптори файлів 1 і 2 зарезервовані для стандартного виводу та стандартних потоків помилок.

В 3<file22означає «Дескриптор з'єднання файлів 3 до file22цієї команді». Число 3 є наступним "безкоштовним" номером дескриптора файлу, але код міг використовувати 4 або 5 або будь-яке невелике ціле число, окрім 0, 1 і 2 (межа обмежувального числа дескрипторів файлу залежить від того, яка оболонка є використовується, але цифри до 9 гарантовано працюють).

У циклі read lineAбуде прочитати рядок зі стандартного вводу за замовчуванням, тобто з файлу file11(стандартний вхід успадковується з циклу). Про це теж можна було написати read lineA <&0.

З read lineB <&3, readкоманда зчитується з дескриптора файлу 3, тобто з file22, а не зі стандартного вводу (дескриптор файлу 3 доступний у циклі, як і стандартний ввід).

Коротше кажучи, він використовує стандартний потік введення та "додатковий" дескриптор файлу (номер 3), щоб читати з двох файлів "одночасно" (рядок одночасно з кожного файлу по черзі). Зазвичай, один має лише доступ до одного вхідного потоку, але це обходить це обмеження, явно створюючи другий вхідний потік і підключаючи його до file22файлу.

Пов'язані:


Я вживаю слово "рядок" вище, а не "рядок". У речах, прочитаних з двох файлів, будуть збиті бічні пробіли, а певні послідовності втечі будуть інтерпретуватися спеціально.

Щоб прочитати рядок за допомогою read, використовуйте

IFS= read -r varname

Пов'язані:


Гарна відповідь! Я не розумію, як можна використовувати дескриптор файлів 3. Чи означає це, ніж 3<file22це як а, fopenде значення FIDне повертається, а зазначається раніше?
А. Donda

2
@ A.Donda Ви описуєте fdopen(). Так.
Кусалаланда
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.