Linux как перезагрузить драйвер

Обновлено: 04.07.2024

Из моей установки по умолчанию Image Magick 6.8.9.9 из репозиториев Ubuntu 16.04 оказывается, что Jpeg200 (.jp2) полностью поддерживается.

Преобразования могут выполняться с помощью:

convert in.jpg out.jp2 convert in.jp2 out.jpg

Для параметров командной строки esp. в отношении параметров кодирования или обработки черепичных изображений см. интерактивную документацию Image Magick.

Следует, однако, сказать, что jp2 не указана в списке поддерживаемых форматов:

identify -list format

Тем не менее, по-видимому, он все еще отлично работает.

Вы можете попытаться отключить питание вашего устройства. Предполагая, что вы не можете / не хотите физически отключать устройство, вы должны запустить (от имени root): iwconfig wlan0 txpower off . Затем я бы подождал 10-15 секунд, чтобы убедиться, что проблема с оборудованием вызвала проблему, и затем: iwconfig wlan0 txpower auto .

Или вы можете просто запустить rfkill и заблокировать / разблокировать ваше устройство. Для этого запустите rfkill block wifi , а затем rfkill unblock wifi . Эта вторая опция должна быть быстрее, так как вам нужно только подождать 2-3 секунды между командами, а не 10-15 секунд. На самом деле, на моей машине мне вообще не нужно ждать, хотя я подозреваю, что это зависит от вашего оборудования WiFi. Эта опция также может быть сделана обычным пользователем, без рута.

Вы также можете перезапустить NetworkManager. Если вы используете systemctl в качестве системы инициализации (как в случае с более новыми версиями Ubuntu), вы можете использовать systemctl restart NetworkManager . В противном случае вы можете использовать sudo initctl restart network-manager . Если вы не знаете, какую систему инициализации вы используете, попробуйте обе команды и посмотрите, что работает.

Вам просто нужно перезапустить Network Manager :

, Находят имя модуля

, Давайте найдем название модуля ядра для Вашего беспроводного соединения:

(Пакет установки hwinfo , если у Вас нет его.)

Ищут имя модуля в строке "Драйвера".

Перезагрузка, которую модуль

Теперь разгружает затем, перезагружает модуль. Например, мое имя модуля iwlwifi

, Таким образом, мы идем, ища другие модули с помощью iwlwifi :

Слева имя модуля и справа другие модули с помощью него. Поэтому давайте попытаемся отключить iwldvm сначала:

, Если это работает, то мы можем теперь успешно отключить iwlwifi

И теперь повторно включить оба модуля в обратном порядке:

Сделанный!

Это - единственная процедура, которая работала на меня в сбросе низких lelel настроек (frag, уровень), что я установил использование iwconfig .

то, Что это делает эффективно, является "перезагрузкой драйвер".

Создан скрипт, основанный на предыдущих советах по ссылкам с небольшим количеством микширования сопоставление предыдущих ссылок. Это работает для меня под управлением Mint Linux 17.3.

Файл ниже не требует доступа с правами root. Это также только перезапускает Wi-Fi только , если он уже выключен. Теперь мне просто нужно добавить этот скрипт в работу cron, чтобы проверять мое Wi-Fi соединение каждые 15 минут или около того.

Они не нуждаются в root, если вы пишете сценарий:

. 116] Как говорят эти парни в комментариях, только для WI-FI:

Обходное решение с помощью "systemctl перезапускает NetworkManager" работы для меня на двух различных ноутбуках с Broadcom и Atheros WiFi при Debian Buster и Ubuntu 19.04 - где проблема с "Wi-Fi не проснется на резюме", происходит на каждом четвертом резюме или так (=, это обычно работает просто великолепно.) я сначала попытался создать настольное средство запуска для вызова сброса Wi-Fi вручную, который работает и требует пароля - но затем я нашел несколько примечаний людей, помещающих проклятие сброса в места в системе, которые запускают скрипты после резюме. А именно, /lib/systemd/system-sleep/ похож на хорошее место для помещения сценария . И, сценарий должен лучше протестировать некоторые условия (полученный через cmdline аргументы), чтобы знать, что это - правильное время для сброса NetworkManager. Извинения за соединение вместо того, чтобы вырезать и вставить - я не спросил разрешение этого конкретного автора, и он может наслаждаться upvotes также для его вклада YouTube (прямо к точке, и хорошо рассказанный).

