При использовании clear
команды экран очищается. Полностью. У меня больше нет доступа ни к чему из того, что было на экране ранее.
Есть ли способ "очистить" экран (т. е. переместить подсказку в верхнюю часть экрана), не стирая при этом все, что было на экране? В идеале я хотел бы "очистить" экран, но иметь возможность прокрутить его вверх, чтобы увидеть все остальное.
Я использую программу Windows Terminal и оболочку PowerShell, но мне бы хотелось узнать ответ и для командной строки Windows.
Я сказал, что хочу сохранить возможность прокрутки вверх — под этим я подразумеваю, что хочу видеть все, что было до того, как я нажал команду «Очистить», так что... да, я хочу сохранить все, что было до этого, а не историю команд.
решение1
PSReadline (стандартный обработчик ввода PowerShell) имеет CtrlLгорячую клавишу, имеющуюся в большинстве оболочек Unix, которая очищает экран, как если бы вы принудительно прокручивали весь текст (как это делает символ ASCII «Form Feed»).
В PS5, однако, он все равно стираетотображаетсятекст полностью – но все, что уже ушло в прокрутку, останется в прокрутке.
В качестве обходного пути можно вывести достаточно пустых строк, чтобы переместить все в обратную прокрутку:
echo ("`n" * $Host.UI.RawUI.WindowSize.Height)
...а затем переместите курсор наверх:
$e = [char]27
echo "$e[H" # Move cursor to 0;0
echo "$e[J" # Erase down/right
Это также можно привязать к ключу с помощью Set-PSReadlineKeyHandler -ScriptBlock
.
У Cmd нет эквивалента – он считывает ввод в линейном режиме, вместо этого Conhost предоставляет лишь несколько сочетаний клавиш. Однако вы все равно можете создать пакетный скрипт (или даже псевдоним Conhost DOSKEY), который будет выводить те же последовательности VT.
решение2
В то время как очистка экрана являетсяТерминалфункция (через коды управления терминалом ANSI), способ, которым вы получаете эти коды, может быть разным в зависимости от оболочки. Общая идея заключается в следующем:
ESC[2J
очищает экран, но оставляет прокруткуESC[3J
очищает экран, включая всю прокрутку
... где ESC
представляет собой код символа ASCII 27.
Согласно man clear
Linux, 2J
изначально (в 1999 году) код был расширением XTerm, которое было подхвачено ядром Linux в 2011 году для драйвера консоли. Некоторое время спустя его подхватил Windows Console Host, и он был в Windows Terminal, вероятно, с самого начала.
Windows Terminal (для всех оболочек)
Терминал Windows включает в себяclearBuffer
действиекоторый можно привязать к любой горячей клавише. Однако, это влияет на все оболочкинезависимо от того, какое приложение может быть запущено внутри него. По этой причине я рекомендую не использовать его, если вы не уверены, что случайно не нажмете горячую клавишу в чем-то вроде vi
(или хуже).
Тем не менее, это определенно самый простой способ получить эту функциональность в CMD.
Если вы хотите его использовать, clearBuffer
действие позволяет указать clear
цель:
screen
scrollback
all
Использование этой screen
опции очистит текущее содержимое экрана, но оставит прокрутку на месте.
Вам придется редактировать Windows Terminal settings.json
напрямую, поскольку пользовательский интерфейс не позволяет задать clear
цель:
{
"command":
{
"action": "clearBuffer",
"clear": "screen"
},
"keys": ""
}
PowerShell
ДляPowerShell, какuser1684 опередил меня Ctrl+ Lотправляет правильную последовательность выхода.
С другой стороны, Clear-Host
(псевдоним clear
) в PowerShell отправляет ESC[3J
(также очищая прокрутку).
Если у вас есть мышечная память при наборе текста clear
в PowerShell, вы можете просто изменить его определение:
Remove-Item Alias:clear
function clear {
Write-Output "$([char]27)[2J"
}
Если вы хотите, чтобы это было постоянно, добавьте это в свой профиль PowerShell.
КМД
Это возможно, но сложно сделать и в CMD.
Самая большая проблема в CMD — это на самом деле печать символа ESC (ASCII 27). У меня был вставлен настоящий «символ», который можно было бы перенести через копирование/вставку в CMD, но он был стерт, когда я в первый раз внес еще одно редактирование в этот пост. Символ все еще есть в истории правок (исходника) для этого ответа, но давайте найдем лучший способ сделать это.
ОтPowerShell, используйте это, чтобы создатьКМДпакетный файл:
@"
@echo off
echo $([char]27)[2J
"@ | Out-File -FilePath .\clear.cmd -Encoding ASCII
Выполнение полученного clear.cmd
пакетного файла в CMD должно очистить экран (но не прокрутку).
Если у вас возникли проблемы с этим, то любой способ, которым вы можете напечатать ASCII 27, а затем [2J
. Если у вас установлен PowerShell Core, например:
pwsh -c "Write-Output "`e[2J""
И просто чтобы предоставить некоторые дополнительные подробности по одному из ваших комментариев:
Похоже, это либо крупнейший в мире провал дизайна, либо... Не знаю. Я утверждаю, что, по крайней мере, есть обходной путь.
Так что да, мы нашли обходной путь, но, честно говоря, меня бы не удивило, если бы мы этого не сделали. Помните, Windows Console Host (в котором CMD запускался по умолчанию) появился еще в Windows 95 (то есть 27 лет назад), задолго до того, как XTerm вообще добавил эти коды.
И хотя Windows Terminal гораздо более современен, я не думаю, что CMD (которая должна генерировать коды) претерпела какие-либо существенные обновления с момента выхода PowerShell в 2006 году.
На самом деле, я считаю, нам повезло, что у нас есть обходной путь ;-).
Подсистема Windows для Linux
- Ctrl+ Lтакже работает во многих оболочках Linux для отправки
ESC[2J
(выйти из прокрутки). clear
будет действовать как в PowerShell, очищая экранипрокрутить назад (ESC[3J
).clear -x
выйдет из прокрутки (ESC[2J
)
решение3
В качестве обходного пути в CMD вы можете удерживать Ctrl↓ (Down arrow)до тех пор, пока экран не опустеет. Он будет прокручиваться вниз довольно быстро, так что можно прокрутить слишком много. В этом случае вы можете нажать Ctrl→ (Right arrow)или начать печатать, и строка подсказки снова появится на экране. Подойдет все, что перемещает курсор.
К сожалению, в Powershell это не работает.
решение4
Очистить PowerShell и сохранить прокрутку
PowerShell
Раньше я Get-Command
искал командлеты вроде Write-Host
или , Write-Output
потому что мне кажется ОЧЕНЬ странным, что это не функция PowerShell.
Get-Command -CommandType Cmdlet
Нет ни одного