WSL - Конечные пробелы, добавляемые в код Bash, вставляемый в CMD WSL TTY для размера окна
У меня есть несколько скриптов Bash для Windows, и я иногда копирую их из Notepad++ в эмулятор терминала (TTY) WSL (на основе CMD) для их выполнения.
Эта проблема:
Конечные пробелы (зеленые прямоугольники в nano) добавляются к каждому сценарию, когда я копирую и вставляю его в WSL Nano с помощью этой команды:
nano ~/script.sh
Эти конечные символы пробелов не являются частью скрипта и фактически нарушают его выполнение в Linux, поэтому их не должно быть в нем.
Чем уже будет окно WST TTY, тем больше будет возврата каретки при вставке.
Скрипт продолжает содержать эти зеленые ящики, когда я открываю его с помощью Nano, которые, кажется, не удаляют эти символы при сохранении файла (как и должно было быть), поэтому можно утверждать, что это ошибка в Nano, но на самом деле выполнение dos2unix
в файле также не удаляются завершающие пробелы.
Желаемая ситуация:
Мне бы хотелось, чтобы при копировании и вставке сценариев Bash (или любых других данных) из Windows в WSL Nano не возникало конечных пробелов при копировании.
Дальнейшая информация:
https://github.com/Microsoft/BashOnWindows/issues/2006
https://savannah.gnu.org/bugs/?50879
Если вы попытаетесь воспроизвести в своем WSL:
- Обязательно скопируйте скрипт из Notepad++, который имеет EOL Unix (LF) и содержит только отступы табуляции.
- Убедитесь, что ваш файл сценария nano заканчивается
.sh
, так что у вас будет подсветка Bash. Если у вас его еще нет, попробуйте подключиться через SSH-туннель к удаленному серверу Ubuntu, если он у вас есть, и создайте там файл сценария таким же образом, и тогда вы должны иметь такое поведение. - В любом случае убедитесь, что ваше окно Nano является узким (около 25-50 процентов от области просмотра) и что вы вставляете большую часть текста).
3 ответа
Как мне подсказал Бенно Шуленберг из команды разработчиков Nano, добавление следующего кода в конец /etc/nanorc решило эту проблему:
bind ^J enter main
С одной стороны, это отключит формирование конечных пробелов, а с другой стороны, добавит перевод строки (LF-символы) к данным, скопированным из Windows, поэтому он не будет отображаться в одной длинной строке.
Как вы сказали, проблема возникает из-за вставки текста в узкое окно с окончаниями строк Unix (LF).
Подумайте об использовании следующего сценария AutoHotkey, чтобы "напечатать" текст буфера обмена, позволяя Windows обрабатывать символы новой строки.
SendMode Input ; Recommended for superior speed and reliability.
; Upon pressing Ctrl+Alt+v
^!v::
; SendRaw "types" the contents of the variable. When it encounters either
; Cr (`r) or Lf (`n), it sends an "Enter", thus CrLf sends Enter twice.
; Replace any CrLf with Lf (ironic, I know), leaving the clipboard as is
newClip := StrReplace(clipboard,"`r`n","`n")
SendRaw %newClip%
return
На широкой картине вы показываете:....
...cd maldetect-* &&␠|<-window boundary
bash ./install.sh
(символ перед вертикальной чертой - это HTML ␠ или символ юникода U+2420(символ пробела).
Это пространство ДОЛЖНО (ДОЛЖНО) быть там. Если бы границы окна не было, линия была бы:
...cd maldetect-* && bash ./install.sh
Если у вас нет пробела, то && не будет пробела между ним и началом слова 'bash' - что не должно повредить, если вы работаете в bash, НО это всего лишь 1 пример... т.е. обычно между двойным амперсандом и пробелом должно быть пространство.
Если ваши места должны быть там, что может быть причиной ваших проблем... хмммм... ARG! Вы вставляете это "в"... Баш... Э-э-э...
Если вы вставляете в bash, bash "глючит" (вопрос мнения) для вставки из-за изменений автозаполнения, сделанных несколько лет назад. Если в вашем вставленном тексте есть какие-либо "TAB" (да, отступ), это вызовет функцию "автозаполнения" bash (я жаловался на это, но мне сказали, что никто не вставляет текст в bash... кашель, кашель) (жалоба в списке "bug-bash@gnu.org", хотя я сомневаюсь, что это будет исправлено в ближайшее время). Когда он вызывает автозаполнение - много раз он проглотит следующий символ вставленного вами текста, потому что задает вопрос:
> ls <'complete-key' pressed>
Display all 199 possibilities? (y or n)
Как правило, это портит вставленный текст. Во всяком случае, раньше это не было для меня проблемой, так как мои вкладки обычно в пустых строках (потому что они имеют отступ кода). Раньше был случай игнорирования нажатий на завершение кода на пустой строке (@ начало строки или когда перед нажатием клавиши предшествуют только пробелы). Это было изменено, чтобы игнорировать только символ завершения в пустых командных строках (не пустая строка tty). Вставка нескольких команд во входные данные обычно рассматривается как bash, как некая непрерывная команда, а НЕ пустая командная строка. Излишне говорить, что это вызывает много проблем.
Для меня несовершенным решением было переназначить ключ завершения кода из TAB в Backquote ("") (above tilde key). (same bug occurs if you have
в вашем тексте, но для меня, я использую это гораздо реже, чем TAB). Он установлен в файле.inputrc вашего домашнего каталога, который управляет поведением readline (используется bash для чтения строк, разрешения редактирования и т. Д.). В частности, в разделе ".inputrc" есть параметры конфигурации, специфичные для bash:
$if bash
# use backquote as completion (yes, that's shift-'~')
# not ideal, but quickest "hack" to get mostly
# transparent pasting (backquote isn't used nearly as often as TAB)
TAB:tab-insert
"`":complete
$endif
Альтернативы: 1) перед вставкой преобразуйте все свои вкладки в пробелы, чтобы TAB не вызывал завершение команды. 2) всегда записывать текст в файл и исходный (.) Файл или делать его исполняемым и добавлять '#!/ Bin/bash' в 1-й строке, чтобы сделать его сценарием оболочки.
Теоретически вы также должны иметь возможность отключить завершение команды, но я использую его слишком часто, поэтому никогда не пытался попробовать.
Что я обычно делаю сейчас, так это редактирую скрипт в 1 окне (обычно gvim), а в окне, где я запускал gvim, я запускаю последовательные итерации скрипта - таким образом избегая "вставки". Конечно, это не был мой первый выбор, но искажающий ввод bash, глотающий вещи после нажатия клавиши завершения, подтолкнул меня в этом направлении.
Обратите внимание, если вы сообщите об этом как об ошибке, будьте готовы предложить решение!;-) Это загвоздка:
> ls \<carriage return>
>> [here people want to be able to hit 'TAB' and get an autocomplete of
of the files in the current directory. It looks like an empty line,
but it is a really a continued command line from the previous line.
То же самое происходит, когда вы вставляете команды в bash... у некоторых будут вкладки там, где они вам не нужны...
(Надеюсь, это поможет, и я не совсем ушел в левое поле, но когда вы упомянули "вставку" и это выглядит как bash-скрипт... и вы упомянули использование вкладок (которые также вставляются), звучало как та же самая проблема, с которой я столкнулся.
Использование обратной цитаты в качестве завершающего ключа иногда немного неудобно, но слишком часто в тексте вставляются вкладки... да ладно)