Как перезапустить звуковую систему в линукс (убунту) без перезагрузки?

sudo /etc/init.d/pulseaudio restart

sudo /etc/init.d/alsa-utils restart

rmmod на все модули alsa по порядку, затем modprobe на них же. Возможно для удобства есть скрипт, которым можно сделать так:

Если используется pulseaudio (или нечто подобное), то нужно перезапустить и его. Опять же для этого скорее всего есть скрипт в /etc/init.d/.

P.S. Я не убунтуец, поэтому точных инструкций дать не могу.

Пока я печатал, уже сказали как правильно =).


можно тупо переконфигурить альсу


>можно тупо переконфигурить альсу

Болит палец - отрубаем руку? (:

ЕМНИП sudo killall puleaudio && pulsaudio

Точно сказать не могу, ибо последний раз юзал пульс 3 месяца назад.

[оффтоп, но все же] Есть причины использовать pulseaudio в дополнение к alsa? Казалось бы это +1 уровень к абстракции (железо<->alsa<->pulse->динамики). Хотелось бы услышать мнение человека, который реально pulse находит удобнее, а не просто описание возможностей.


Прыгай в машину времени, сейчас быть довольным пульсом очень сложно. Наверное, можно заставить его работать нормально, но только вот зачем - всё интересное ещё не реализовали.

а нахрена этот пульс? я в гентоо без него все собираю. алсо, это говно даже не портабельно.

1) У pulseaudio программный микшер быстрее, чем встроенный в alsa dmix.
2) На pulseaudio можно менять устройства вывода (например с колонок на наушники) не перезапуская программу с которой выводится звук.
3) Для разных программ можно держать свои настройки громкости.
4) Искаробочный lowpass-фильтр для сабвуфера.
5) Прозрачная передача звука по сети.

P.S. PulseAudio не использую. Последний раз смотрел довольно давно.

> 2) На pulseaudio можно менять устройства вывода (например с колонок на наушники) не перезапуская программу с которой выводится звук.

Хм. вставляю в разьём наушники во время проигрывания любого звука (хоть входа в систему) на динамика сразу mute, в наушниках - звук. Alsa.

> 3) Для разных программ можно держать свои настройки громкости.

Как-то сомнительно. Сделал допустим на kopete 10% общей громкости. Потом забыл об этом. Включаю какой-нить metal (Slayer скажем). Соседи счастливы.

> 5) Прозрачная передача звука по сети.

Хм. А чем это лучше NAS? Последнего, правда, не использовал.


> Хм. вставляю в разьём наушники во время проигрывания любого звука (хоть входа в систему) на динамика сразу mute, в наушниках - звук. Alsa.

Можно инструкцию на это чудо? А то поисковый запрос не придумывается.

> Как-то сомнительно.

Полезно, но афаик они это пока не реализовали.


Пульс несовместим с вайном => без танцев с бубном в проприетарные игры не поиграешь.

> Там в настройках была какая-то опция по поводу создания виртуальных устройств или что-то подобное. С этим работает. По-крайней мере в вине 0.9.5(где-то там) работал звук в конфигуряторе.

> Можно инструкцию на это чудо? А то поисковый запрос не придумывается.

Мне вообще казалось, что это фича железа, а не софта


> Мне вообще казалось, что это фича железа, а не софта

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

Можно ли сбросить подключение USB-устройства без физического отключения / подключения от ПК?

В частности, мое устройство представляет собой цифровую камеру. я использую gphoto2 , но в последнее время я получаю "ошибки чтения устройства", поэтому я хотел бы попытаться выполнить программный сброс соединения.

Из того, что я могу сказать, нет никаких модулей ядра, загружаемых для камеры. Единственный, который выглядит связанным usbhid ,

Сохранить следующее как usbreset.c

Выполните следующие команды в терминале:

Получите идентификатор шины и устройства USB-устройства, которое вы хотите сбросить:

Сделайте нашу скомпилированную программу исполняемой:

Запустите программу с привилегией sudo; сделать необходимую замену <Bus> а также <Device> идентификаторы, найденные путем запуска lsusb команда:

Я раньше не сталкивался с вашими конкретными обстоятельствами, поэтому я не уверен, что этого будет достаточно, но я нашел самый простой способ перезагрузить USB-устройство с помощью этой команды: (Внешние приложения не нужны)

Это именно то, что я использую для сброса моего Kinect, поскольку у libfreenect, похоже, нет API для возврата его в спящий режим. Он у меня на Gentoo box, но ядро ​​должно быть достаточно новым, чтобы использовать ту же структуру пути для sysfs.

Ваш, очевидно, не будет 1-4.6 но вы можете либо извлечь этот путь устройства из журнала ядра ( dmesg ) или вы можете использовать что-то вроде lsusb чтобы получить идентификаторы поставщиков и продуктов, а затем с помощью быстрой команды, подобной этой, перечислить, как пути связаны с различными парами идентификаторов поставщиков / продуктов:

Это сбросит все подключенные порты USB1/2/3 [1]:

Я верю, что это решит вашу проблему. Если вы не хотите сбрасывать все конечные точки USB, вы можете использовать соответствующий идентификатор устройства из /sys/bus/pci/drivers/ehci_hcd

Мне нужно было автоматизировать это в скрипте Python, поэтому я адаптировал чрезвычайно полезный ответ LiLo к следующему:

В моем случае это был драйвер cp210x (о котором я мог сказать lsmod | grep usbserial ), так что вы можете сохранить приведенный фрагмент как reset_usb.py и затем сделать это:

Это также может быть полезно, если у вас еще нет настройки компилятора переменного тока в вашей системе, но у вас есть Python.

Поскольку частный случай вопроса - это проблема связи gphoto2 с камерой по USB, в gphoto2 есть возможность сбросить USB-соединение:

Возможно, этот вариант не существовал в 2010 году, когда был задан вопрос.

Я использую кувалду, перезагружая модули. Это мой скрипт usb_reset.sh:

И это мой файл службы systemd /usr/lib/systemd/system/usbreset.service, который запускает usb_reset.sh после запуска моего менеджера diplay:

Сохраните приведенный ниже скрипт как reset_usb.py или клонируйте этот репозиторий.

Я сделал скрипт Python, который будет сбрасывать определенное устройство USB на основе номера устройства. Вы можете узнать номер устройства из команды lsusb.

В этой строке 004 номер устройства

Самым быстрым способом сброса будет сброс самого контроллера USB. Это заставит udev отменить регистрацию устройства при отключении, и регистрация вернется после того, как вы его включите.

Это должно работать для большинства компьютерных сред. Однако, если вы используете какое-то нестандартное оборудование, вы можете просто перебирать имена устройств. С помощью этого метода вам не нужно узнавать имя устройства по lsusb. Вы также можете включить в автоматизированный скрипт.

Вот скрипт, который будет сбрасывать только соответствующий идентификатор продукта / поставщика.

Иногда я хочу выполнить эту операцию на определенном устройстве, как указано VID (идентификатор поставщика) и PID (идентификатор продукта). Это скрипт, который я нашел полезным для этой цели, который использует изящную библиотеку libusb.

Затем этот C++ файл resetDeviceConnection должен выполнить эту задачу сброса подключения устройства, как указано в vid и pid.

Я сделал простой скрипт для перезагрузки определенного USB-устройства.

Если вы знаете имя вашего устройства, этот скрипт Python будет работать:

Попробуйте, это отключение программного обеспечения (Eject).

Иногда не работает просто отсоединить устройство для некоторых устройств.

Я хочу удалить или извлечь мой "Genius NetScroll 120".

Тогда я сначала проверь мое подключенное USB-устройство

Хорошо, я нашел свою мышь, она имеет шину 002, устройство 009, idVendor 0458 и idProduct 003a, так что это справочная информация об устройстве мыши.

Это важно, номер шины - это начальный путь к устройству, и я проверю идентификатор продукта и поставщика, чтобы убедиться, что устройство удаляется.

Обратите внимание на папки, проверьте начало с папкой номер 2, я проверю эту, потому что мой Bus - 002, и одну за другой я проверяю каждую папку, содержащую правильные idVendor и idProduct, о моей информации о мыши.

В этом случае я получу информацию с помощью этой команды:

Хорошо, путь /sys/bus/usb/drivers/usb/2-1.3/ совпадает с моей информационной мышью! XDDD.

Пришло время удалить устройство!

Подключите снова USB-устройство, и оно снова работает!

Возможно, это работает и для камеры:

После этого все снова заработало. dmesg рассказал только одну строчку о USB устройство найдено.

Я действительно понятия не имею, что делает следующее подробно. Но это сработало.

Следующий пример вывода из Debian Squeeze с 2.6.32-5-686 Ядро, так что я думаю, что это работает для 2.6 и выше:

Пользователи Windows привыкли, что для того, чтобы оборудование хорошо работало и выдавало максимальную производительность, необходимо выполнять обновление драйверов.

Такая же ситуация характерна для Ubuntu, и даже больше, здесь еще многое оборудование не поддерживается или поддерживается не полностью. С новыми версиями драйверов могут приходить исправления, улучшения производительности или даже поддержка нового оборудования. В этой статье мы рассмотрим как обновить драйвера в Ubuntu.

Обновление драйверов в Ubuntu

Мы уже подробно рассматривали что из себя представляют драйвера в операционной системе Linux и как с ними работать в статье установка драйверов в Linux. Из той же статьи мы узнали, что большинство драйверов Linux, а именно драйвера с открытым исходным кодом входят в ядро системы, но также есть прошивки для драйверов и проприетарные драйвера.

Таким образом, чтобы обновить драйвера в Ubuntu достаточно просто обновить ядро до самой новой версии, а если ещё проще то просто регулярно обновлять систему с помощью команд:

sudo apt update
sudo apt upgrade

Но тут есть еще несколько нюансов. В о-первых в официальных репозиториях не содержится самая новая версия ядра Linux, там находится та версия, которая была самой новой на момент релиза вашего дистрибутива. Во-вторых проприетарные драйвера тоже в официальных репозиториях чаще всего не обновляются и нужно искать другие пути для их установки. Все это мы рассмотрим дальше.

Обновление драйверов, встроенных в ядро

Как я уже сказал, для обновления драйверов с открытым исходным кодом необходимо обновить версию ядра. Но не смотря на то, что новая версия ядра не будет автоматически устанавливаться в вашей системе, deb пакеты новых версий исправно пакуются и выгружаются в общий доступ для всех желающих обновить свою систему.

Посмотреть какая версия ядра используется сейчас вы можете командой:


Вы можете скачать нужный образ ядра по ссылке. Там хранится больше количество ядер для разных дистрибутивов, чтобы найти самое новое пролистайте вниз. Не стоит брать ядра с приставкой rc - это нестабильные версии. Здесь нас будут интересовать два файла linux-headers и linux-image.


Обратите внимание, что ядро нужно качать только для своей архитектуры, например, для x86 - i386, а для x64 - amd64. Узнать свою архитектуру вы можете просто выполнив команду:

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

sudo dpkg -i linux-image*
sudo dpkg -i linux-headers*

Теперь осталось обновить параметры загрузчика Grub, чтобы теперь система загружалась с новым ядром:

После применения этой команды необходимо будет перезагрузить компьютер.

Если вы хотите уже самую-самую свежую версию ядра Linux, для которой еще не собраны пакеты на выше указанном сайте, то в можете собрать ядро Linux из исходников. Ещё есть и другие методы обновления ядра, все они описаны в этой статье.

Обновления на прошивки для драйверов выходят очень редко, но если вы не хотите обновлять всю систему, то можно проверить есть ли обновления для прошивок:

sudo apt-cache policy linux-firmware

И затем установить если есть:

sudo apt install linux-firmware

С обновлением обычных драйверов с открытым исходным кодом разобрались, теперь поговорим о проприетарных драйверах с ними ситуация немного сложнее.

Обновление проприетарных драйверов

Если обновление драйверов Ubuntu с открытым исходным кодом происходит, можно сказать, за раз, в пару команд, то с проприетарными драйверами не все так просто. В Ubuntu есть специальная утилита, для обновления и установки драйверов от сторонних разработчиков. Для ее запуска откройте главное меню и введите в строке поиска Программы и обновления.

Откройте программу, а затем перейдите на последнюю вкладку - Дополнительные драйвера. Здесь вы можете выбрать необходимые драйвера и их версии для установки, будут доступны не только драйвера для видеокарт, но и другие проприетарные драйвера, например, для сетевых адаптеров, звуковых карт и т д:


После завершения настройки нажмите Применить, и система запустит установку драйверов. Но все дело в том, что программа берет драйвера из официальных репозиториев, а там они не всегда первой свежести. Если вы хотите именно самую новую версию драйверов, то придется качать установщики из официальных сайтов.

Но тут уже кроется еще одна проблема, если вы устанавливаете драйвера не из репозиториев системы, а с помощью стороннего установщика, то есть большой риск, что они слетят при следующем обновлении системы. Так что тут придется выбирать или новизна или стабильность, ну в общем, как обычно.

Установка драйверов NVIDIA подробно описана в отдельной статье, поэтому я не буду подробно на этом останавливаться. Скажу только, что скачать установщик можно с официального сайта, но будьте осторожны и качайте драйвера только для вашей видеокарты.

С драйвером для видеокарт AMD все стало намного проще с выходом свободного драйвера, теперь он поставляется вместе с ядром и может быть обновлен без проблем, так, как описано в первом способе. О нём на сайте тоже есть подробная статья.

Если вы использовали установку драйверов с помощью системного менеджера драйверов, то вы будете получать обновления при каждом обновлении системы. Но если вы использовали установщик, здесь уже придется устанавливать их каждый раз вручную.

Что касается других проприетарных драйверов, то вам придется обновлять их подобным способом.

Выводы

Теперь вы знаете как обновить драйвера Ubuntu. Для новичков это может показаться сложным, но если ваше оборудование работает отлично, то вам и необязательно ничего обновлять. Если у вас остались вопросы, пишите комментарии!

Драйверы - это программы подобные обычному программному обеспечению. Разница лишь в том, что для их работы не требуется постоянное вмешательство пользователя. Они служат для взаимодействия ваших аппаратных средств между собой. Как все просто. Вам необходимо улучшить их использование операционной системой.

Чаще всего, необходимые драйвера включаются в дистрибутив и устанавливаются в процессе установки. Иногда бывает все не так удачно, и только что собранная рабочая станция будет идти без звука, сети или видео драйверов.

Я не буду вдаваться в детали, поясняя установку специфических драйверов. Для получения этой информации вам необходимо обратиться к поставщикам оборудования. Я поясню, как установить драйверы, как загрузить их, а затем как добавить их в автозагрузку, чтобы они загружались автоматически каждый раз при запуске системы.

Установка

Подобно любому программному обеспечению, драйверы могут быть скомпилированными или нет. Обычно они не скомпилированы. Драйверы обычно распространяются в виде исходных текстов, с целью достижения максимально возможной совместимости аппаратных средств на установленной платформе. Это значит, что вам придется компилировать их из исходных текстов. Элементарно! Мы уже знаем как это сделать.

Если поставщик оборудования является щедрым, он, возможно, дополнит поставляемый драйвер само-устанавливающим скриптом. Другими словами, вам будет нужно только запустить одну команду, которая выполнит: распаковку архива, компиляцию, установку и загрузку драйвера. Но это может не работать. Я был свидетелем как само-устанавливающийся скрипт драйвера работал неверно. По этой причине, для всех практических задач, вам следует устанавливать драйвер вручную.

После успешной распаковки из архива и компиляции исходников (./configure, make, make install), вы, скорее всего, столкнетесь с выбором из трех вариантов:

  • Драйвер будет полностью сконфигурирован и скопирован в папки, выбранные по умолчанию, и системные пути будут обновлены. В этом случае, вам не нужно ничего делать, чтобы использовать драйвер.
  • Драйвер будет сконфигурирован автоматически, и системные пути будут обновлены. Это значит, что вы только добавите имя драйвера в список загружаемых драйверов начальной загрузки, чтобы он загружался автоматически при запуске системы.
  • Драйвер будет готов к использованию, но не будет сконфигурирован, системные пути не будут обновлены. Вам придется вручную загрузить драйвер и затем обновить список загружаемых драйверов начальной загрузки, чтобы он загружался автоматически при запуске системы.

При втором варианте, процесс установки, будет выглядеть следующим образом:

Теперь только остается добавить этот драйвер в список загружаемых драйверов при запуске системы. В Linux драйвера часто называют модулями .

Вам нужно открыть конфигурационный файл, содержащий список модулей. Также необходимо знать его точное имя и размещение файла в вашем дистрибутиве. В Ubuntu этот файл называется modules.conf и размещается в /etc каталоге ( /etc/modules.conf ). Мы обновим этот файл, но вначале мы сделаем его резервную копию. Пожалуйста помните, что для изменения конфигурационных файлов нужны права суперпользователя.

Так будет выглядеть эта процедура:

Приведенные выше команды откроют файл modules.conf в текстовом редакторе gedit. Теперь, просто добавьте драйвер в пустую строку ниже существующих драйверов, сохраните файл, выйдите из текстового редактора и перезагрузите систему, чтобы изменения вступили в силу. Это все!

Вот пример, файла modules.conf для Kubuntu Linux, установленной на виртуальной машине. Добавим новый драйвер. Мы просто запишем его имя ниже существующих записей. Конечно, необходимо знать ТОЧНОЕ имя соответствующего драйвера.


Третий вариант немного более сложный.

Загрузка драйверов

Вы успешно скомпилировали драйвер, но ничего не произошло. Это получилось потому, что драйвер еще не включен. Посмотрев внутрь каталога, вы заметите файл с расширением .ko . Это и есть ваш драйвер, и его необходимо загрузить вручную.

Нам нужно установить драйвер в ядро. Это можно сделать с помощью команды insmod .

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

Если вы случайно сделали серьезную ошибку и хотите удалить драйвер, то можете воспользоваться командой rmmod :

Конфигурирование драйверов

Конфигурирование драйвера требует немного знаний о его функциональности. Чаще всего инструкции находятся в текстовых файлах how-to руководства.

Ниже приведенный пример показывает как конфигурировать сетевую карту после загрузки сетевого драйвера. Сетевой карте присвоен идентификатор и IP адрес. В данном случае, eth0 - имя выбранного устройства, но оно может быть другим, например: eth1, eth2 и т. д. . Назначенный IP адрес показывает нам, что машина будет частью локальной сети.

После перезагрузки вы увидите, что сетевое подключение отсутствует. Это происходит из-за того, что драйвер отсутствует в общем каталоге по умолчанию, и система не знает, где его искать. Вам придется повторить всю процедуру снова:

Скрипты

Как и в системах DOS и Windows, скрипты могут быть написаны в текстовом редакторе. Учитывая внутренние различия между текстовыми файлами и скриптами, необходимо различать текстовые файлы и скрипты. В системе Windows достаточно изменить расширение .txt на .bat и файл станет скриптом. В Linux немного по-другому.

Командная строка Linux находится внутри оболочки или, точнее сказать, и есть сама оболочка или Шелл (Shell). Существует несколько оболочек, каждая со своим уникальным набором команд. Самая популярная (устанавливается по умолчанию) оболочка Linux это BASH . Нам необходимо добавить информацию в наш скрипт, если хотим сделать его связанным с нашей оболочкой.

Таким образом, записав в файл приведенные выше команды плюс ссылка на оболочку, получим следующий скрипт:

Можно сделать это короче:

Теперь у нас есть рабочий скрипт. Или точнее текстовый файл, который содержит соответствующие команды. Нам необходимо сделать его исполняемым файлом. Во-первых, нужно сохранить этот файл. Назовем его network_script .

Сделаем скрипт исполняемым.

Теперь у нас есть работающий скрипт. Нам нужно разместить его в каталоге /etc/init.d и он будет запускаться во время начальной загрузки системы.

В завершение нужно обновить систему для активации скрипта.

После перезагрузки вы поймете, что драйвер загружен автоматически и сетевая карта сконфигурирована! Возможен и другой вариант, make install и драйвер будет помещен в каталог по умолчанию:

Или вы могли разместить драйвер в этом каталоге сами. Таким образом, вы могли бы избежать написания скрипта.

Однако мой метод, даже если и менее изящный, имеет одно преимущество. Драйверы, которые вы скомпилировали вручную и поместили в каталоги по умолчанию, будут потеряны при обновлении ядра системы. Это значит, что вам будет необходимо их переустанавливать каждый раз после такого обновления. Мой неэлегантный метод позволяет избежать этой проблемы.

Читайте также: